AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程(四)——ANE面向IAP的测试和开发

本文的内容如下:

  • 在Native扩展中使用StoreKit框架
  • ActionScript扩展
  • ANE-IAP开发实例分享

    本文用到的工具和设备如下:
    Flash Builder 4.5
    Flex SDK 4.5.1
    Flash Professional CS5.5
    AIR SDK 3.0
    Xcode 4.1 + iOS SDK 4.3
    iPad 1

    本文例子中的Objective-C部分和AS扩展类库部分的代码作者为我的同事Saumitra Bhave
    ———————————————————————————–
    在Native扩展中使用StoreKit框架

    下载安装XCode 4和iOS SDK之后,让我们先来了解一下苹果原生类库是如何处理应用内付费功能的。iOS SDK中有一个框架叫做StoreKit,它负责应用程序和应用商店的业务流程。StoreKit中有一些负责具体功能的类,商品的请求,请求结果,结果回调,购买,购买队列等都由不同的类来完成。

    图1 StoreKit的业务流程

    如上图所示,StoreKit解决内付费业务的大体流程可以概括成这样,SKProductsRequest向商店发出请求获得商品信息,商店通过回调函数SKProductsRequestDelegate把请求的结果SKProductsReponse传了回来,如果用户选择购买商品,则创建一个SKPayment实例到购买队列SKPaymentQueue中,然后通过回调SKPaymentTransactionObserver来返回购买的结果。

    我现在拿请求商品信息的部分来举例说明一下:

    1
    2
    3
    
    SKProductsRequest* req = [[SKProductsRequest alloc] initWithProductIdentifiers:pids]; 
    	req.delegate = observer;
    	[req start];

    上面的Objective-C的代码如果转译成ActionScript 3.0,相当于这个意思:

    1
    2
    3
    
    var req:SKProductsRequest = SKProductsRequest.initWithProductIdentifiers(pids);
    req.delegate = observer;
    req.start();

    SKProductsRequest继承于父类SKRequest,通过静态方法initWithProductIdentifiers和参数pids创建了一个实例req,参数pids是一个数组,列出了需要请求的内付费商品ID。req通过start方法向商店发出请求,并在发出请求的动作之前给自己注册了一个回调函数observer。

    observer是SKProductsRequestDelegate的实例,回调接口如下:

    1
    
    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response;

    转译成AS是如下的代码:

    1
    
    function productsRequest(request:SKProductsRequest, response:SKProductsResponse):void;

    其中response就是请求的结果。

    下面是一个完整的Objective-C函数体:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
    	NSLog(@"Products Received");
    	NSMutableString* retXML = [[NSMutableString alloc] initWithString:@"<products>"];
    	for (SKProduct* p in response.products) {
    		[retXML appendFormat:@"<product><title>%@</title><desc>%@</desc><price>%@</price><locale>%@</locale><id>%@</id></product>",p.localizedTitle,p.localizedDescription,p.price,[p.priceLocale localeIdentifier],p.productIdentifier];
    	}
    	[retXML appendFormat:@"<invalid>"];
    	for(NSString* s in response.invalidProductIdentifiers){ 
    		[retXML appendFormat:@"<id>%@</id>",s];
    	}
    	[retXML appendFormat:@"</invalid></products>"]; 
    	FREDispatchStatusEventAsync(g_ctx, (const uint8_t*)"productsReceived", (const uint8_t*)[retXML UTF8String]);
    	[retXML release];
    	[request release]; 
    }

    这里主要实现的是将结果格式化成一个XML流,然后通过派发事件传回给AS扩展类,注意这里派发事件用的是FREDispatchStatusEventAsync方法,它定义在FlashRuntimeExtension.h内部,前文我介绍过,这是负责与AS扩展类通信的类。

    在AS类包中,通过注册的StatusEvent来侦听这个事件,并从e.level中取得XML流里的商品信息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    ext.addEventListener(StatusEvent.STATUS,onStatus);
    ...
    function onStatus(e:StatusEvent):void{
         switch(e.code){
              case "productsReceived":
              var xml:XML = new XML(e.level);
              ......
         }
    }

    购买的业务流程和请求信息的流程十分相似,这里我不一一介绍,大家可以在最后下载项目的代码来查看。
    ———————————————————————————
    ActionScript扩展

    在Saumitra提供的ANE扩展类中,AS部分的结构是这样的:
    com.adobe.nativeExtensions.AppPurchase;
    com.adobe.nativeExtensions.AppPurchaseEvent;
    com.adobe.nativeExtensions.Base64;
    com.adobe.nativeExtensions.Product;
    com.adobe.nativeExtensions.Transaction;

    其中AppPurchase负责业务流程以及与Native扩展的接口,AppPurchaseEvent定义了各种StatusEvent的状态,Product和Transaction定义了数据模型,Base64负责为参数转码。整个扩展类库简单易懂,我会在下面的项目实例中介绍其中用到的一些方法。
    ———————————————————————————–
    ANE-IAP开发实例分享

    最后总结本系列教程所有的知识来做一个例子。
    我首先做的准备是在iTunesConnect中创建了一个新的应用,并新建了四个内付费商品:plane(非消耗型),diary(非消耗型),bottle(消耗型),key(消耗型)。我希望在iPad的沙箱环境中测试以下的业务流程:
    请求商品信息,购买消耗型和非消耗性商品,恢复非消耗型商品的购买状态,如果都成功则我的应用调试成功。

    分析一下这个应用的UI需求,我需要一个按钮来触发请求商品信息的动作,然后需要一个列表来显示商品信息,接下来需要给每个商品添加一个购买的按钮。由于iPad上无法用trace等debug方法调试,所以我还需要一个监测的窗口来打印所有的流程信息。

    下面是该应用的截屏:


    图2 请求商品列表


    图3 显示商品信息


    图4 恢复非消耗型商品的购买状态


    图5 购买新的消耗型商品


    图6 输入测试用户密码


    图7 购买成功

    资源:
    实例ANE-IAP(包括AS扩展类,Native扩展类)下载

    如何使用本例:
    开发者需要使用自己的证书和设备来打包和发布,有关如何打包ANE和如何发布IPA,我已经在这个系列教程的前文提到过了,本文不做重复介绍。

    注意事项:
    1,本例使用Flash Professional作为Compiler,使用Flash Builder作为代码编辑IDE,请在Flash Professional的发布设置中选择Flash Player,并在发布的时候忽略这个错误: VerifyError: Error #1014: Class flash.external::ExtensionContext could not be found。直接使用生成的SWF即可。

    2,在iPad上测试之前务必要先注销已经登陆的苹果帐号,注销方法为,进入系统偏好设置,在左边列表内点击Store图标,然后点击在右侧出现的帐号,再在弹出的窗口中点击”注销“。

    3,如果你没有用过XCode,不知道如何发布OBJC项目,请在安装XCode之后打开下载的Native扩展包里的AppPurchase.xcodeproj文件,项目打开后按Command+B,在左边项目资源列表的Products文件夹内会生成一个.a文件,右键点击后可以在Finder中找到这个文件。

    总结:
    本文所提供的例子,只是应用内付费的入门,如果要做真正的产品,你需要搭建自己的服务器用来验证购买商品的收据,以及在本地记录商品的使用状态并与服务器同步等等。这些知识不是本文的重点,这里不做详细介绍,感兴趣的朋友可以和我做进一步的探讨。谢谢各位!

  • 你可能感兴趣的:(ios,xcode,测试,AIR,actionscript,extension)