【问题标题】:Allow ComplicationController to access CoreData SwiftUI允许 ComplicationController 访问 CoreData SwiftUI
【发布时间】:2020-11-12 01:52:53
【问题描述】:

在使用 SwiftUI 的 Xcode 12 beta 2 中,我希望我的 ComplicationController 发出 FetchRequest 以更新我的并发症,但我无法将持久存储注入环境。

我应该注意到这是 watchOS 中的纯 SwiftUI 应用程序,其中应用程序入口点是 @main 结构。没有 ExtensionDelegate 或 HostingController。

对于 watchOS 应用程序本身,这是我设置 PersistentContainer 的方式:

struct RunPlanner: App {
    @Environment(\.scenePhase) private var scenePhase
    @StateObject private var persistentStore = PersistentStore.shared
    @ObservedObject var selection = TabSelection()
    
    var body: some Scene {
        WindowGroup {
            TabView(selection: $selection.currentTab) {
                WatchAddRunView(tabSelection: selection)
                    .tag(0)
                ContentView()
                    .tag(1)
            }
            .environment(\.managedObjectContext, persistentStore.context)
            .animation(.easeIn)
        }
        .onChange(of: scenePhase) { phase in
            switch phase {
                case .active:
                    print("\(#function) REPORTS - App change of scenePhase to ACTIVE")
                case .inactive:
                    print("\(#function) REPORTS - App change of scenePhase to INACTIVE")
                case .background:
                    print("\(#function) REPORTS - App change of scenePhase to BACKGROUND")
                    savePersistentStore()
                default:
                     print("\(#function) REPORTS - App change of scenePhase Default")
            }
        }
    }
    
    func savePersistentStore() {
        persistentStore.saveContext()
    }
}

这适用于应用程序本身将值保存到 CoreData 但是我的 ComplicationController 没有看到 NSPersistentStoreContainer 并且我不确定如何注入它。

我目前在 ComplicationController 类中的尝试是这样的:

class ComplicationController: NSObject, CLKComplicationDataSource {
    @Environment(\.managedObjectContext) var moc

    let request = NSFetchRequest<RunEvents>(entityName: "RunEvents")
        ....complication code...
}

func getSavedRunName() -> String {
        var activeName = "Run Roster"
            do {
            let savedRuns = try moc.fetch(request)
            savedRuns.forEach({
                if $0.isActive {
                    guard let fetchedName = $0.name else { return }
                    activeName = fetchedName
                }
            })
        } catch {
            print("Error in Fetch Request")
        }
        
        return activeName
    }

但是 getSavedRunName 方法会导致应用程序在执行时崩溃,调试器会说“原因:'+entityForName: nil 不是用于搜索实体名称'RunEvents''的合法 NSPersistentStoreCoordinator”

我已经搜索并摸索了各种解决方案,但没有得到积极的结果。非常感谢这里的任何见解。

-丹

【问题讨论】:

  • 你找到解决办法了吗?
  • 我没有。不幸的是,我在从新创建的 iOS14 Widget 扩展访问 Core Data 时遇到了类似的问题。
  • 我遇到了同样的两个问题,如果找到解决办法我会在这里写出来
  • 我能够让 CoreData 访问为小部件工作。启用 App Groups 和此方法的组合:developer.apple.com/forums/thread/651648 如果您仍在使用 CoreData 和 Widget 工具包,请告诉我,我可以提供帮助。不过,我仍在研究并发症。
  • 我已经用同样的方法做到了这一点。我真的不知道我做了什么不同的事情,所以也许你可以看看我的项目并找出答案。这是一个非常简单的项目。 github.com/Mofawaw/1-Decision

标签: core-data swiftui watchos apple-watch-complication


【解决方案1】:

CLKComplicationDataSource 是一个独立于 WKExtensionDelegate 的独立可执行文件,因此您需要在每个文件中设置您的 CoreData 堆栈。此外,您使用 App Group 来共享相同的 Core Data 文件。我在所有目标中都使用了这样的扩展。

extension NSPersistentContainer {

    static func appContainer() -> NSPersistentContainer {
        let container = NSPersistentContainer(name: AppConstants.databaseName)
        
        let storeURL = URL.storeURL(for: AppConstants.appGroupName, databaseName: AppConstants.databaseName)
        let storeDescription = NSPersistentStoreDescription(url: storeURL)
        container.persistentStoreDescriptions = [storeDescription]
        
        container.loadPersistentStores { storeDescription, error in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }
    
}

请注意,将扩展中所做的更改同步回应用程序的上下文中需要额外的工作待定。我的并发症(和小部件)是只读的,操作系统按需运行它们,因此它们初始化为最新的。

跨设备同步时,我使用CloudCore

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2011-07-28
    • 2017-05-22
    • 2020-05-03
    • 2022-06-25
    相关资源
    最近更新 更多