问题
I set up an App Group to use with my Today Extension. I added the app group in the main app's target and in the extension's target. In my App ID Configuration in the developer portal I have the app group enabled. But for some reason FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: id)
returns nil whenever I call it. I have tripled checked the forSecurityApplicationGroupIdentifier
string and know it's correct.
Does anyone have any idea why this is not working?
EDIT: I was able to fix the nil issue by editing my entitlements for debug to include the app group. I have been following this post and was able to successfully migrate my data from my NSPersistentContainer, but this same method does not work when I try to use an NSPersistentCloudKitContainer for when the user has toggled iCloud on. It's able to still migrate the data, but does not let me sync my data between devices (pretty much just makes it become a regular NSPersistentContainer). If I revert back to the old way of how I was doing this I am able to use iCloud sync.
Can anyone help me fix this syncing issue when migrating with a NSPersistentCloudKitContainer
to use the app group?
Core Data code:
class CoreDataManager {
static let sharedManager = CoreDataManager()
private init() {}
lazy var persistentContainer: NSPersistentContainer = {
var useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
//Get the correct container
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "App")
} else {
containerToUse = NSPersistentContainer(name: "App")
}
guard let container = containerToUse else {
fatalError("Couldn't get a container")
}
//Set the storeDescription
let storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.App")!.appendingPathComponent("\(container.name).sqlite")
var defaultURL: URL?
if let storeDescription = container.persistentStoreDescriptions.first, let url = storeDescription.url {
defaultURL = FileManager.default.fileExists(atPath: url.path) ? url : nil
}
if defaultURL == nil {
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeURL)]
}
let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
if !useCloudSync {
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
//migrate from old url to use app groups
if let url = defaultURL, url.absoluteString != storeURL.absoluteString {
let coordinator = container.persistentStoreCoordinator
if let oldStore = coordinator.persistentStore(for: url) {
do {
try coordinator.migratePersistentStore(oldStore, to: storeURL, options: nil, withType: NSSQLiteStoreType)
} catch {
print("Hey Listen! Error migrating persistent store")
print(error.localizedDescription)
}
// delete old store
let fileCoordinator = NSFileCoordinator(filePresenter: nil)
fileCoordinator.coordinate(writingItemAt: url, options: .forDeleting, error: nil, byAccessor: { url in
do {
try FileManager.default.removeItem(at: url)
} catch {
print("Hey Listen! Error deleting old persistent store")
print(error.localizedDescription)
}
})
}
}
}
return container
}
}
I assumed the issue was with the store descriptions, but when I look at the storeDescription before and after changing it, its options still have iCloud sync on.
回答1:
I had the same issue in the past. To fix FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: id)
being nil, just make sure that the entitlements that are being used for the debug (You can find this in your target's Build Settings) has the app group you made. Sometimes it's not added.
来源:https://stackoverflow.com/questions/61845865/app-groups-forsecurityapplicationgroupidentifier-returns-nil