Search code examples
iosuiactivityviewcontroller

UIActivityViewController contacts sharing?


I'm trying to think about a way to share contact using UIActivityViewController (or using SMS) from one device to another.

So far I've been looking and I've no idea how can I share contacts between devices using my app.

Any ideas?


Solution

  • After searching for months, I have finally discovered the way to achieve this.

    You can use this code to share a single CNContact in a UIActivityViewController:

    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)
    

    This code converts the contact into its NSData representation, saves it to the app's cache folder, and shares the file as an activity item.

    If you want to share multiple contacts, you can pass multiple files in this way.

    Edit: Swift 3.0 version

    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)