【问题标题】:userDidAcceptCloudKitShareWith not being calleduserDidAcceptCloudKitShareWith 未被调用
【发布时间】:2019-07-19 00:10:41
【问题描述】:
func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {...}

在共享 cloudkit 记录的链接上单击“确定”后不会调用。应用会打开,但这个函数(应该被调用)没有。

  • CKSharingSupported:YES 列在我的 info.plist 中
  • 我已将记录放入名为“sharedZone”的区域中
  • SharedZone 显示在我的私人数据库中的区域列表中。
  • 共享记录显示我被“邀请”了
  • 尝试删除应用和云数据并重新安装,没有变化
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)
    }

预期结果:至少看到控制台打印出“你接受了某些东西”这一行。

更新:恢复到 IOS11.3 并不能正常工作。

更新:我下载了一个使用 cloudkit 构建的教程,并且(经过一番琢磨之后,让他们的代码开始工作。然后我删除了他们的代码并将我的代码放入其中,现在该功能可以正常工作,所以我认为问题可能与其中任何一个有关:

  • XCODE 11 测试版,或
  • 苹果新增coredata + cloudkit同步功能。

【问题讨论】:

  • "关于共享 cloudkit 记录的链接" 我们在哪里可以找到链接?
  • 当“共享”用户界面出现时(内置苹果),它会在底部显示方法列表:邮件、Whatsapp、消息、复制链接。如果您选择“复制链接”,窗口将变为电子邮件,允许您添加联系人。在右上角,它会说“复制链接”。点击它会将链接放在剪贴板上。然后我打开“消息”并粘贴链接。这是一个类似于“icloud.com/share/2949485r8959494#shareTitle”的 icloud 链接,然后我将其发送到我的其他帐户,然后在我的其他设备上单击该链接。

标签: ios swift cloudkit


【解决方案1】:

如果您使用新的 Xcode 11 项目,则有 SceneDelegate.swift。 你需要在那里实现:

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

如果你想在AppDelegate.swift 中调用userDidAcceptCloudKitShareWith,你必须从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>
                <key>UISceneStoryboardFile</key>
                <string>Main</string>
            </dict>
        </array>
    </dict>
</dict>

更新

如果您尝试使用 Scene Manifest 在冷启动时接受共享,CKShare.Metadata 将被传递到 connectionOptions 中的 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)

【讨论】:

  • 如果您实施选项 1,当您的应用程序冷启动时它不起作用。您也知道解决方案吗? (我需要 UIApplicationSceneManifest 所以我无法删除它)
  • 您是否了解过如何确保在尚未运行的应用程序上调用 CKAcceptSharesOperation? CKAcceptSharesOperation 启动时?
  • 我正在使用 SceneDelegate 并且至少在 MacOS 10.15.3 和 10.15.4 Beta 1 中,我的 willConnectToSession 永远不会被 connectionOptions.cloudKitShareMetadata 调用,并且 userDidAcceptCloudKitShareWith 根本不会被调用。它们都可以在 iOS 上完全按照预期工作。 CKSharingSupported 为真。并且当点击链接时应用程序正确启动/激活,因此 MacOS 清楚地知道哪个应用程序应该处理 CKShare。
  • 你是怎么知道这些东西的?你为我节省了 5 个小时的时间。您能否解释一下在 info.plist 中删除该部分的含义是什么?
  • @erotsppa,最初的问题是:在 AppDelegate 中调用 userDidAcceptCloudKitShareWith。但是,如果项目是在 Scene Manifest 支持下创建的,那么您将永远不会接到那个电话。否则应用程序将在您的场景委托中调用类似的方法。虽然如果你想在 AppDelegate 中调用它,你需要通过编辑 info.plist 来禁用场景清单支持。
【解决方案2】:

要完成这项工作,您必须使用 SceneDelegate。

有 3 个步骤可以让场景委托工作。

1 - 添加 Appdelegate

class AppDelegate: NSObject, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        print("abc")
        return true
    }
}

别忘了使用委托适配器

    struct ExampleApp: App {
        @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    var body: some Scene {
              MainView()
          }
    }

2 - 配置 info.plist 以处理基于场景委托的场景

将这些添加到您的 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 - 添加场景代理。

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            var window: UIWindow?
        
            func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
                print("abcd")
            }
    }

    }

【讨论】:

  • 第 3 部分场景委托代码去哪了?
  • 进入类 SceneDelegate: UIResponder, UIWindowSceneDelegate {} 我更新了示例的第 3 部分。
【解决方案3】:

经过 2 天的反复试验,我得到了它的工作。

这个问题似乎与 Apple 的新 Core Data + Cloudkit 同步功能有关。他们似乎掩盖了我需要调用的 appdelegate 函数。

我通过在 Xcode 10 中重建应用程序解决了这个问题,然后在 XCode 11 中打开它而不进行任何更改。我也会让苹果知道。

谢谢。我不客气。

【讨论】:

  • 听起来您的解决方案与我的相似:stackoverflow.com/questions/50827303/…
  • 我看到了您的帖子,是的,但是由于您使用的是 Mac 应用程序,因此我不确定问题是否相同。我很高兴你不必从头开始重建你的!
猜你喜欢
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 2016-05-21
  • 2012-02-15
  • 2011-11-17
  • 2019-10-22
  • 2016-04-03
相关资源
最近更新 更多