【问题标题】:How to use @AppStorage inside a model with @Published and store In App Purchased products如何在具有@Published 的模型中使用@AppStorage 并存储在应用内购买的产品
【发布时间】:2020-12-05 12:00:19
【问题描述】:

我知道@AppStorage 只能在视图内部使用,但我更喜欢管理模型并利用@AppStorage 的优势。

例如,如果我想将购买的产品存储在In App Purchasing,我可以使用此解决方法还是最好避免这样做?

typealias PurchasedProductIdentifiers = Set<String>

extension PurchasedProductIdentifiers: RawRepresentable {
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8),
            let result = try? JSONDecoder().decode(PurchasedProductIdentifiers.self, from: data)
        else {
            return nil
        }
        self = result
    }
    public var rawValue: String {
        guard let data = try? JSONEncoder().encode(self),
            let result = String(data: data, encoding: .utf8)
        else {
            return "[]"
        }
        return result
    }
}

class MyModel: NSObject, ObservableObject {
    
    @Published var purchasedPub: PurchasedProductIdentifiers = [] {
        didSet {
            purchased = purchasedPub
        }
    }
    @AppStorage("purchased") private var purchased = PurchasedProductIdentifiers(["p1"])
    
    override init() {
        super.init()
        self.purchasedPub = self.purchased
    }
}

struct TestView: View {

    @StateObject var model: MyModel = MyModel() 
        
    var body: some View {
        
        VStack (alignment: .leading){
            HStack {
                Image(systemName: model.purchasedPub.contains("p1") ? "lock.open":"lock")
                Text("\("p1")")
                Button(action: {
                    model.purchasedPub.insert("p1")
                }, label: {
                    Text("buy")
                })
                Button(action: {
                    model.purchasedPub.remove("p1")
                }, label: {
                    Text("remove")
                })
            }
            HStack {
                Image(systemName: model.purchasedPub.contains("p2") ? "lock.open":"lock")
                Text("\("p2")")
                Button(action: {
                    model.purchasedPub.insert("p2")
                }, label: {
                    Text("buy")
                })
                Button(action: {
                    model.purchasedPub.remove("p2")
                }, label: {
                    Text("remove")
                })
            }
        }
    }
}



struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

【问题讨论】:

  • AppStorage 仅在视图中是全功能的,因此在模型类内部没有使用它的意义。请改用 UserDefaults。

标签: swift iphone swiftui in-app-purchase appstorage


【解决方案1】:

添加 willSet {..} 并在 ObservableObject 上调用 send():objectWillChange.send()

例如:

@AppStorage("purchased") 
private var purchased = PurchasedProductIdentifiers(["p1"]) {
   willSet {
      DispatchQueue.main.async {
         self.objectWillChange.send()
      }
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多