2

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:

Shared

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.

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128
  • I see the same thing when I use the link directly; but if you check the dashboard you note your record is shared and if you use the UICloudSharingController and send the link to somebody else; they will be able to access your shared data. I suspect you need to add more to the URL to gain a view of the data shared, maybe documented in the CloudKit JS docs. – user3069232 Jun 20 '18 at 13:28

1 Answers1

5

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:

Development Environment Settings

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. :)

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128
  • Clifton, are CloudKit fallback URLs still working for you? They seem to be recently broken for our app and I'm not having any luck getting help from Apple. Clicking on a shared record URL results in an iCloud.com web page that says "iCloud has stopped responding" which is an error exception in the javascript in the web page. Thanks! – LenK May 15 '20 at 18:28
  • Hmm... I hadn't noticed any problems. Was it a temporary outage or is it still not working? – Clifton Labrum May 18 '20 at 18:22
  • This is still happening and appears to have been happening for weeks. Have you tried any CloudKit URLs from your apps lately? Here's an example URL from our app that works on iOS Safari, but fails on macOS Safari, Chrome, Windows Edge, etc. https://www.icloud.com/share/0bjtbTTaM5b7bG1ff6dnKFbmg#Wizard_Stories – LenK May 18 '20 at 18:48