前言
目前有很多关于iOS内购帖子及开源项目,但是没有一个相对合适自己项目的,所以就多研究下.主要还是因为苹果的IAP太坑了,所以笔者自己基于目前网上的部分代码以及平时项目的BUG反馈封装了一套内购方案和大家分享探讨.
内购的坑
其实苹果的IAP还是做了很多操作了,但是现实用起来发现还是有很多坑爹的地方,防不胜防.由于自己项目须在IAP进行前就需要获取一个自己服务器的订单才能进行IAP购买验证,所以会出现以下几个问题:
- 用户购买,IAP无回调响应,用户退出程序导致定单异常.
- 原因:用户虽然点击了购买就储存了订单,但是还没有进入了苹果的内购队列,所以用户退出后再次进入本地就会有个僵尸订单,无法清除.所以储存订单应该在
- 解决办法:SKPaymentTransactionStatePurchasing时才储存.
- 用户完成苹果购买,自己的服务器网络发生错误,无法及时到账.
- 原因:一般是因为在SKPaymentTransactionStatePurchased后就结束订单了,自己的储存方案有异常.
- 解决办法:在没有自己服务器得到验证订单状态前就不finish订单,程序再启动或者再次监听IPA时苹果会再次通过
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
回调未结束的订单,即使重新安装程序也会有回调.
- SKPaymentTransaction.applicationUsername丢失,程序崩溃.
- 原因:applicationUsername丢失的问题相信很多开发者都遇到过...苹果坑逼.
- 解决办法:通过对比UserID以及productIdentifier来确定一个以前在SKPaymentTransactionStatePurchasing时储存的订单.看似有点问题,但是因为苹果的交易是串行的,如果自己验证也是串行验证,那么通过UserID和productIdentifier就能确定为同一个订单了.
- 用户卸载程序导致本地订单号丢失.
- 原因:购买订单时的数据存储在本地,删除应用就丢失.
- 解决办法:通过储存在keychain里面防止丢失.
- 获取本地苹果票据为空.
- 原因:有可能删除应用后重新安装,这个时候本地票据可能是空的,导致验证失败.
- 解决方法:通过SKReceiptRefreshRequest刷新票据得到最新的苹果票据.
由于内购的地方很多,为此封装了一套JKIAPHelp用于快速接入.
JKIAPHelp基本逻辑:
- 用户注册后,开始购买商品,把自己服务器上的订单号传给JKIAPHelp.
- JKIAPHelp在系统支付回调
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
SKPaymentTransactionStatePurchasing时将订单相关信息(订单号以及物品价格)加入到钥匙串中保证订单信息的完整性与可靠性.
- 在SKPaymentTransactionStatePurchased的时候来验证订单.验证是通过开发者实现JKIAPHelp代理
-(void)verifyWithModel:(JKIAPTransactionModel *)model resultAction:(VerifyRsultBlock)resultAction
来向开发者自己的服务器完成订单的验证.(开发者通过调用resultAction回调服务器验证状态).
- 如果验证出现失效或者完成,那么就判断当前的用户是否和创建订单时候的用户一致,如果一致那么久删除钥匙串里对应的订单完成购买,不一致的话就将状态同步到钥匙串里,当下一次用户注册时通过补发货的回调来通知开发者.
- 如果服务器验证网络错误,就同步钥匙串订单状态.当用户点击购买,从后台进入程序,重新注册JKIAP时就会检测当前未完成的订单,将未完成的订单再次验证,如果再次发生错误就下一次再验证,有多个未完成的话就继续验证下一个订单.
网友评论