You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftyStoreKit IAP内购后购买状态不保存、广告栏不隐藏问题排查

问题原因&修复方案

1. IAP方法调用的实例错误

你在GameScene的弹窗回调中写的GameViewController().buytheIAP(),本质是新建了一个临时的GameViewController对象,不是当前App正在显示的那个已加载的控制器实例:

  • 这个临时实例没有和IAPHelper绑定代理,IAP购买成功后的purchaseDidSucceed、restoreDidSucceed回调根本不会触发,你可以检查日志是否有打印Purchased upgrade ENJOYYYYYYYY,正常情况应该是没有的
  • 临时实例的bannerView没有被加载到视图层级,就算回调触发也不会操作到当前界面的广告横幅
  • 临时实例会在执行完调用逻辑后立即被释放,所有状态修改都不会生效

修复代码

替换GameScene中原来的IAP调用逻辑,拿到当前的根控制器再调用方法:

// 替换购买按钮的回调
alert.addAction(UIAlertAction(title: "Remove Ads", style: .default, handler: { action in
    print("Pressed Remove Ads")
    if let rootVC = view?.window?.rootViewController as? GameViewController {
        rootVC.buytheIAP()
    }
}))
// 替换恢复购买按钮的回调
alert.addAction(UIAlertAction(title: "Restore Purchases", style: .default, handler: { action in
    print("Pressed Restore")
    if let rootVC = view?.window?.rootViewController as? GameViewController {
        rootVC.restoretheIAP()
    }
}))

2. UserDefaults读写方法错误

你当前保存购买状态的代码UserDefaults.setValue(true, forKey: iAPHelper.productID)是直接调用类方法,iOS中UserDefaults需要通过标准单例实例才能真正把数据写入本地沙盒,你现在的写法不会持久化存储购买状态,重启App后自然读不到值。

修复代码

把所有purchaseDidSucceed、restoreDidSucceed中的存储逻辑替换为:

// 替换原来的错误写法
UserDefaults.standard.set(true, forKey: iAPHelper.productID)
// 可选增加主动同步,避免极端情况写入延迟
UserDefaults.standard.synchronize()
bannerView.isHidden = true

同时确认viewDidLoad中读取的逻辑用的也是UserDefaults.standard,你当前代码里写的userDefaults如果是自己定义的变量,要保证它指向的是UserDefaults.standard实例。

可选优化

如果需要规避用户修改本地存储伪造购买的情况,可以在App启动时调用SwiftyStoreKit的本地收据校验方法,校验通过后再设置广告隐藏状态,安全性比单纯读取本地UserDefaults更高。


内容的提问来源于stack exchange,提问作者DannyRoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:36:03