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

2023-11-30 16:58

本文主要是介绍iOS 内付费(in-app purchase)--非消耗品的购买与恢复,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里写图片描述


iOS内付费的功能对于一个app来说是非常重要的,如果在这一环节出了一些致命的问题,那就很可能会影响app的推广和公司的利益了。

我在很早之前写过一篇关于iOS内付费的文章(文章地址),在那篇博客中讲述了如何在苹果后台生成iOS内付费商品,以及在我们的app工程中如何去添加相应的内付费代码。但是,在后来的日子里面我发现网友在关于内购功能上遇到的问题比我想象的还要多,其中很大一部分都是一些很简单的问题,比如说签名使用的不正确,内购商品ID不正确,bundleID没有和签名一致,苹果账号没有补充完整银行税务信息等导致的,只要简单的修改一下就能解决以上问题。

另外,很多app项目创建的内购商品都是以“消耗品“ ,这种类型的商品为主,不过有的网友也遇到了其他的问题,他在app中创建了几个非消耗品的内购商品,然后提交苹果审核的时候,却被苹果打回了,原因是苹果要求开发者对这种非消耗品的商品增加一个“恢复“的按钮。

Apple 打回的原文如下:

Business - 3.1.1We 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 内付费(in-app purchase)--非消耗品的购买与恢复的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437805

相关文章

Git中恢复已删除分支的几种方法

《Git中恢复已删除分支的几种方法》:本文主要介绍在Git中恢复已删除分支的几种方法,包括查找提交记录、恢复分支、推送恢复的分支等步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录1. 恢复本地删除的分支场景方法2. 恢复远程删除的分支场景方法3. 恢复未推送的本地删除分支场景方法4. 恢复

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

如何恢复回收站中已删除/清空的文件

回收站清空后如何恢复已删除的文件?是否可以恢复永久删除的文件?或者最糟糕的是,如果文件直接被删除怎么办?本文将向您展示清空回收站后恢复已删除数据的最佳方法。 回收站清空后如何恢复已删除的文件? “回收站清空后我还能恢复已删除的文件吗?” 答案是肯定的,但是在这种情况下您将需要一个  回收站恢复工具 来从回收站中检索文件: 错误/永久删除回收站或任何数字存储设备中的文件 直接删除的文件/