iOS:为 App 添加内购买项目

作者: Linsw | 来源:发表于2017-03-06 21:09 被阅读6190次

    思维导图

    前言

    在 AppStore 里,付费应用的下载量往往比免费应用的下载量少的多。上架过应用的开发者,可能会有这样的体会:当一个应用免费的时候,每天能有几十上百次的下载,但是一旦设置为收费的时候,下载量立即暴跌,即使只设成了一元,可能好几星期都没人下载。

    收费的应用不好做,与其长时间零下载,还不如设置为免费,每天看看下载量来的舒服。

    但是作为一个开发者,开发免费应用的动力,显然比不上开发收费应用。应用免费了,开发的动力也少了。因此,我们可以考虑在应用里面加入内购买项目,通过免费下载吸引用户,再用内购买项目让用户按需购买,自己赚点零花钱。

    本文将用一个真实的例子(已上架 AppStore:Catch - 捕捉稍纵即逝的灵感),介绍为 App 添加内购买项目的流程。

    必要的准备

    添加内购买项目之前,需要有一个付费的开发者账号,并在开发者账号的“协议、税务和银行业务”里完善银行卡等信息,否则 Apple 无法将应用的收入转给你。

    你还需要准备一个已上架或者未上架的应用,应用在首次添加内购买项目时需要与新的应用版本一起提交审核。

    内购买项目的用户界面

    在添加内购买项目前,你需要在你的应用里,自己设计好商品展示的界面,Apple 只负责购买的流程。这个界面在接下去新建内购买项目时也会用到。

    下图是一个实际应用的内购商品展示界面:

    在 iTunesConnect 上新建内购买项目

    接下来,在 iTunesConnect 上的应用页面,选择“功能”-“App 内购买项目“,点击加号新建项目,如下图:

    之后会要求选择内购买项目的类型,这里以“消费型项目”为例。在接下来的表里填写相应的信息。产品 ID 一般以 App 的 Bundle ID 为前缀再加上自定义的产品后缀,如:com.self.purchase1。在审核信息里上传刚刚的内购商品展示界面,供审查员审核。其他信息自行填写即可。

    新建内购买项目后,在内购买项目列表里显示为“准备提交”状态。现在在准备提交的 App 版本中添加刚刚新建的内购买项目。

    完成内购买相关代码

    关于内购买的代码,本文将使用一个现成的框架:SwiftyStoreKit,这样有利于理清思路。对于直接使用 StoreKit 完成整个内购买的流程,将在下一篇文章里讨论。

    首先在项目里添加 SwiftyStoreKit 框架。具体添加的方法上面的链接里已有说明。
    总共的代码有三部分,如下:

    一、获取商品信息,用于在界面上显示:

    SwiftyStoreKit.retrieveProductsInfo([productID]) {[weak self ] result in
        if let product = result.retrievedProducts.first {
            let priceString = product.localizedPrice!
            print("Product: \(product.localizedDescription), price: \(priceString)")
        }else if let invalidProductId = result.invalidProductIDs.first {
            print("Could not retrieve product info .Invalid product identifier: \(invalidProductId)")
        }else {
            print("Error: \(result.error)")
        }
    }
    

    商品信息包括商品的价格和名称,保存在 SKProduct 对象里。汇率的问题 Apple 已经帮我们处理好,商品的名称会根据我们在 iTunesConect 里填写的本地化信息自动选择,因此我们只需要直接使用 localizedPricelocalizedTitlelocalizedDescription

    二、购买商品(当用户点击购买后):

    func purchase(_ productID: String) {
        SwiftyStoreKit.purchaseProduct(productID, atomically: true) { [weak self] result in
            if case .success(let product) = result {
            // Deliver content from server, then:
            if product.needsFinishTransaction {
                SwiftyStoreKit.finishTransaction(product.transaction)
                }
            }
            if let alert = self?.alertForPurchaseResult(result) {
                self?.showAlert(alert)
            }
        }
    }
    

    productID 就是内购买项目的 ID,如:com.self.appname.purchase1。productID 可以事先在程序中定义,如果想从网络上获取 productID 的话,只能从自己的服务器中获取,iTunesConnect 并不提供获取内购买商品列表的 API。

    三、完成购买事务:

    func completeIAPTransactions() {
        SwiftyStoreKit.completeTransactions(atomically: true) { products in
            for product in products {
                if product.transaction.transactionState == .purchased || product.transaction.transactionState == .restored {
                    if product.needsFinishTransaction {
                    // Deliver content from server, then:
                        SwiftyStoreKit.finishTransaction(product.transaction)
                    }
                    print("purchased: \(product.productId)")
                }
            }
        }
    }
    

    在 application:didFinishLaunchingWithOptions 里调用上述的函数。因为 Apple 建议在 app 载入的时候为购买事务添加一个观察者:

    Adding your app's observer at launch ensures that it will persist during all launches of your app, thus allowing your app to receive all the payment queue notifications.

    SwiftyStoreKit 用 completeTransactions 函数实现了这个功能。这样,如果在载入的时候有任何进行中的事务,就可以对它们进行处理,更新 app 的状态和 UI。

    内购买测试

    完成内购买的代码后,在提交审核之前,还应该对它进行测试。Apple 为应用内购买项目提供了沙箱(sandbox)测试,让你使用虚拟的货币模拟内购过程。

    a) 在 iTunesConnect 的“用户与职能”里添加沙箱技术测试员。

    b) 在 iPhone 设置里的 “iTunes Store 与 App Store” 将原来的账号注销。但是不要登陆测试员的账号。

    c) 打开待测试内购买的 app,点击内购买的项目进行购买。这时候,会提示登录 App Store,使用沙箱测试员的账号登录。

    d) 之后会弹出购买信息确认窗口,注意窗口内的提示信息 “Environment: Sandbox“,表示是在沙箱中测试,购买的货币是虚拟的。如果没有这一行的话,则是在真实的环境中进行交易,使用的就是真实的货币了。

    结语

    测试完成后就可以提交审核了。如果是首次添加内购买项目,记得在 app 审核页添加内购项目一起提交审核。当再次添加内购买项目,就可以独立审核内购买项目,而无需提交新的 app 版本。当然,这样做的前提是 app 能够从自己的服务器上获取内购买项目的 productID,否则 app 无法获取新内购买项目的信息。

    本文是以消费性内购买项目为例,对于其他类型的内购买项目,方法大同小异,更多的信息请参考官方文档

    欢迎访问我的Github:LinShiwei (Lin Shiwei) · GitHub

    有任何疑问的话,欢迎在下方评论区讨论。

    相关文章

      网友评论

      • MMD_:SwiftyStoreKit这个组建必须要公共秘钥嘛?通过StoreKit内购为啥不要私钥呢,?????
      • Yinper:提交项目被拒 内购列表全部暴红
        被拒的原因是 : 我们无法完成对您的应用的审核,因为您的一个或多个应用内购买产品尚未提交审核。
        但是我已经提交了呀
      • LianC:内购项目怎么删除啊?上个月还删除来着,这个月怎么找不到了
        b4eca60cadbc:@邢泽 鼠标放到内购项目的任意一行上,右边就会出现一个红色的减号
        邢泽:内购项目怎么删除啊。。。 死活找不到删除按钮
      • e8ac74ae83e9:急,版本提审时把还没完成的内购项目给勾选了,跟着版本一起提交,结果被拒。回复是月卡计费点,在游戏中没找到购买入口,我想把月卡计费点移除,怎么操作?
        Linsw:@fcltuteng 把这个内购项目删除了呗?
      • ArchLL:急!! 我之前版本中已经有内购项目,现在如果想新增几个内购项,可以先提交内购项目审核,等内购项目审核通过了之后,再提交新的应用的版本?
        ArchLL:@疾风小超 需要啊,在新版本提交的时候把新增的内购项目也勾选提交即可。
        疾风小超:请问,新增的内购项不需要在APP中展示么?如果展示的话,线上用户怎么购买呢,可以购买成功么
        Linsw:@Mint丶bin 可以
      • 529f167dd23e:如果看到 请回复下 2695531878@qq.com 谢谢
      • 529f167dd23e:我现在 的APP内部购买 项 的状态是 准备提交 ,我在测试购买的时候 说 productID 无效
        Linsw:准备提交就行。确保 bundleID 和 iTunesConnect 上的 AppID 一致。还有完成银行、税务等信息。
      • 529f167dd23e:哥,你的意思是 只有 APP内购项目 的状态是 已经批准 才能测试吗
      • 谢谢生活:新建内购买项目后,在内购买项目列表里显示为“准备提交”状态。现在在准备提交的 App 版本中添加刚刚新建的内购买项目。 这句话什么意思?是把app提交审核吗?
        Linsw:@谢谢生活 对,第一次为 app 添加内购买项目时,需在新的 app 版本中连同 app 一起提交审核。

      本文标题:iOS:为 App 添加内购买项目

      本文链接:https://www.haomeiwen.com/subject/xzpugttx.html