swift 在运行时期间切换iCloud同步

cyvaqqii  于 2023-09-30  发布在  Swift
关注(0)|答案(2)|浏览(163)

我有一个SwiftUI应用程序,用户可以在应用程序内购买一些高级功能。其中一个功能是iCloud同步到更多设备。我正在使用CoreData保存用户数据。我的持久化容器:

lazy var persistentContainer: NSPersistentCloudKitContainer = {
        let container = NSPersistentCloudKitContainer(name: "store name")
        let description: NSPersistentStoreDescription? = container.persistentStoreDescriptions.first
        let remoteChangeKey: String = "NSPersistentStoreRemoteChangeNotificationOptionKey"
        if(description != nil) {
            description!.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
            description!.setOption(true as NSNumber, forKey: remoteChangeKey)
        }
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

我的问题是,当用户购买订阅时,我如何打开/关闭云同步。我不想让用户重新启动应用程序。我还希望用户可以在应用程序内设置中切换此设置。

63lcw9qa

63lcw9qa1#

将变量声明为NSPersistentContainer而不是NSPersistentCloudKitContainer。启动时,如果用户有云同步,则加载云套件持久容器,否则加载非云套件持久容器。
切换开关后,按照相同的规则重新加载容器。为了重新加载容器,我将属性添加到管理器对象中,在其中我将添加一些方法,这些方法根据用户的设置重新加载容器。

06odsfpq

06odsfpq2#

根据苹果工程师给出的答案,正确的方法是在想要禁用iCloud同步时将cloudKitContainerOptions设置为nil。但是,简单地将其设置为nil并不起作用。每次用户更改其首选项时都需要创建一个新的容器

class DataController: ObservableObject {

    private var container: NSPersistentCloudKitContainer!

    init(iCloudSync: Bool) {
        setupContainer(iCloud: iCloudSync)
    }

    private func setupContainer(iCloud: Bool) {
        container = NSPersistentCloudKitContainer(name: "Model_Name")

        guard let description: NSPersistentStoreDescription = container.persistentStoreDescriptions.first else {
            fatalError()
        }

        description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
        description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)

        if iCloud == false {
            description.cloudKitContainerOptions = nil
        }

        container.loadPersistentStores { description, error in
            if let error {
                print("Failed to load data \(error.localizedDescription)")
            }
        }
    }

    var iCloudSync: Bool {
        get { container.persistentStoreDescriptions.first!.cloudKitContainerOptions != nil }
        set { setupContainer(iCloud: newValue) }
    }
}

您可以拥有DataController的单例,也可以在AppDelegate中维护对象

相关问题