zoukankan      html  css  js  c++  java
  • iOS 开发 初级:应用内购买 In-App Purchase

     现在有很多应用都使用了In-App Purchase,虽然对于很多用户来说,可能并不喜欢甚至讨厌这个模式,以为一点击就要从账户里扣钱。但是,应用内购买对于开发者而言不失为一种好的商业模式,而且人们也将越来越接受这种购买模式。

    下面开始介绍一下应用内购买的基本原理和编程方法。

    1、基本原理

    这里参考了Apple的开发文档In-App Purchase Programming Guide


    简要介绍一下整个流程:

    Pre 0:在iTunesConnect中对于的App创建相应的产品,并在应用信息中加入这些产品。具体步骤之后介绍。

    Step 1:应用内根据创建的产品的bundle identifier来获取产品的List。

    Step 2:应用请求产品的信息。产品信息为SKProduct对象。

    Step 3:App Store返回信息。在实际编程中,Step1,2,3是在一起的。通过创建SKProductsRequest得到SKProductsResponse。SKProducts信息就在SKProductsResponse的对象中,是其Property。

    Step 4:在应用中显示产品信息给用户

    Step 5:用户点击了一个产品。

    Step 6:应用向App Store发出一个购买请求 Payment Request

    Step 7:App Store处理请求,完成交易,并返回信息到应用。

    Step 8:  应用获取信息然后根据交易情况将购买的内容解锁给用户使用。

     

    这是In-App Purchase的一个基本的过程描述。在我们实际的编程过程中。对于这个产品列表,我们可能会选择直接提供给用户,而不是通过App Store获取信息。只有当用户点击了某个产品后,我们才开始去获取产品信息并完成购买。另一方面,在购买过程中,我们在应用中应该显示足够的提示信息,因此交易过程中的Notification也很重要。

     

    下面开始StepByStep介绍整个具体的实现过程。这里只是介绍最基本的实现方法,以non-consumable产品为例。

    Step 1:创建产品

    首先要说明一下为了实现应用内购买,你的AppID就是com.companyname.appname必须是唯一的,不能带*。

    在iTunesConnect中Manage My Applications中选择Manage In-App Purchases



    有四种产品类型,具体详见开发文档。这里选择non-consumable,就是一次购买终身受用的产品。consumable就是消费类可以不断购买的,这种在游戏中比较常见。


    上面是产品的详细信息填写。这里特别注意的是ProductID的填写,其实就是ProductIdentifier,这个和应用的BundleIdentifier类似,必须独一无二,一般的做法是填写成com.companyname.appname.productname,当然从本质上讲可以是任意字符串,只要独一无二就可以了。这个ProductID是之后在程序中获取产品信息的依据。其他方面的信息填写很简单,这里不在费述。

    Step 2:在应用版本信息中加入产品

    进入到应用页面,点击View Detail,然后在下面可以看到

    In-App Purchases,点击Edit然后加入之前创建的Products。

    Step 3:创建测试User

    为了在开发阶段测试In-App Purchase,Apple为我们提供了Test User功能,通过它,可以在开发时用这个账号免费实现应用内购买。

    具体就是在iTunesConnect首页,点击Manage Users

    点击Test User进行创建。

    Step 4:开始编程。在Xcode中要加入StoreKit.framework,通过它来实现功能

    Step 5:一般我们会单独创建一个类来实现应用内购买的功能。由于这个是教程,而不是案例,所以不打算把整个类的编写都搬进来。只是介绍一下重要的东西和流程。

    在类中要加入

    <SKProductsRequestDelegate,SKPaymentTransactionObserver>

    对于SKPaymentTransactionObserver这个东西可以监测交易的整个过程,即使交易时退出应用,交易也可以继续进行,当然要回到应用内的页面才能最后完成交易,显示产品相应内容。类的初始化应加入

    [[SKPaymentQueuedefaultQueueaddTransactionObserver:self];

    加入这句代码来实现TransactionObserver的功能,后面有相应的Methods可以加入

    paymentQueue:开头

    Step 6:下面的介绍不局限在一个类的编写,而是按照购买流程。假设我们已经编写好了一个应用内购买的类,然后我们要实现购买。首先就是Request Products。

    _productRequest = [[SKProductsRequestalloc]initWithProductIdentifiers:_productIdentifiers];

    _productRequest.delegate =self;

    [_productRequest start];


    一个完整的请求如上,对于productsIdentifiers,这是一个Set,就是在这里创建一个set加入各个ProductIdentifer

     NSSet *productIdentifiers = [NSSetsetWithObjects:

                                        K_CAMERA_ANGLE_MODE,

                                        K_SLOPE_ANGLE_MODE,

                                        K_DIHEDRAL_ANGLE_MODE,

                                        K_LINE_PLANE_ANGLE_MODE,

                                        nil];

    然后就是request delegate的methods

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

       NSArray *skProducts = response.products;

        // process....

    }

     

    - (void)request:(SKRequest *)request didFailWithError:(NSError *)error

    {

       // process....   

    }


    请求成功,就能获取Products,一个NSArray,里面就是SKProduct 对象的产品信息了。产品信息有名称,价格,等等,很容易找到。这些东西只是在显示信息时有用,购买时不需要,只要用SKProduct就行了

    Step 7:购买

    SKPayment *payment = [SKPaymentpaymentWithProduct:product];

    [[SKPaymentQueuedefaultQueueaddPayment:payment];

    代码如上。然后就开始连接App Store了。主要看下面

    #pragma mark - SKPaymentTransactionObserver

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    {

       for (SKPaymentTransaction *transactionin transactions) {

           switch (transaction.transactionState) {

                caseSKPaymentTransactionStatePurchased:

                    [selfcompleteTransaction:transaction];

                   break;

                caseSKPaymentTransactionStateFailed:

                    [selffailedTransaction:transaction];

                   break;

                caseSKPaymentTransactionStateRestored:

                    [selfrestoreTransaction:transaction];

                    

               default:

                   break;

            }

        }

    }


    这里说一下上面的第三种交易状态Restore,恢复。这个是这样的。如果有些人在iPhone上用一个账号购买了一个产品,那么在iPad上又下载了这个应用,还要再重新购买吗?不用了,通过Restore在App Store中检测你这个账号的购买记录,如果有购买记录存在,那就不用再次购买了,直接restoreTransaction。

     

    接下来就是根据购买的状态分别进行处理

    - (void) completeTransaction: (SKPaymentTransaction *)transaction
    {
    
        // Your application should implement these two methods.
        [self recordTransaction:transaction];
        [self provideContent:transaction.payment.productIdentifier];
    
        // Remove the transaction from the payment queue.
    
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    }
    

    一般我们用NSUserDefaults来进行交易的记录就行了。

    注意程序中finishTransaction这一行代码,这样TransactionObserver就不再监测这个交易了。

    其他状态Restore,failed都是差不多的处理,这些代码在开发文档中有。

     

    当然,对于restore,还有一个Method要注意

    - (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error

    如果restore失败,可以显示相应的信息提示

     

    Step 8:附加

    在整个购买过程中,我们一般要给用户一下提示信息,比如等待,比如正在连接,比如交易已完成。要实现这些功能,就应该用notification,在上面的交易环节加入postNotification,然后对notification进行有效处理。本文只讲In-App Purchase,关于notification的编程不做介绍。

     

    基本上,通过上面的环节就能完成整个应用内购买了。当然,从安全性上考虑,Apple在交易完成后会发送验证信息,通过发送验证信息给App Store来判断这笔交易是否出自App Store,从而确认交易的合法性。

    关于这方面,Apple 有一个代码包提供了validationController来实现很方便的验证。

  • 相关阅读:
    Apache 虚拟主机 VirtualHost 配置
    EAX、ECX、EDX、EBX寄存器的作用
    Python中文文档 目录(转载)
    八度
    POJ 3268 Silver Cow Party (最短路)
    POJ 2253 Frogger (求每条路径中最大值的最小值,Dijkstra变形)
    2013金山西山居创意游戏程序挑战赛——复赛(1) HDU 4557 非诚勿扰 HDU 4558 剑侠情缘 HDU 4559 涂色游戏 HDU 4560 我是歌手
    HDU 4549 M斐波那契数列(矩阵快速幂+欧拉定理)
    UVA 11624 Fire! (简单图论基础)
    HDU 3534 Tree (树形DP)
  • 原文地址:https://www.cnblogs.com/wudan7/p/3621763.html
Copyright © 2011-2022 走看看