【问题标题】:How to automatically reflect CoreData+iCloud Changes in SwiftUI view?如何在 SwiftUI 视图中自动反映 CoreData+iCloud 的变化?
【发布时间】:2020-06-17 08:13:16
【问题描述】:

???? 所以...我有一个启用了 StoreData 和 iCloud 的应用程序。我的数据正在设备之间同步,但在反映 UI 中的更改时,我没有得到我想要的行为。

我想要的行为:当用户在两台设备(A 和 B)上打开我的应用并进行更改其中一台 (A) 时,我希望更改自动反映在第二个 (B) 设备 UI 在合理的时间内。

我目前的行为:当用户在一台设备上进行更改 (A) 时,另一台 (B) 上什么都没有发生...直到我在第二台设备上最小化和最大化应用程序(B)(不重新启动...只是最小化)。

????我的想法是,在最小化和重新打开应用程序时触发某些操作之前,应用程序不会收到更改(iCloud 不会同步)。

????但我不知道。根据Syncing a Core Data Store with CloudKit,同步和通知其他设备应该会自动发生。而且我认为我的视图应该正确连接,因为当对 CoreData 数据库中的数据进行本地更改时,它会立即更改。

我的 SwiftUI 视图大致如下所示:

import SwiftUI
import CloudKit
import Foundation

struct MyView: View {
    @FetchRequest(fetchRequest: Entity.fetchRequest() as! NSFetchRequest<Entity>) var entities: FetchedResults<Entity>

    var body: some View {
        List {
            ForEach(entities, id: \.id) { e in
                Text("\(e.title)")
            }
        }
    }
}

public class Entity: NSManagedObject {
    @NSManaged public var id: UUID?
    @NSManaged public var title: String
}

非常感谢任何帮助! (如果我需要提供更多信息,请告诉我。)

【问题讨论】:

  • @AlbertoLunardini 很遗憾我已经有了“context.automaticallyMergesChangesFromParent = true”,它没有任何区别。
  • 您是否有机会使用模拟器和真实设备进行测试?我发现当你在真机上进行更改时,模拟器不会更新,但是当你在模拟器上进行更改时,真机会更新(XCode 11.4)。
  • @Charles 我使用的是 iPhoneX 和 iPad Pro。两者都运行 13.4
  • 我明白了。你也试过try? context.setQueryGenerationFrom(.current)。每次访问上下文,而不是一次?

标签: swift core-data swiftui icloud nsfetchrequest


【解决方案1】:
// MARK: - Core Data stack

lazy var persistentContainer: NSPersistentCloudKitContainer = {

    let container = NSPersistentCloudKitContainer(name: "ComCloudSync")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

尝试添加以下代码(将“ComCloudSync”更改为您的 appName):

// MARK: - Core Data stack

lazy var persistentContainer: NSPersistentCloudKitContainer = {

    let container = NSPersistentCloudKitContainer(name: "ComCloudSync")
    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 = NSMergeByPropertyStoreTrumpMergePolicy

  return container
}()

【讨论】:

  • 感谢帮助!但是为什么它只指向私有数据库?我在 Presistence.swift 文件中尝试了storeDescription.cloudKitContainerOptions?.databaseScope = .public,但这没有用
猜你喜欢
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
  • 2013-10-26
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多