CloudKit CKShare userDidAcceptCloudKitShareWith Never Macs App

时间:2018-06-12 23:44:30

标签: cloudkit ckshare cloudkit-sharing

我正在接受Swift 4中macOS应用程序中的CKShare。我已经完成了以下所有操作:

  • 创建CKShare并将其rootRecord保存到CloudKit
  • 添加参与者(CKShare.Participant
  • 我已确认CKShare位于CloudKit服务器上,并且我邀请的人可以访问它。这是一个屏幕截图:https://d.pr/i/0sMFQq

当我点击与CKShare相关联的共享链接时,它会打开我的应用,但没有任何反应,userDidAcceptCloudKitShareWith无法触发。

func application(_ application: NSApplication, userDidAcceptCloudKitShareWith metadata: CKShareMetadata) {
  print("Made it!") //<-- This never gets logged :(
  let shareOperation = CKAcceptSharesOperation(shareMetadatas: [metadata])
  shareOperation.qualityOfService = .userInteractive

  shareOperation.perShareCompletionBlock = {meta, share, error in
    print("meta \(meta)\nshare \(share)\nerror \(error)")
  }
  shareOperation.acceptSharesCompletionBlock = { error in
    if let error = error{
      print("error in accept share completion \(error)")
    }else{
      //Send your user to where they need to go in your app
      print("successful share:\n\(metadata)")
    }
  }

  CKContainer.default().add(shareOperation)
}

我的info.plist中是否包含某种URL方案?或者我需要在NSApplicationDelegate代表中遵守协议?我无法为我的生活找出要做的事情。提前谢谢!

更新

我已经尝试了一些更多的事情。当我在网络浏览器中打开共享链接时,我看到了:

enter image description here

点击确定会使屏幕渐渐消失:

Nothing

不是特别有帮助。 :)完成此操作后,参与者在CloudKit中的状态仍然是邀请,因此共享仍未被接受。

当我点击消息中的共享链接时,我会看到一个如下弹出窗口: CloudKit Sharing Popup 点击打开后,我的应用程序的新副本显示在停靠栏中,然后应用程序突然关闭。崩溃日志指出:

  

由于未捕获的异常终止应用程序&#39; CKException&#39;,原因:&#39;应用程序缺少必需的权利com.apple.developer.icloud-services&#39;

我已尝试在Xcode的功能部分关闭iCloud,但没有任何变化。我知道这个例外是对的,因为我可以正常启动我的应用并整天使用CloudKit。只有CKShare导致此崩溃。

这是一团糟。救救我,欧比旺克诺比,你是我唯一的希望。

4 个答案:

答案 0 :(得分:2)

是,

您需要将其添加到info.plist。

<key>CKSharingSupported</key>
<true/>

**编辑答案**

我使用此代码进行共享,我不手动执行...不确定这是否是OS X下的选项我必须承认。我正在使用iOS。

let share = CKShare(rootRecord: record2S!)
share[CKShareTitleKey] = "My Next Share" as CKRecordValue
share.publicPermission = .none

let sharingController = UICloudSharingController(preparationHandler: {(UICloudSharingController, handler:
                    @escaping (CKShare?, CKContainer?, Error?) -> Void) in
let modifyOp = CKModifyRecordsOperation(recordsToSave:
                        [record2S!, share], recordIDsToDelete: nil)
modifyOp.savePolicy = .allKeys
modifyOp.modifyRecordsCompletionBlock = { (record, recordID,
                        error) in
                        handler(share, CKContainer.default(), error)
                    }
                    CKContainer.default().privateCloudDatabase.add(modifyOp)
                })
sharingController.availablePermissions = [.allowReadWrite,
                                                          .allowPrivate]
sharingController.delegate = self
                sharingController.popoverPresentationController?.sourceView = self.view
            DispatchQueue.main.async {
                self.present(sharingController, animated:true, completion:nil)
            }

这会显示一个活动控制器,您可以在其中选择说出电子邮件然后发送链接。您可能还想观看此视频,一开始就专注于cloudKit JS。

观看此WWDC视频https://developer.apple.com/videos/play/wwdc2015/710/ 它讨论了cloudkit JSON API,使用它可以查询终端窗口/简单脚本中的内容和内容。几年前我在使用Dropbox API时做了同样的事情。嘿,您甚至可以在代码中使用cloudkit JSON API代替本机调用。

答案 1 :(得分:1)

如果您的应用程序是Mac Catalyst应用程序,且其至少在包括10.15.4 Beta 1(包括10.15.4 Beta 1)的任何版本的macOS Catalina上运行,则将永远不会调用UIApplicationDelegate userDidAcceptCloudKitShareWith方法。

经过大量的调试之后,我们发现MacCatalyst UIKit甚至在其UIApplication委托中都没有实现userDidAcceptCloudKitShareWithMetadata的实现。它没有坏,只是不在那里。因此,至少暂时来说,我们的解决方法如下,即使它非常优雅,它也似乎可以正常工作:

// Add CloudKit sharing acceptance handling to UINSApplicationDelegate, which is missing it.
#if targetEnvironment(macCatalyst)
extension NSObject {
    @objc func application(_ application: NSObject, userDidAcceptCloudKitShareWithMetadata cloudKitShareMetadata: CKShare.Metadata) {
        YourClass.acceptCloudKitShare(cloudKitShareMetadata: cloudKitShareMetadata)
    }
}
#endif

答案 2 :(得分:0)

我终于开始工作了!我做了以下所有事情:

  1. ~/Library/Developer/Excode/DerivedData
  2. 删除了我的应用
  3. 确保我的计算机上没有任何其他应用程序副本存档。
  4. 说祷告。
  5. 后重新启动。
  6. Sheesh,那很粗糙。 :)

答案 3 :(得分:0)

如果您使用的是SceneDelegate,请在此处而不是在AppDelegate上实现委托回调。

func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
    // ...
}