我正在开发一个共享应用程序,但在共享邀请方面遇到了问题。我在 iOS 16 上使用 Swift UI。我遇到了两个示例项目,它们运行良好,除了共享邀请在两者上以相同的方式失败。在这两种情况下,数据都存储在云中,并且正确生成了共享链接。但是,除非收件人的应用程序已经启动,否则不会识别或保存链接中的数据。如果收件人的应用程序在单击链接之前未启动,则只会启动该应用程序。收件人必须返回链接,然后再次单击才能获得共享。似乎归结为场景delegate func windowScene。除非应用程序已经启动,否则不会调用它。我的问题是有人知道解决方法吗?谁能同意这是 Apple 可能正在处理的错误?它只与iOS 16有关吗?我假设这些示例在早期版本中有效?参考示例链接在下面带有委托片段。
示例1:https://github.com/apple/sample-cloudkit-sharing.
示例2:https://www.kodeco.com/29934862-sharing-core-data-with-cloudkit-in-swiftui
// Example 1
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
}
import UIKit
import SwiftUI
import CloudKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView().environmentObject(ViewModel())
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
guard cloudKitShareMetadata.containerIdentifier == Config.containerIdentifier else {
print("Shared container identifier \(cloudKitShareMetadata.containerIdentifier) did not match known identifier.")
return
}
// Create an operation to accept the share, running in the app's CKContainer.
let container = CKContainer(identifier: Config.containerIdentifier)
let operation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata])
debugPrint("Accepting CloudKit Share with metadata: \(cloudKitShareMetadata)")
operation.perShareResultBlock = { metadata, result in
let rootRecordID = metadata.rootRecordID
switch result {
case .failure(let error):
debugPrint("Error accepting share with root record ID: \(rootRecordID), \(error)")
case .success:
debugPrint("Accepted CloudKit share for root record ID: \(rootRecordID)")
}
}
operation.acceptSharesResultBlock = { result in
if case .failure(let error) = result {
debugPrint("Error accepting CloudKit Share: \(error)")
}
}
operation.qualityOfService = .utility
container.add(operation)
}
}
// Example 2
import CloudKit
import SwiftUI
final class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = SceneDelegate.self
return sceneConfig
}
}
final class SceneDelegate: NSObject, UIWindowSceneDelegate {
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
let shareStore = CoreDataStack.shared.sharedPersistentStore
let persistentContainer = CoreDataStack.shared.persistentContainer
persistentContainer.acceptShareInvitations(from: [cloudKitShareMetadata], into: shareStore) { _, error in
if let error = error {
print("acceptShareInvitation error :\(error)")
}
}
}
}