我使用UserDefaults的值设置我的WidgetView。为了在小部件和核心应用程序之间共享数据,我已经设置了appGroup。
let appGroupId = "group.com.myAppGroupId"
Text(UserDefaults(suiteName: appGroupId)!.object(forKey: "githubId") as? String ?? "??")它在预览中显示良好,但当我将它添加到主屏幕时,它无法读取属性。在同样的情况下,当我重新构建应用程序(cmd+r)时,主屏幕中的小工具可以很好地读取UserDefaults的值。
我猜不出原因。
+添加更多代码
实际上,我使用属性包装将我的githubId定义为UserDefaults,如下所示。
extension UserDefaults {
    enum Key: String {
        case githubId
    }
  
    static let shared: UserDefaults = {
        let appGroupId = "group.com.myAppGroupId"
        return UserDefaults(suiteName: appGroupId)!
    }()
    @UserDefault(key: .githubId)
    static var githubId: String?
}我的属性包装器是这样的。
@propertyWrapper
struct UserDefault<Value> {
    let key: String
    let defaultValue: Value
    var container: UserDefaults = .shared
    private let publisher = PassthroughSubject<Value, Never>()
    
    var wrappedValue: Value {
        get {
            return container.object(forKey: key) as? Value ?? defaultValue
        }
        set {
            if let optional = newValue as? AnyOptional, optional.isNil {
                container.removeObject(forKey: key)
            } else {
                container.set(newValue, forKey: key) //this is where I set my value
            }
            publisher.send(newValue)
        }
    }
    var projectedValue: AnyPublisher<Value, Never> {
        return publisher.eraseToAnyPublisher()
    }
}
extension UserDefault where Value: ExpressibleByNilLiteral {
    init(key: UserDefaults.Key, _ container: UserDefaults = .shared) {
        self.init(key: key.rawValue, defaultValue: nil, container: container)
    }
}在LoginViewModel中,我设置了githubId的值。
class LoginViewModel: ObservableObject {
    @Published var githubId = UserDefaults.githubId ?? ""
    private var subscriptions = Set<AnyCancellable>()
    
    init() {
        $githubId
            .sink { githubId in
                UserDefaults.githubId = githubId
            }
            .store(in: &subscriptions)
    }
}最后,我使用UserDefaults.githubId在我的应用程序和小部件扩展中使用此值
我在上面写的代码( UserDefaults(suiteName: appGroupId)!.object(forKey: "githubId") )是UserDefaults.githubId的长版本。
发布于 2021-07-11 23:06:25
.sink不能在窗口小部件中工作。
在设置时间线时,必须完成要在小部件中显示的任何内容。窗口小部件不会监听更改。
当有变化时,你必须从应用程序中重新加载小部件时间线。将每个时间线条目视为屏幕截图。
WidgetCenter.shared.reloadAllTimelines()
重新加载是计量的,所以一定要检查一下,不要过多地重新加载。
https://stackoverflow.com/questions/68335835
复制相似问题