在 SwiftUI 中使用 NSPersistentCloudKitContainer 实现共享

Posted

技术标签:

【中文标题】在 SwiftUI 中使用 NSPersistentCloudKitContainer 实现共享【英文标题】:Implementing Sharing with NSPersistentCloudKitContainer in SwiftUI 【发布时间】:2021-03-24 00:12:02 【问题描述】:

有可能吗?

我用 Core Data 和 Cloudkit 设置了一个新的 ios 14 应用程序。我必须对我的 Persistence.swift 文件进行一些更改才能使其正常工作,但它运行正常。

我有兴趣实现与other iCloud Users 的共享,但很多文档都已过时且令人困惑,而且似乎在某一时刻可能无法实现,但现在可以了吗?

我认为第一步是让我的数据库共享?我将以下行添加到我的 Persistence.swift 文件中

container.persistentStoreDescriptions.first!.cloudKitContainerOptions?.databaseScope = .shared

(这是全部内容):

import CoreData

struct PersistenceController 
    static let shared = PersistenceController()
    let container: NSPersistentCloudKitContainer

    init(inMemory: Bool = false) 
        container = NSPersistentCloudKitContainer(name: "Shopmatic")

        container.loadPersistentStores(completionHandler:  (storeDescription, error) in
            if let error = error as NSError? 
                fatalError("Unresolved error \(error), \(error.userInfo)")
            
        )

        container.viewContext.automaticallyMergesChangesFromParent = true
        container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        
        container.persistentStoreDescriptions.first!.cloudKitContainerOptions?.databaseScope = .shared
    

但是当我运行应用程序时,我收到以下错误

Thread 1: "CKDatabaseScopeShared is not supported with NSPersistentCloudKitContainer"

这不令人鼓舞,但也许可以实现与公共数据库范围的共享?

我不确定接下来的步骤是什么?实现我自己的 NSPersistentContainer 来同步到 cloudkit 并允许共享?

【问题讨论】:

您可以使用AppGroup 和分享cloud kit container @loremipsum 很有趣,我第一次听说 AppGroup,但我会进一步调查。如果您愿意,请随时详细说明完整的答案。 我稍后会发布一些代码(我现在离开我的 Mac)在尝试让 CoreData 与 Widget 和其他用户设备一起工作时遇到了这个问题。这并不完美,因为当编辑 CoreData 对象但小部件选择同时更新时,我无法更新小部件。 您想与同一设备中的扩展程序(即小部件)共享数据库吗?或者您想与其他人分享您的物品? @EmilioPelaez 哦,是的,我想实现与其他人的共享,即:developer.apple.com/documentation/cloudkit/shared_records/… 【参考方案1】:

我相信基于this thread on the Apple dev forums 的答案是否定的(我是那里的 MasonAndMuse),但那里有一位 Apple 工程师说是,但没有详细说明。很快我就停止了尝试,没有找到任何解决系统不透明性质的方法,就像现在这样。我所看到的没有任何迹象表明其他人已经开始使用它,但我在 8 个月前放弃后并没有仔细观察。当然可能有办法 - 我很想被证明是错误的!

我假设他们在 iOS 15 中引入了共享,但现在这不是很有帮助...太糟糕了,因为它现在已经很接近了,如果/当他们添加它时它将节省很多时间...

【讨论】:

哦,是的,我自己也看到了这个帖子,Apple 员工在开玩笑,这有点令人震惊!我会继续挖掘并根据任何发现更新此页面。【参考方案2】:

论坛里的苹果工程师answer我读得很清楚:

NSPersistantCloudKitContainer 不支持共享! 你需要实现CloudKit sharing through CK APIs。

我还没有实现这样的功能,但我会这样处理它:

    让 NSPersistantCloudKitContainer 实现工作。 在同一个容器上实现 CloudKit 共享。 开始将特定记录从 NSPersistantCloudKitContainer 传递到第 2 步中实现的共享功能中。

使用 CKDatabase.Scope = shared 访问共享的 Cloudkit 数据库:

如果这是 NSPersistentCloudKitContainer:

container = NSPersistentCloudKitContainer(name: "AppName")


我会尝试像这样访问这个容器的共享数据库:

let myAppsCloudKitContainer = CKContainer(identifier: "iCloud.com.name.AppName")
let myContainersSharedDatabase = myAppsCloudKitContainer.database(with: .shared)

要从 NSPersistantCloudKitContainer 访问数据以用于 CloudKit 共享功能,请使用 NSPersistantCloudKitContainer 实例方法

record(for managedObjectID: NSManagedObjectID)

(从 macOS 11 / Xcode 12 开始)

【讨论】:

它确实支持共享:developer.apple.com/videos/play/wwdc2021/10015 虽然我认为还没有人让它工作。即使他们在 WWDC 2021 上展示了典型的苹果 coredata/cloudkit 风格的文档(它仍然使用 AppDelegate),也已经过时了,而且似乎不起作用。

以上是关于在 SwiftUI 中使用 NSPersistentCloudKitContainer 实现共享的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SwiftUI 在 UICollectionViewCell 中填充内容

在 SwiftUI 中使用 UIControl 组件

在 SwiftUI 1 中使用 LazyVStack

如何在 UIkit 中添加 SwiftUI 对象

如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?

如何在 swiftUI 视图中使用按钮? [关闭]