1

我已成功将CKShareURL 保存到 CloudKit,并且可以看到用户INVITED在 CloudKit 仪表板中。我的 Mac 应用程序通过电子邮件将 URL 发送给那个人,但是当他们单击它时,他们在 icloud.com 上的这个屏幕上看到的都是:

共享

单击“确定”会使所有内容消失,因此您所看到的只是网页上的背景。

我的理解是 URL 应该打开我的 Mac 应用程序,它将userDidAcceptCloudKitShareWith在我的应用程序委托中触发。但它什么也没做。

这可能是因为我的应用程序正在开发中,而不是在 Mac App Store 中吗?我是否需要自定义 URL 方案才能打开我的应用程序?

关于这些东西的文档非常稀少。我希望有人可以提供任何帮助。

4

1 回答 1

4

从那以后,我了解到您必须为 CloudKit 容器指定一个备用 URL。在未安装应用程序的情况下(或无法识别,这似乎是像我一样在 Xcode 中进行开发构建时的情况),CloudKit 会将共享 URL 转发到您指定的位置。他们将唯一的共享 ID 附加到 URL,以便您可以在自己的网页上处理它。

在 CloudKit 仪表板中,转到Environment Settings...,您将看到以下弹出窗口:

开发环境设置

我让它重定向到它重定向到https://myapp.com/share/?id=的我的网页上,我做了一个$_GET['id']来抓取id. 然后,我使用自定义 URL 方案再次重定向到我的应用程序并传递共享 ID(例如myapp://abc123abc123共享 ID 在哪里)。

在我的应用程序委托中,我收到如下 URL:

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

然后我CKFetchShareMetadataOperation用来查找共享的 URL 并CKAcceptSharesOperation像这样接受它:

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)
}

NSItemProvider我认为使用and有更简单的方法来解决这个问题NSSharingService,但我正在做很多自定义 UI,并希望完全控制共享工作流程。

我希望这可以帮助别人。:)

于 2018-06-20T17:57:04.933 回答