App Groups forSecurityApplicationGroupIdentifier returns nil

夙愿已清 提交于 2020-05-26 10:11:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!