You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的watchOS应用无法读取iOS Core Data应用中的数据?

watchOS 应用使用 NSPersistentCloudKitContainer 无法读取 Core Data 数据

我跟着Hacking with Swift教程开发了一款支持iPhone、iPad和Mac端数据同步的应用,用Core Data + CloudKit实现同步。现在想把这套方案适配到带watchOS配套应用的项目里,用了NSPersistentCloudKitContainer。

已经把iOS和watchOS应用加入同一个App Group,也通过正确的App Group标识符加载了共享容器(小组件能正常读取数据),但watchOS应用始终读不到数据,不会崩溃,只是返回空的实体数组。

想问watchOS是否不支持这种方法?还是我漏了关键步骤?

以下是我的DataController类代码:

import CoreData
import SwiftUI

class DataController: ObservableObject {
let container: NSPersistentCloudKitContainer
private var saveTask: Task<Void, Error>?

static var preview: DataController = {
    let dataController = DataController(inMemory: true)
    return dataController
}()

private var sharedStoreURL: URL {
    let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.MyCo.MyApp1")!
    return container.appendingPathComponent("Model.sqlite")
}



static let model: NSManagedObjectModel = {
    guard let url = Bundle.main.url(forResource: "Model", withExtension: "momd") else {
        fatalError("Failed to locate model file.")
    }

    guard let managedObjectModel = NSManagedObjectModel(contentsOf: url) else {
        fatalError("Failed to load model file.")
    }

    return managedObjectModel
}()


init(inMemory: Bool = false) {
    container = NSPersistentCloudKitContainer(name: "Model", managedObjectModel: Self.model)
    
    if inMemory {
        container.persistentStoreDescriptions.first?.url = URL(filePath: "/dev/null")
    } else {
        container.persistentStoreDescriptions.first?.url = sharedStoreURL
    }
    
    container.viewContext.automaticallyMergesChangesFromParent = true
    container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
    
    container.persistentStoreDescriptions.first?.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
    NotificationCenter.default.addObserver(forName: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator, queue: .main, using: remoteStoreChanged)
    
    container.loadPersistentStores { _, error in
        if let error {
            fatalError("Fatal error loading store: \(error.localizedDescription)")
        }
        
    }
}



func remoteStoreChanged(_ notification: Notification) {
    objectWillChange.send()
}


func save() {
    saveTask?.cancel()
    
    if container.viewContext.hasChanges {
        try? container.viewContext.save()
    }
}


func queueSave() {
    saveTask?.cancel()
    
    saveTask = Task { @MainActor in
        try await Task.sleep(for: .seconds(3))
        save()
    }
}


func delete(_ object: NSManagedObject) {
    objectWillChange.send()
    container.viewContext.delete(object)
    save()
}



private func delete(_ fetchRequest: NSFetchRequest<NSFetchRequestResult>) {
    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    batchDeleteRequest.resultType = .resultTypeObjectIDs
    
    if let delete = try? container.viewContext.execute(batchDeleteRequest) as? NSBatchDeleteResult {
        let changes = [NSDeletedObjectsKey: delete.result as? [NSManagedObjectID] ?? []]
        NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [container.viewContext])
    }
}


func getMyEntities() throws -> [MyEntity] {
    let request: NSFetchRequest<MyEntity> = MyEntity.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(keyPath: \MyEntity.name, ascending: true)]
   
    let entities = try container.viewContext.fetch(request)
   
    return entities
}

解决方案(补充编辑)

问题出在遗漏了两项关键的功能权限配置,需要给iOS和watchOS应用目标都添加:

  • 添加iCloud功能:选择CloudKit服务,并创建一个iOS与watchOS共享的容器;
  • 添加Background Modes功能:iOS需勾选Background fetch模式,iOS和watchOS都要勾选Remote notifications模式。

内容的提问来源于stack exchange,提问作者Legion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:50:40