web-dev-qa-db-ja.com

Swiftui:userdefaultsを使用して@published変数を守る方法は?

私は@published変数を永続化させたいのですが、アプリを再起動するたびに同じです。

1つの変数に@userdefaultと@publishedプロパティラッパーの両方を使用します。たとえば、「@publishedUserDefault var islogedin 'が必要です。

次のPropertyWrapperがあります

import Foundation

@propertyWrapper
struct UserDefault<T> {
    let key: String
    let defaultValue: T

    init(_ key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: T {
        get {
            return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}
 _

これは私の設定クラスです

import SwiftUI
import Combine

 class Settings: ObservableObject {

   @Published var isLogedIn : Bool = false

 func doLogin(params:[String:String]) {

        Webservice().login(params: params) { response in

            if let myresponse = response {                    
                    self.login = myresponse.login
                    }
               }
         }

}
 _

私のビュークラス

struct HomeView : View {
    @EnvironmentObject var settings: Settings
    var body: some View {
        VStack {
            if settings.isLogedIn {
            Text("Loged in")
            } else{
            Text("Not Loged in")
            }
        }
    }
}
 _

持続的と公開の両方をカバーする単一のプロパティラッパーを作成する方法はありますか?

9
Sreeni

新しいプロパティラッパーを作成することは可能であるべきです。

手動でプロパティラッパータイプを作成できるため、この提案の最初の改訂から構成されていました。たとえば、@a @bはABラッパーとして実装できます。

@propertyWrapper
struct AB<Value> {
  private var storage: A<B<Value>>

  var wrappedValue: Value {
    get { storage.wrappedValue.wrappedValue }
    set { storage.wrappedValue.wrappedValue = newValue }
  }
}
 _

このアプローチの主な利点はその予測可能性です.ABの作者は、AとBの構成を適切に実現する方法を決定し、正しいAPIとそのセマンティクスの文書化を提供します。一方、各組成物を手動で書く必要があることは、特に主要な販売点がボイラープレートの除去である特徴のための多くの定式化である。各構成の名前を発明する必要があります--- @A @Bを介して作成すると、手作りのプロパティラッパータイプABを探すことができますか?それともBaになるべきですか?

Ref: プロパティWrappersProposal:SE-0258

1
Mycroft Canner

現在、現在許可されていないため、@UserDefault@Publishedを描くことはできません。

@PublishedUserDefaultを実装する方法は、objectWillChangeをラッパーに渡し、変数を設定する前に呼び出します。

0
Fabian