SwiftUI:在 macOS 上共享 NSSharingService 未收到共享

SwiftUI: Sharing NSSharingService on macOS not receiving share

我有一个简单的测试应用程序,它尝试使用 NSSharingService 与另一个用户共享 CoreData 记录。我可以创建我的共享并且有效,

但是当我尝试接收共享时,它打开了应用程序但没有执行任何操作。

我已将 CKSharingSupported 添加到我的 plist。

我也跟着这个 link 无济于事: CloudKit CKShare userDidAcceptCloudKitShareWith Never Fires on Mac App

这是我的代码:

共享服务应用程序:

final class AppDelegate: NSObject, NSApplicationDelegate
{
    func application(_ application: NSApplication, userDidAcceptCloudKitShareWith metadata: CKShare.Metadata)
    {
        print ("userDidAcceptCloudKitShareWith")
        let shareStore = persistenceController.sharedPersistentStore!
        persistenceController.container.acceptShareInvitations(from: [metadata], into: shareStore)
        { _, error in
            if let error = error
            {
                print("acceptShareInvitation error :\(error)")
            }
        }
    }
}

内容视图:

import SwiftUI
import CoreData
import CloudKit

let persistenceController = PersistenceController()

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    NavigationLink {
                        VStack
                        {
                            Text("Item at \(item.timestamp!, formatter: itemFormatter)")
                            Button("Share")
                            {
                                shareRecord(item: item)
                            }
                        }
                        
                    } label: {
                        Text(item.timestamp!, formatter: itemFormatter)
                    }
                }
            }
            .toolbar {
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

private let itemFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .medium
    return formatter
}()

func shareRecord(item: Item)
{
    Task
    {
        if let share = await createShare(item: item)
        {
            let container = CKContainer(identifier: "iCloud.com.xxxxxxxx.sharingservice")
            
            let item = NSItemProvider()
            item.registerCloudKitShare(share, container: container)
            
            DispatchQueue.main.async
            {
                let sharingService = NSSharingService(named: .cloudSharing)
                sharingService!.perform(withItems: [item])
            }
        }
    }
}

private func createShare(item: Item) async -> CKShare?
{
    do
    {
        let (_, share, _) = try await persistenceController.container.share([item], to: nil)
        share[CKShare.SystemFieldKey.title] = "MyApp"
        return share
    }
    catch
    {
        print("Failed to create share")
        return nil
    }
}

好的,我终于成功调用了 userDidAcceptCloudKitShareWith。

您需要使用@NSApplicationDelegateAdaptor 为您的 SwiftUI 应用创建应用委托:

@main
struct Sharing_ServiceApp: App
{
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene
    {
        WindowGroup
        {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

我输入该行,我的代码立即开始接收共享请求。