UIActivityViewController联系人共享?

时间:2014-11-11 14:48:46

标签: ios uiactivityviewcontroller

我试图考虑使用UIActivityViewController(或使用短信)从一台设备与另一台设备分享联系方式。

到目前为止,我一直在寻找,而且我不知道如何使用我的应用在设备之间共享联系。

有什么想法吗?

4 个答案:

答案 0 :(得分:10)

经过几个月的搜索,我终于找到了实现这一目标的方法。

您可以使用此代码在UIActivityViewController中共享单个CNContact:

let contact: CNContact = /* your contact here */

let fileManager = NSFileManager.defaultManager()
let cacheDirectory = try! fileManager.URLForDirectory(NSSearchPathDirectory.CachesDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: true)

let fileLocation = cacheDirectory.URLByAppendingPathComponent("\(CNContactFormatter().stringFromContact(contact)!).vcf")

let contactData = try! CNContactVCardSerialization.dataWithContacts([contact])
contactData.writeToFile(fileLocation.path!, atomically: true)

let activityVC = UIActivityViewController(activityItems: [fileLocation], applicationActivities: nil)
presentViewController(activityVC, animated: true, completion: nil)

此代码将联系人转换为其NSData表示形式,将其保存到应用程序的缓存文件夹,并将该文件作为活动项共享。

如果您想共享多个联系人,可以通过这种方式传递多个文件。

编辑:Swift 3.0版本

let contact: CNContact = /* your contact here */

let fileManager = FileManager.default
let cacheDirectory = try! fileManager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

let fileLocation = cacheDirectory.appendingPathComponent("\(CNContactFormatter().string(from: contact)!).vcf")

let contactData = try! CNContactVCardSerialization.data(with: [contact])
do {
    try contactData.write(to: fileLocation.asURL(), options: .atomicWrite)
} catch {
    ...
}

let activityVC = UIActivityViewController(activityItems: [fileLocation], applicationActivities: nil)
present(activityVC, animated: true, completion: nil)

答案 1 :(得分:2)

Swift 3.0:

    let cacheDirectory = try! FileManager.default.url(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: true)

    let fileLocation = cacheDirectory.appendingPathComponent("\(CNContactFormatter().string(from: contact)!).vcf")

    let contactData = try! CNContactVCardSerialization.data(with: [contact])
    do {
        _ = try contactData.write(to: fileLocation, options: .atomic)
    } catch let error {
        print(error)
    }

答案 2 :(得分:1)

使用旧的ABAddressBook框架也可以类似的方式轻松实现这一点(制作vCard表示,将其保存到文件,共享URL):

func AB_RecordVcardFileURL(record: ABRecord) -> NSURL? {
    let docsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)

    guard let
        pathStr = docsPath.first as NSString?
        else {return nil}

    let name = ABRecordCopyCompositeName(record).takeRetainedValue() ?? "vcard"
    let filePath = pathStr.stringByAppendingPathComponent("\(name!).vcf")

    let fileUrl = NSURL(fileURLWithPath: filePath)

    let card = ABPersonCreateVCardRepresentationWithPeople([record]).takeRetainedValue() as NSData
    card.writeToURL(fileUrl, atomically: true)

    return fileUrl
}

您只需将URL传递给活动控制器:

guard let
        fileUrl = AB_RecordVcardFileURL(record)
else {return}

let activity = UIActivityViewController(activityItems: [fileUrl], applicationActivities: nil)
presentViewController(activity, animated: true, completion: nil)

答案 3 :(得分:0)

版本:Swift 4.2为了避免当联系人没有名字时崩溃。

let cnContact : CNContact = CNContact()
 let fileManager = FileManager.default
        do {
            let cacheDirectory = try? fileManager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            let fileLocation = cacheDirectory?.appendingPathComponent("\(CNContactFormatter().string(from: cnContact) ?? "Contact")).vcf")
            let contactData = try? CNContactVCardSerialization.data(with: [cnContact])
            try? contactData?.write(to: (fileLocation?.asURL())!, options: .atomicWrite)
            attachedFiles.append(fileLocation!)
        } catch let error {
            logger.info("share contact failed due to :\(error)")
        }

如果您的联系人没有姓名,而当您尝试执行CNContactFormatter()。string(from:cnContact)时,它将崩溃,因为它将返回nil。因此,为避免崩溃,请不要强行使用默认名称。