在@Observable中使用@AppStorage

所属分类:ios | 发布于 2024-12-26

@Observable是苹果在WWDC23推出的Observation Framework中提出的。可以更加便利的实现类似ObservableOjbect的效果。

但是在@Observable中不支持@AppStorage包装器,我们可以这样使用:

@Observable
class MyModel {
    // Externally visible properties
    @ObservationIgnored var name: String {
        get {
            access(keyPath: \.name)
            return _name
        }
        set {
            withMutation(keyPath: \.name) {
                _name = newValue
            }
        }
    }
    
    // Internal stored properties
    @ObservationIgnored @AppStorage("name") private var _name: String = "Bob"
}

比如在自己的项目中使用:

// pipWindowPosition
@ObservationIgnored var pipWindowPosition:PipWindowPosition {
    get {
        access(keyPath: \.pipWindowPosition)
        return _pipWindowPosition
    }
    set {
        withMutation(keyPath: \.pipWindowPosition) {
            _pipWindowPosition = newValue
        }
    }
}
@ObservationIgnored @AppStorage("pipWindowPosition") private var _pipWindowPosition: PipWindowPosition = .topTraining

在stackoverflow中还有人提供了另外一种方法,原理是封装了两个泛型函数来直接操作UserDefaults,没有测试过,这里贴出来:

@Observable class AppPreferences {
    
    //    @AppStorage("username") var username: String = ""
    public var username: String {
        get { appStorageGetter(keyPath: \.username, name: "username", defaultValue: "") }
        set { appStorageSetter(keyPath: \.username, name: "username", newValue: newValue) }
    }

    // Generic functions to help workaround the issue with @AppStorage properties in an @Observable class
    private func appStorageGetter<T>(keyPath: KeyPath<AppPreferences, T>, name: String, defaultValue: T) -> T where T : Decodable {
        access(keyPath: keyPath)
        if let data = UserDefaults.standard.data(forKey: name) {
            return try! JSONDecoder().decode(T.self, from: data)
        } else {
            return defaultValue
        }
    }
    
    private func appStorageSetter<T>(keyPath: KeyPath<AppPreferences, T>, name: String, newValue: T) where T : Encodable {
        withMutation(keyPath: keyPath) {
            let data = try? JSONEncoder().encode(newValue)
            UserDefaults.standard.set(data, forKey: name)
        }
    }
    
}

 

文哥博客(https://wenge365.com)属于文野个人博客,欢迎浏览使用

联系方式:qq:52292959 邮箱:52292959@qq.com

备案号:粤ICP备18108585号 友情链接