Reputation: 109
I developed an app using CoreData and CloudKit. It gives some warning message in the console but works with no problem. However Apple rejected due to crash which I could not replicate. Really appreciate if you could advise how to address the issue.I implemented CoreData and CloudKit based on this material:
This is crash log from Apple:
In the splash screen CoreDataStack file is called:
struct SplashView: View {
@EnvironmentObject var iconSettings: IconNames
let persistenceController = CoreDataStack.shared
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@AppStorage("isOnboarding") var isOnboarding: Bool = true
@StateObject private var modelData = ExLibrisModelData()
@State var isActive: Bool = false
var body: some View {
ZStack {
if self.isActive {
ContentView()
.environmentObject(modelData)
.environmentObject(IconNames())
.environment(\.managedObjectContext, CoreDataStack.shared.context)
.environment(\.urlImageOptions, URLImageOptions(
maxPixelSize: CGSize(width: 600.0, height: 600.
And here is my CoreDataStack file where I get the crash according to the report.
final class CoreDataStack: ObservableObject {
static let shared = CoreDataStack()
var context: NSManagedObjectContext {
persistentContainer.viewContext
}
static let appGroupName = "group.com.Bookshelf"
static let containerURL: URL = {
FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: CoreDataStack.appGroupName)!
}()
var ckContainer: CKContainer {
let storeDescription = persistentContainer.persistentStoreDescriptions.first
guard let identifier = storeDescription?.cloudKitContainerOptions?.containerIdentifier else {
fatalError("Unable to get container identifier")
}
return CKContainer(identifier: identifier)
}
var privatePersistentStore: NSPersistentStore {
guard let privateStore = _privatePersistentStore else {
fatalError("Private store is not set")
}
return privateStore
}
var sharedPersistentStore: NSPersistentStore {
guard let sharedStore = _sharedPersistentStore else {
fatalError("Shared store is not set")
}
return sharedStore
}
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "Bookshelf")
guard let privateStoreDescription = container.persistentStoreDescriptions.first else {
fatalError("Unable to get persistentStoreDescription")
}
let storesURL = privateStoreDescription.url?.deletingLastPathComponent()
privateStoreDescription.url = storesURL?.appendingPathComponent("private.sqlite")
let sharedStoreURL = storesURL?.appendingPathComponent("shared.sqlite")
guard let sharedStoreDescription = privateStoreDescription.copy() as? NSPersistentStoreDescription else {
fatalError("Copying the private store description returned an unexpected value.")
}
sharedStoreDescription.url = sharedStoreURL
guard let containerIdentifier = privateStoreDescription.cloudKitContainerOptions?.containerIdentifier else {
fatalError("Unable to get containerIdentifier")
}
let sharedStoreOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
sharedStoreOptions.databaseScope = .shared
sharedStoreDescription.cloudKitContainerOptions = sharedStoreOptions
container.persistentStoreDescriptions.append(sharedStoreDescription)
container.loadPersistentStores { loadedStoreDescription, error in
if let error = error as NSError? {
fatalError("Failed to load persistent stores: \(error)")
} else if let cloudKitContainerOptions = loadedStoreDescription.cloudKitContainerOptions {
guard let loadedStoreDescriptionURL = loadedStoreDescription.url else {
return
}
if cloudKitContainerOptions.databaseScope == .private {
let privateStore = container.persistentStoreCoordinator.persistentStore(for: loadedStoreDescriptionURL)
self._privatePersistentStore = privateStore
} else if cloudKitContainerOptions.databaseScope == .shared {
let sharedStore = container.persistentStoreCoordinator.persistentStore(for: loadedStoreDescriptionURL)
self._sharedPersistentStore = sharedStore
}
}
}
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
do {
try container.viewContext.setQueryGenerationFrom(.current)
} catch {
fatalError("Failed to pin viewContext to the current generation: \(error)")
}
return container
}()
private var _privatePersistentStore: NSPersistentStore?
private var _sharedPersistentStore: NSPersistentStore?
private init() {}
}
The console warnings are below. I have several of those:
CoreData: warning: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1093): <NSCloudKitMirroringDelegate: 0x282340540>: Successfully set up CloudKit integration for store (0811C705-3EB2-4C73-BC5B-B96B43E4F2E0): <NSSQLCore: 0x106c15b40> (URL: file:///var/mobile/Containers/Data/Application/CAA6F402-F5D0-496E-8E32-01299A0B7C7E/Library/Application%20Support/private.sqlite)
CoreData: warning: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1093): <NSCloudKitMirroringDelegate: 0x2823407e0>: Successfully set up CloudKit integration for store (1F2E3F9B-9DD9-4D61-9DB9-ADD2A3DE9D8D): <NSSQLCore: 0x106c087d0> (URL: file:///var/mobile/Containers/Data/Application/CAA6F402-F5D0-496E-8E32-01299A0B7C7E/Library/Application%20Support/shared.sqlite)
CoreData: warning: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _enqueueRequest:]_block_invoke_2(990): Failed to enqueue request: <NSCloudKitMirroringExportRequest: 0x28397cdc0> 709BC9FC-3172-4F7C-9878-A5E3412E8425
CoreData: warning: CoreData+CloudKit: -NSCloudKitMirroringDelegate finishedAutomatedRequestWithResult:: Finished request '<NSCloudKitMirroringExportRequest: 0x28397cdc0> 709BC9FC-3172-4F7C-9878-A5E3412E8425' with result: <NSCloudKitMirroringResult: 0x2814eb090> storeIdentifier: 0811C705-3EB2-4C73-BC5B-B96B43E4F2E0 success: 0 madeChanges: 0 error: Error Domain=NSCocoaErrorDomain Code=134417 "Request '<NSCloudKitMirroringExportRequest: 0x28397cdc0> 709BC9FC-3172-4F7C-9878-A5E3412E8425' was cancelled because there is already a pending request of type 'NSCloudKitMirroringExportRequest'." UserInfo={NSLocalizedFailureReason=Request '<NSCloudKitMirroringExportRequest: 0x28397cdc0> 709BC9FC-3172-4F7C-9878-A5E3412E8425' was cancelled because there is already a pending request of type 'NSCloudKitMirroringExportRequest'.}
Upvotes: 0
Views: 260
Reputation: 30811
It's probably caused by the lazy var persistentContainer
. Or it's caused by let persistenceController = CoreDataStack.shared
and .environment(\.managedObjectContext, CoreDataStack.shared.context)
where as it should be .environment(\.managedObjectContext, persistenceController.viewContext)
But try changing CoreDataStack
to a struct to match what is in Xcode's template since that is the tried and tested way to integrate Core Data with SwiftUI and using Combine's ObservableObject class is non-standard.
You'll also need to fix this:
.environmentObject(IconNames())
You can't init objects in body like that.
Upvotes: -1