func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {...}
does not get called after clicking "OK" on the link to a shared cloudkit record. The app will open, but this function (which is supposed to be called) is not.
func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
print("you accepted something")
let acceptShareOperation: CKAcceptSharesOperation = CKAcceptSharesOperation(shareMetadatas:[cloudKitShareMetadata])
//acceptShareOperation.qualityOfService = .userInteractive
acceptShareOperation.perShareCompletionBlock = {meta, share,
error in
print("share was accepted")
}
acceptShareOperation.acceptSharesCompletionBlock = {
error in
/// Send your user to where they need to go in your app
print("share accepted completion block!")
}
CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptShareOperation)
}
Expected result: AT LEAST seeing the line "you accepted something" printed to the console.
UPDATE: Reverting back to IOS11.3 doesn't make it work.
UPDATE: I downloaded a tutorial someone had built that uses cloudkit and (after some finagling, got theirs to work. I then gutted their code and put mine in instead, and NOW the function works properly, so I think the issue may have something to do with either:
If you use fresh Xcode 11 project, there is SceneDelegate.swift
.
You need to implement there:
internal func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) { }
If you want to get userDidAcceptCloudKitShareWith
called inside AppDelegate.swift
you have to remove from Info.plist
file next lines:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
UPDATED
If you are trying to accept share on cold start using Scene Manifest, CKShare.Metadata
will be passed to func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
in connectionOptions
.
To make this work you have to use SceneDelegate.
There are 3 steps to get scenedelegate working.
1 - Add Appdelegate
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("abc")
return true
}
}
Don't forget to use a delegate adaptor if you use SwiftUI way of entering the program.
struct ExampleApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
MainView()
}
}
Also don't forget to add this to your appdelegate class:
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
if options.userActivities.first?.activityType == "newWindow" {
let configuration = UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
configuration.delegateClass = SceneDelegate.self
return configuration
} else {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
}
2 - Configure info.plist to handle scenes through a SceneDelegate
add these to your info.plist
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
3 - Now add SceneDelegate and get the delegate callbacks that you need
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
print("abcd")
}
}
}
note: in info.plist and in your appdelegate code there is a reference to "default configuration". You can change this to whatever you want (it's meant to enable management of more than one scene), but they should be the same off course.
After 2 days of trial and error I got it working.
The issue seems to be related to Apples new Core Data + Cloudkit syncing abilities. They seem to gloss over the appdelegate function I need to call.
I fixed the issue by rebuilding the app in Xcode 10, then opening it in XCode 11 without changing anything. I'll let Apple know too.
Thank me. I'm welcome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With