开发tweak时实现localiap购买无receipt,重启应用需重复购买求助
LocalIAP Tweak 购买状态不持久化问题排查方案
当前实现仅覆盖了单次点击购买后的成功回调模拟,没有覆盖StoreKit框架完整的交易持久化、启动时状态恢复、本地收据校验三个核心链路,所以应用重启后读不到任何持久化的购买记录,才会反复要求重新走购买流程。
具体排查与修复方向
- 补全交易持久化存储逻辑
在应用沙盒可访问的路径(比如沙盒下Library/Application Support目录)建立独立的plist存储文件,保存所有模拟购买成功的商品ID、对应固定的交易标识、交易时间戳。不要把购买记录存在tweak的私有容器路径,避免沙盒权限隔离导致读取失败;也不要仅依赖UserDefaults存储——部分应用会主动清空偏好目录的内容重置状态。 - 补全启动阶段的交易状态回调逻辑
绝大多数应用启动时,会主动注册SKPaymentTransactionObserver观察者,同时触发-[SKPaymentQueue restoreCompletedTransactions]方法拉取历史已购交易。你需要在这两个节点,主动把之前存储的已购商品打包为SKPaymentTransactionStatePurchased(也就是你当前已经能正常处理的transactionState=1对应状态)的交易对象回调给应用,而不是只在用户手动点击购买按钮时才触发回调。 - 补全本地收据的动态生成逻辑
应用重启后做购买校验时,一定会读取-[NSBundle appStoreReceiptURL]指向的本地收据文件。如果应用读到的是不包含已购商品信息的空收据,就会直接判定所有商品为未购买状态。你需要hook收据读取接口,动态在返回的收据内容里拼接上所有已购商品对应的交易字段,保证应用校验收据时能识别到已购记录——这也是你怀疑“无对应receipt”问题的核心补全方向。 - 匹配IAP Crackers复现问题的共性根因
你观察到IAP Crackers出现了完全一致的问题,本质是这类老旧的破解工具普遍只实现了“点击购买后返回成功”的单步模拟,没有实现收据动态生成、启动状态恢复的完整链路,和你当前的实现缺漏完全一致,不属于你单独写的逻辑有特殊bug。 - 细节避坑
模拟生成的SKPaymentTransaction对象的交易标识要和本地存储的商品ID一一对应、固定生成,不要每次回调时随机生成新的交易ID,避免应用判定为异常交易后清空状态;同时要正确hook-[SKPaymentQueue finishTransaction:]方法,拦截应用对模拟交易的苹果服务器上报流程,避免触发无效校验导致状态异常。
内容的提问来源于stack exchange,提问作者Kurax Scoresx
相关产品推荐
相关产品推荐

