Как мне перехватить изменение значения, которое было изменено с помощью функции в SwiftUI?

#swift #swiftui #observableobject

#swift #swiftui #observableobject

Вопрос:

Мое представление не проверяет, изменилось ли значение. Можете ли вы сказать мне, почему, или вы можете мне помочь?

Вы можете увидеть ниже важный код.

Мой класс

 import SwiftUI
import SwiftyStoreKit

class Foo: ObservableObject {
 @Published var Trigger : Bool = false
  
 func VerifyPurchase() { 
      let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "your-shared-secret")
      SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
           switch result {
                case .success(let receipt):
                     let productId = "com.musevisions.SwiftyStoreKit.Purchase1"
                     // Verify the purchase of Consumable or NonConsumable
                     let purchaseResult = SwiftyStoreKit.verifyPurchase(
                          productId: productId,
                          inReceipt: receipt) 
                     
                     switch purchaseResult {
                          case .purchased(let receiptItem):
                               print("(productId) is purchased: (receiptItem)")
                               
                               self.Trigger.toggle()
                               
                          case .notPurchased:
                               print("The user has never purchased (productId)")
                               
                               self.Trigger.toggle()
                     }
                case .error(let error):
                     print("Receipt verification failed: (error)")
                     
                     self.Trigger.toggle()
                     
           }
      }
 } 
} 
  

В SceneDelegate мой важный код в sceneDidbecom, чтобы значение было равно true, а затем, если функция завершена, я хочу, чтобы триггер вернулся к false

  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 

      let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

      let foo = Foo()
      let contentView =  ContenView(foo: Foo).environment(.managedObjectContext, context) 
       
      if let windowScene = scene as? UIWindowScene {
          let window = UIWindow(windowScene: windowScene)
          window.rootViewController = UIHostingController(rootView: contentView)
          self.window = window
          window.makeKeyAndVisible()
      }
 }


 func sceneDidBecomeActive(_ scene: UIScene) {
 let foo = Foo()
 foo.Trigger = true
 foo.VerifyPurchase()
 }
  

Мое представление, которое не обновляется самостоятельно, когда значение изменилось.

 struct ContentView: View {
   @ObservedObject var foo: Foo
 
    var body: some View {
      Text(self.foo.Trigger ? "true" : "false")
    }
}
  

Ответ №1:

SwiftyStoreKit.verifyReceipt это асинхронная функция, и @Published переменные должны обновляться в основном потоке.

Попробуйте добавить, DispatchQueue.main.async когда вы изменяете Trigger переменную в фоновом режиме:

 SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
    ...
    DispatchQueue.main.async {
        self.Trigger = false
    }
}
  

Также обратите внимание, что переменные в Swift обычно имеют нижний регистр — ie. trigger вместо Trigger .


Вы также используете два разных Foo экземпляра в своем проекте.

Я рекомендую вам удалить код из func sceneDidBecomeActive(_ scene: UIScene) и переместить его в .onAppear в ContentView :

 struct ContentView: View {
   @ObservedObject var foo: Foo
 
    var body: some View {
      Text(self.foo.Trigger ? "true" : "false")
        .onAppear {
            foo.Trigger = true
            foo.VerifyPurchase()
        }
    }
}
  

Также вместо

 Text(self.foo.Trigger ? "true" : "false")
  

вы можете сделать

 Text(String(describing: self.foo.Trigger))