IOS开发入门iOS 内付费(in-app purchase)-非消耗品的购买与恢复
白羽 2019-07-10 来源 :网络 阅读 701 评论 0

摘要:本文将带你了解IOS开发入门iOS 内付费(in-app purchase)-非消耗品的购买与恢复,希望本文对大家学IOS有所帮助。

    本文将带你了解IOS开发入门iOS 内付费(in-app purchase)-非消耗品的购买与恢复,希望本文对大家学IOS有所帮助。

IOS开发入门iOS 内付费(in-app purchase)-非消耗品的购买与恢复

iOS内付费的功能对于一个app来说是非常重要的,如果在这一环节出了一些致命的问题,那就很可能会影响app的推广和公司的利益了。
   我在很早之前写过一篇关于iOS内付费的文章(文章地址),在那篇博客中讲述了如何在苹果后台生成iOS内付费商品,以及在我们的app工程中如何去添加相应的内付费代码。但是,在后来的日子里面我发现网友在关于内购功能上遇到的问题比我想象的还要多,其中很大一部分都是一些很简单的问题,比如说签名使用的不正确,内购商品ID不正确,bundleID没有和签名一致,苹果账号没有补充完整银行税务信息等导致的,只要简单的修改一下就能解决以上问题。
   另外,很多app项目创建的内购商品都是以“消耗品“  ,这种类型的商品为主,不过有的网友也遇到了其他的问题,他在app中创建了几个非消耗品的内购商品,然后提交苹果审核的时候,却被苹果打回了,原因是苹果要求开发者对这种非消耗品的商品增加一个“恢复“的按钮。
   Apple 打回的原文如下:
   ?12345678910Business - 3.1.1  We found that your app offers  In-App Purchase(s) that can be restored but does not include a "Restore  Purchases" feature to allow users to restore the previously purchased  In-App Purchase(s), as specified in the "Restoring Purchase  Products" section of the In-App Purchase Programming  Guide "Users restore transactions to maintain access to content  they've already purchased. For example, when they upgrade to a new phone,  they don't lose all of the items they purchased on the old phone. Include  some mechanism in your app to let the user restore their purchases, such as a  Restore Purchases button." To restore previously purchased In-App  Purchase products, it would be appropriate to provide a "Restore"  button and initiate the restore process when the "Restore" button  is tapped by the user. Before You Submit
   今天,我在这篇文章中就来针对上述的苹果打回的问题做出解决方案。
   
   “非消耗品的购买和恢复” 该如何操作
   创建非消耗品(non-consumable)
   在 iTunesconnect 后台中创建一个非消耗品,根据内购商品所需要的内容编辑完整。创建的选项如下图所示:
   
   内购流程梳理
   非消耗品第一次购买的逻辑和消耗品是一样,我们先来理一遍内购的流程,首先在代码中我们一定要在内购初始化的地方加上这句代码:
  [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
   不然购买成功和失败的任何回调你都收不到。在初始化之后,要去苹果服务器那获取我们所要提供给用户的详细商品信息,代码逻辑如下:
  - (void)  requestProductData{    if(!self.mRequestProductDataObjects  || self.mRequestProductDataObjects.count ==  0){        return;    }     if  ([SKPaymentQueue  canMakePayments])    {        NSArray  *product = nil;        product =  [NSArray arrayWithArray:_mRequestProductDataObjects];        NSSet  *nsset = [NSSet  setWithArray:product];        SKProductsRequest  *request=[[SKProductsRequest alloc] initWithProductIdentifiers:  nsset];        request.delegate =  self;        [request  start];    }     ...}
   在保证商品id正确的情况下,我们的程序会把获取到的商品信息回调到此函数中:
   - (void)productsRequest:(SKProductsRequest *)request  didReceiveResponse:(SKProductsResponse *)response  NS_AVAILABLE_IOS(3_0);
   解析商品信息的逻辑,我这边就不细说了,要看详细的代码,就去我这篇文章中 iOS应用程序内购/内付费看吧!
   在获取到商品信息之后,我们就可以开始进行购买了,购买的逻辑函数如下:
   - (void) purchase:(NSString*)  productId{    if(productId.length == 0 ||  !productId){        return;    }     SKProduct  * _payProduct  =nil;     if ([SKPaymentQueue  canMakePayments])    {        for  (SKProduct * payment in self.purchasableObjects)  {            if  ([productId isEqualToString:payment.productIdentifier]  )            {                _payProduct  = payment;                break;            }        }    }     if(!_payProduct){        return;    }     SKMutablePayment  * payment = [SKMutablePayment paymentWithProduct:_payProduct];    [[SKPaymentQueue  defaultQueue] addPayment:payment];}
   上述函数的内部逻辑走完以后,就会回调此方法了:
    (void)paymentQueue:(SKPaymentQueue  *)queue updatedTransactions:(NSArray *)transactions{    for  (SKPaymentTransaction *transaction in  transactions){        switch  (transaction.transactionState)        {            case  SKPaymentTransactionStatePurchased:                [self  completeTransaction:transaction];                NSLog(@"支付成功");                break;             case  SKPaymentTransactionStateFailed:                [self  failedTransaction:transaction];                NSLog(@"支付失败");                break;             case  SKPaymentTransactionStateRestored:                [self  restoreTransaction:transaction];                NSLog(@"交易恢复处理");            default:                break;        }    }}
   在这个回调函数的内部逻辑里面,分别有对购买成功,购买失败,恢复交易的处理。好了,经过一遍简单的梳理以后,想必你已经在心中有了一个大概,接下来就是我们的重头戏了。
   恢复按钮怎么添加?
   正常情况下,非消耗品的内购商品在购买成功后,应该把 “购买” 字样变成 “恢复”  字样,当用户完成一次购买以后,就可以永久使用啦!那在什么时机去修改这个按钮呢。
   当非消耗品完成一次购买以后,再次去点击购买的话,系统会提示你已经购买了此项目,如图:
   
   为了确保我们的app在每次运行起来后,内购商品列表能正确显示,哪些非消耗商品是已经购买过的,我们得在内购功能初始化的地方(就是添加监听函数下面)调用该函数,来获取哪些商品是已经买过的:
   [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
   该函数调用后会恢复之前的交易,程序会直接进入到函数updatedTransactions的回调:
    (void)paymentQueue:(SKPaymentQueue *)queue  updatedTransactions:(NSArray *)transactions{   case  SKPaymentTransactionStateRestored:                ..... }
   然后再走到此回调函数:
   - (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue  *)queue
   我们可以给上面函数中添加如下逻辑,用一个NSMutableArray来存储苹果回调过来给我们已经购买过的非消耗品的商品信息:
   - (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue  *)queue{    purchasedItemIDs = [[NSMutableArray alloc]  init];    NSLog(@"received restored transactions:  %i", queue.transactions.count);    for  (SKPaymentTransaction *transaction in  queue.transactions)    {        NSString  *productID =  transaction.payment.productIdentifier;        [purchasedItemIDs  addObject:productID];        NSLog(@"%@",purchasedItemIDs);    }}
   在这里我们已经获取到了所有已经购买过的非消耗品的  transactions,那最后一步就是回调app界面去修改按钮名称咯。那有些人会问,如果我换了设备怎么办,其实也很简单,iOS内购商品是跟着你的Apple  ID走的,你换到新设备后登录你的Apple ID帐号,启动app就会走到restoreCompletedTransactions函数,苹果还是会给你推送过来你购买过的非消耗品信息,然后再去修改app按钮是显示  购买 还是 恢复 。
   最后关于在app内购买非消耗品  ,道具应该怎么下发,我做一下自己的理解说明吧!非消耗品不管是第一次购买,还是恢复购买,苹果验证票据返回过来的信息都是一致的,如图所示:
   
   所以,我们在第一次购买非消耗品的时候,待苹果服务器票据验证成功后,服务器要将玩家的账号信息(非Apple ID账号,再说你app也获取不到)和  该商品ID保存在数据库中;玩家若换设备或者卸载了app以后,再次想要获取该道具,我们就可以直接根据玩家的账号信息和商品ID去数据库中查找,若已经购买过了,就可以直接下发道具。
   总结
   关于iOS内购的功能其实代码就那么些,但是如果你真的要做到内购功能很健壮,例如购买东西时不丢单,游戏充值到账等,确实要花很多精力去研究,这不单单是客户端的任务,还包括服务器如何保存票据,丢单的时候如何去补单这些操作。好了,写了这么些,不早了也该歇歇了,若有什么问题的话,请加以下公众号联系我。   


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程