CloudKit CKShare URL Goes Nowhere

你。 提交于 2021-02-08 10:36:23

问题


I have successfully saved a CKShare URL to CloudKit, and I can see that the user is INVITED in the CloudKit Dashboard. My Mac app emailed the URL to that person, but when they click it, all they see it this screen on icloud.com:

Clicking OK makes everything disappear so all you see is the background on the web page.

My understanding is that the URL is supposed to open my Mac app where it will fire userDidAcceptCloudKitShareWith in my app delegate. But it does nothing.

Could this be because my app is in development and not in the Mac App Store yet? Do I need a custom URL scheme to get it to open my app?

Documentation on this stuff is pretty sparse. I'd love any help someone can provide.


回答1:


I have since learned that you must specify a fallback URL for your CloudKit container. In cases where the app isn't installed (or isn't recognized, which seems to be the case when doing dev builds in Xcode like I am), CloudKit will forward share URL to somewhere you specify. They append the unique share ID to the URL so that you can process it on your own web page.

In the CloudKit dashboard, go to Environment Settings... and you'll see this popup:

I have it redirect to https://myapp.com/share/?id= and on my web page where it redirects to, I do a $_GET['id'] to grab the id. I then do another redirect to my application using a custom URL scheme and pass the share ID (e.g. myapp://abc123 where abc123 is the share ID).

In my app delegate, I receive the URL like this:

func application(_ application: NSApplication, open urls: [URL]) {
  if let url = urls.first, let shareId = url.host{
    fetchShare(shareId) //<-- sharedId = abc123
  }
}

I then use CKFetchShareMetadataOperation to look up the URL of the share and CKAcceptSharesOperation to accept it like this:

func fetchShare(shareId: String){
  if let url = URL(string: "https://www.icloud.com/share/\(shareId)"){
    let operation = CKFetchShareMetadataOperation(shareURLs: [url])

    operation.perShareMetadataBlock = { url, metadata, error in
      if let metadata = metadata{
        //:::
        acceptShare(metadata: metadata)
      }
    }
    operation.fetchShareMetadataCompletionBlock = { error in
      if let error = error{
        print("fetch Share error: \(error)")
      }
    }
    CKContainer.default().add(operation)
  }
}

func acceptShare(metadata: CKShareMetadata){
  let operation = CKAcceptSharesOperation(shareMetadatas: [metadata])

  operation.acceptSharesCompletionBlock = { error in
    if let error = error{
      print("accept share error: \(error)")
    }else{
      //Share accepted!
    }
  }
  CKContainer.default().add(operation)
}

I think there are easier ways to work through this using NSItemProvider and NSSharingService, but I'm doing a lot of custom UI and wanted to have full control of the share workflow.

I hope this helps someone. :)



来源:https://stackoverflow.com/questions/50937353/cloudkit-ckshare-url-goes-nowhere

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