2016-07-12 55 views
5

Sono nuovo di swift e i metodi che sto trovando sono deprecati per quanto riguarda il mio problema. Sto creando un'app di directory e sto prelevando i dati dei contatti da un'API, non dalla rubrica del telefono.Come creare un file vCard/vcf da utilizzare nel foglio di condivisione?

In iOS, se si accede alla rubrica, è possibile selezionare un contatto e scegliere "Condividi contatto" che visualizza un foglio di condivisione. Voglio questa esatta funzionalità nella mia app.

ho penso c'ho Share Sheets capito, ed ecco il mio codice per questo:

@IBAction func actShare(sender: AnyObject) { 

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

voglio cambiare "text" as NSString essere una vCard, come quello è l'oggetto che le azioni iOS dalla rubrica, giusto? Supponendo che abbia ragione, voglio creare una vCard dall'oggetto contatto della mia app per condividerla con app appropriate (email, sms, ecc.).

Come posso ottenerlo in Swift? Se sbaglio, per favore correggimi e mostrami cosa devo fare. Grazie.

EDIT: Ok, ecco le mie modifiche.

@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") 
    } 

e

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

    return contactCard 
} 

Tuttavia, quando si fa clic sul pulsante di condivisione e porta il mio foglio di quota, ho selezionare l'applicazione che voglio condividere per e non aggiunge/collegare il contatto dati come previsto. Come posso realizzare questo?

risposta

6

Il trucco è quello di salvare il contatto in un file vCard (.vcf) utilizzando CNContactVCardSerialization.dataWithContacts, quindi passare l'URL del file al UIActivityViewController. Il controller della vista di attività rileva il formato vCard da l'estensione del file, e mostra le applicazioni in cui è supportato il formato (ad esempio Messaggi, Mail, Note, Airdrop, ecc)

Esempio:

@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:"[email protected]") 
    let workEmail = CNLabeledValue(label:CNLabelWork, value:"[email protected]") 
    contact.emailAddresses = [homeEmail, workEmail] 

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

    return contact 
} 

Activity view controller showing apps which support VCard format

VCard contact appearing in Messages app

+0

Thank you - Ho appena aggiornato il mio post iniziale con una nuova domanda. Penso che la tua risposta lo risolva, comunque. Ci proverò e tornerò da te.Molto apprezzato! –

+0

Grazie mille! Ha funzionato perfettamente. Lo capisco adesso. Ho un'ultima domanda, comunque. Quando condivido il contatto, il file .vcf ha un nome lungo come "6DD3C04D-08C1-44C7-8A7E-F08C6F0CB5CD.vcf". Posso cambiarlo in JohnnyAppleseed.vcf, proprio come si ottiene quando si condivide un contatto dalla propria rubrica? EDIT: Oh, ho capito! Ho trascurato .URLByAppendingPathComponent (NSUUID(). UUIDString). Grazie mille! –

+0

'CNContactFormatter' ti aiuterà lì. Ho aggiornato il codice per mostrare come potresti usarlo. Tornerà alla stringa UUID se il contatto non ha un nome (per qualsiasi motivo) o se si condividono più contatti contemporaneamente (nel qual caso probabilmente non si desidera utilizzare il nome). –

2

È possibile utilizzare un CNContact (richiede iOS 9):

let contact = CNMutableContact() 
    contact.givenName = "John" 
    contact.familyName = "Doe" 
    contact.emailAddresses = [ 
     CNLabeledValue(label: CNLabelWork, value: "[email protected]") 
    ] 
0

è molto semplice per creare il contatto dalla tua app iOS e condividere nel corso le applicazioni esterne.

In primo luogo è necessario creare Condividi Pulsante Azione come di seguito: -

-(void)shareContactAction:(UIButton*)sender 
{ 
    CNMutableContact *selectedCon = [[CNMutableContact alloc] init]; 
    selectedCon.givenName = @"ABC"; 
    selectedCon.familyName = @"XYZ"; 
    NSString *phoneNum = @"+91-XXXXXXXXXXX" 
    CNLabeledValue *contactNum1 = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:[CNPhoneNumber phoneNumberWithStringValue:phoneNum]]; 
    selectedCon.phoneNumbers = @[contactNum1]; 
    NSString *url=[self saveContactDetailsToDocDir:selectedCon]; 
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"Contact", [NSURL fileURLWithPath:url]] applicationActivities:nil]; 
    [self presentViewController:activityViewController animated:YES completion:nil];  
} 

di quanto si può chiamare la funzione di sotto del quale restituirà il percorso della carta contatto al precedente evento pulsante .

- (NSString *)saveContactDetailsToDocDir:(CNContact *)contact { 

    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,  NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString * contactCardPath = [documentsDirectory stringByAppendingString:@"/vCardName.vcf"]; 
    NSArray *array = [[NSArray alloc] initWithObjects:contact, nil]; 
    NSError *error; 
    NSData *data = [CNContactVCardSerialization dataWithContacts:array error:&error]; 
    [data writeToFile:contactCardPath atomically:YES]; 

    return contactCardPath; 
}