SwiftUI:如何在macOS上从联系人中拖放联系人



我正试图将联系人从Contacts拖动到我的应用程序中。

这是我更新的代码:

import SwiftUI
import UniformTypeIdentifiers
let uttypes = [UTType.contact, UTType.emailMessage]
struct ContentView: View
{
let dropDelegate = ContactDropDelegate()
var body: some View
{
VStack
{
Text("Drag your contact here!")
.padding(20)
}
.onDrop(of: uttypes, delegate: dropDelegate)
}
}
struct ContactDropDelegate: DropDelegate
{
func validateDrop(info: DropInfo) -> Bool
{
return true
}

func dropEntered(info: DropInfo)
{
print ("Drop Entered")
}

func performDrop(info: DropInfo) -> Bool
{
print ("performDrop")
NSSound(named: "Submarine")?.play()

print (info)
print ("Has UniformTypeIdentifiers:", info.hasItemsConforming(to: uttypes))

let items = info.itemProviders(for: uttypes)
print ("Number of items:",items.count)
print (items)
for item in items
{
print ("item:", item)
item.loadDataRepresentation(forTypeIdentifier: kUTTypeVCard as String, completionHandler: { (data, error) in
if let data = data
{
print ("contact")
}
})
}
return true
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

控制台中的输出如下:

Drop Entered
performDrop
2020-11-07 10:00:37.150359+0000 DropContact[9653:434367] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600003fd9b80> F8BB1C28-BAE8-11D6-9C31-00039315CD46
DropInfo(platformDropInfo: SwiftUI.(unknown context at $7fff423616a8).DropInfo_Mac(location: (85.0618896484375, 22.804290771484375), pasteboard: <NSPasteboard: 0x600001ba6ca0>))
Has UniformTypeIdentifiers: true
Number of items: 1
[<NSItemProvider: 0x6000014a73a0> {types = (
)}]
item: <NSItemProvider: 0x6000014a73a0> {types = (
)}
2020-11-07 10:00:37.427867+0000 DropContact[9653:434367] Cannot find representation conforming to type public.vcard

所以它知道投递中有联系人,但我该如何访问它?当我试图把它弄出来的时候,它似乎是零。

订阅&加载数据类型应该是相同的,所以这里有一个已工作的解决方案的演示。使用Xcode 12.1/macOS 10.15.7 进行测试

let uttypes = [String(kUTTypeVCard), String(kUTTypeEmailMessage)]
struct ContentView: View
{
let dropDelegate = ContactDropDelegate()
var body: some View
{
VStack
{
Text("Drag your contact here!")
.padding(20)
}
.onDrop(of: uttypes, delegate: dropDelegate) // << kUTTypeVCard !!
}
}
import Contacts
struct ContactDropDelegate: DropDelegate
{
func validateDrop(info: DropInfo) -> Bool
{
return true
}

func dropEntered(info: DropInfo)
{
print ("Drop Entered")
}

func performDrop(info: DropInfo) -> Bool
{
print ("performDrop")
NSSound(named: "Submarine")?.play()

print (info)
print ("Has UniformTypeIdentifiers:", info.hasItemsConforming(to: uttypes))

let items = info.itemProviders(for: uttypes)
print ("Number of items:",items.count)
print (items)
for item in items
{
item.loadDataRepresentation(forTypeIdentifier: kUTTypeVCard as String, completionHandler: { (data, error) in
if let data = data, 
let contact = try? CNContactVCardSerialization.contacts(with: data).first
{
print("Contact: (contact.givenName)")
}
})
}
return true
}
}

以下是MacOS 13 Ventura的解决方案:

import SwiftUI
import Contacts
import UniformTypeIdentifiers
struct ContentView: View {
@State private var name = "Drag vcard here"

@State var contacts:[CNContact] = []
var body: some View
{
VStack
{
Image(systemName: "person")
.resizable()
.scaledToFit()
.frame(width:150, height:150)
Text(name)
}
.dropDestination(for: Data.self) { items, location in
for item in items
{
do
{
contacts = try CNContactVCardSerialization.contacts(with: item)
name = (contacts[0].givenName + " " + contacts[0].familyName)
}
catch
{
print("getContactsFromVCard (error)")
}
}
return true
}
}
}

最新更新