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

SwiftUI集成Glassfy内购成功后如何通过AppStorage更新视图

问题原因
  • @AppStorage的自动视图刷新能力仅对SwiftUI View 内声明的属性生效,你把它写在IAPManager普通单例类中时,它只是个普通属性,修改后不会向SwiftUI发送刷新通知,自然不会触发视图切换。
  • Glassfy的回调默认运行在后台线程,直接更新UI相关状态会导致刷新延迟甚至不生效。
最简修复方案(仅用AppStorage实现,无需额外状态管理)

第一步:清理IAPManager中的无效属性

删除IAPManager里的这行代码:

@AppStorage("boughtFirst") var boughtFirst = false

第二步:在视图层声明可触发刷新的AppStorage属性

在你写购买/已购买内容切换逻辑的View结构体中,直接声明@AppStorage属性,只有在这里声明的属性变更才会自动触发视图重绘:

struct ContentView: View {
    // 仅在此处声明boughtFirst状态,修改后自动刷新UI
    @AppStorage("boughtFirst") private var boughtFirst = false

    var body: some View {
        NavigationView {
            VStack {
                if !boughtFirst {
                    BuyExtraContent()
                } else {
                    AllView()
                }
            }
        }
        .onAppear {
            // 页面每次展示时拉取最新权限,避免本地缓存状态和实际购买状态不一致
            IAPManager.shared.getPermissions()
        }
    }
}

原来的两个平行if判断可以直接换成if-else,逻辑更清晰。

第三步:修改IAPManager中的状态更新逻辑

@AppStorage本质是监听UserDefaults对应键值的变化,你不需要持有这个属性,只要在任意位置更新UserDefaults中对应key的值,视图就会自动刷新。
同时注意:所有Glassfy的回调都要切回主线程再更新状态,避免线程问题导致不刷新。

把IAPManager三个方法(purchase/getPermissions/restorePurchases)中原来写self.boughtFirst = true的位置,全部替换为以下代码:

// 切回主线程更新存储值
DispatchQueue.main.async {
    UserDefaults.standard.set(true, forKey: "boughtFirst")
}

以purchase方法为例,修改后的核心逻辑是:

func purchase(sku: Glassfy.Sku) {
    Glassfy.purchase(sku: sku) { transaction, error in
        guard let t = transaction, error == nil else {
            return
        }

        if t.permissions["numberOne"]?.isValid == true {
            NotificationCenter.default.post(
                name: Notification.Name("numberOne"),
                object: nil
            )
            DispatchQueue.main.async {
                UserDefaults.standard.set(true, forKey: "boughtFirst")
            }
        }
    }
}

getPermissions和restorePurchases里的状态更新逻辑按同样方式修改即可。

方案说明
  • 不需要让IAPManager遵循ObservableObject,不需要加@Published或者其他第三方状态管理工具,完全符合你想用最简逻辑、仅靠AppStorage实现状态同步的需求。
  • 只要购买/恢复/权限校验通过,更新UserDefaults后,所有声明了@AppStorage("boughtFirst")的视图都会立刻自动刷新,切换到已购买内容页。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 05:06:29