如何创建要在共享表中使用的vCard/vcf文件?

C. *_*ows 9 addressbook abaddressbook ios swift

我是swift的新手,我发现的方法因我的问题而被弃用.我正在构建一个目录应用程序,我从API中提取联系人数据,而不是从手机的地址簿中提取.

在iOS中,如果您转到地址簿,则可以选择联系人并选择"共享联系人",这将显示共享表.我想在我的应用程序中使用这个功能.

我已经找到了Share Sheets,这是我的代码:

    @IBAction func actShare(sender: AnyObject) {

    let activityViewController = UIActivityViewController(activityItems: ["text" as NSString], applicationActivities: nil)
    presentViewController(activityViewController, animated: true, completion: {})
}
Run Code Online (Sandbox Code Playgroud)

我想改成"text" as NSStringvCard,因为这是iOS从地址簿中分享的对象,对吧?假设我是对的,我想从我自己的应用程序的联系对象创建一个vCard,以便将其分享给适当的应用程序(电子邮件,短信等).

我怎样才能在Swift中实现这一目标?如果我错了,请纠正我并告诉我我需要做什么.谢谢.

编辑:好的,这是我的变化.

@IBAction func actShare(sender: AnyObject) {
    do {
        var contactData = NSData()
        try contactData = CNContactVCardSerialization.dataWithContacts([createContact()])

        let activityViewController = UIActivityViewController(activityItems: [contactData as NSData], applicationActivities: nil)
        presentViewController(activityViewController, animated: true, completion: {})
    } catch {
        print("CNContactVCardSerialization cannot save address")
    }
Run Code Online (Sandbox Code Playgroud)

func createContact() -> CNMutableContact {
    let contactCard = CNMutableContact()
    contactCard.givenName = "John"
    contactCard.familyName = "Doe"
    contactCard.emailAddresses = [
        CNLabeledValue(label: CNLabelWork, value: "john.doe@email.com")
    ]

    return contactCard
}
Run Code Online (Sandbox Code Playgroud)

但是,当我单击共享按钮并显示我的共享表时,我选择了要共享的应用程序,并且它不会按预期添加/附加联系人数据.我该如何做到这一点?

Luk*_* In 11

这里的技巧是将联系人保存到VCard(.vcf)文件CNContactVCardSerialization.dataWithContacts,然后将文件URL传递给UIActivityViewController.活动视图控制器从文件扩展名中检测VCard格式,并显示支持该格式的应用程序(例如,消息,邮件,便笺,Airdrop等)

例:

@IBAction func buttonTapped(button: UIButton) {

    let contact = createContact()

    do {
        try shareContacts([contact])
    }
    catch {
        // Handle error
    }
}

func shareContacts(contacts: [CNContact]) throws {

    guard let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask).first else {
        return
    }

    var filename = NSUUID().UUIDString

    // Create a human friendly file name if sharing a single contact.
    if let contact = contacts.first where contacts.count == 1 {

        if let fullname = CNContactFormatter().stringFromContact(contact) {
            filename = fullname.componentsSeparatedByString(" ").joinWithSeparator("")
        }
    }

    let fileURL = directoryURL
        .URLByAppendingPathComponent(filename)
        .URLByAppendingPathExtension("vcf")

    let data = try CNContactVCardSerialization.dataWithContacts(contacts)

    print("filename: \(filename)")
    print("contact: \(String(data: data, encoding: NSUTF8StringEncoding))")

    try data.writeToURL(fileURL, options: [.AtomicWrite])

    let activityViewController = UIActivityViewController(
        activityItems: [fileURL],
        applicationActivities: nil
    )

    presentViewController(activityViewController, animated: true, completion: {})
}

func createContact() -> CNContact {

    // Creating a mutable object to add to the contact
    let contact = CNMutableContact()

    contact.imageData = NSData() // The profile picture as a NSData object

    contact.givenName = "John"
    contact.familyName = "Appleseed"

    let homeEmail = CNLabeledValue(label:CNLabelHome, value:"john@example.com")
    let workEmail = CNLabeledValue(label:CNLabelWork, value:"j.appleseed@icloud.com")
    contact.emailAddresses = [homeEmail, workEmail]

    contact.phoneNumbers = [CNLabeledValue(
        label:CNLabelPhoneNumberiPhone,
        value:CNPhoneNumber(stringValue:"(408) 555-0126"))]

    return contact
}
Run Code Online (Sandbox Code Playgroud)

活动视图控制器显示支持VCard格式的应用程序

VCard联系人出现在消息应用程序中