2016-07-12 15 views
5

Ich bin neu zu schnell und Methoden, die ich finde, sind über mein Problem veraltet. Ich baue eine Verzeichnis-App und ziehe Kontaktdaten aus einer API, nicht aus dem Adressbuch des Telefons.Wie erstellt man eine vCard/vcf-Datei für die Verwendung im Aktienbogen?

Wenn Sie in iOS zu Ihrem Adressbuch wechseln, können Sie einen Kontakt auswählen und "Kontakt freigeben" wählen, wodurch ein Freigabeblatt angezeigt wird. Ich möchte diese genaue Funktionalität in meiner App.

ich denken Ich habe Teile Blätter herausgefunden, und hier ist mein Code dafür:

@IBAction func actShare(sender: AnyObject) { 

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

Ich möchte "text" as NSString zu ändern, um eine vCard zu sein, als dass das Objekt ist, dass iOS Aktien aus dem Adressbuch, richtig? Angenommen, ich habe Recht, möchte ich eine vCard aus dem Kontaktobjekt meiner eigenen App erstellen, um sie mit entsprechenden Apps (E-Mail, SMS usw.) zu teilen.

Wie kann ich das in Swift erreichen? Wenn ich falsch liege, bitte korrigieren Sie mich und zeigen Sie mir, was ich tun muss. Vielen Dank.

EDIT: Okay, hier sind meine Änderungen.

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

und

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

    return contactCard 
} 

Allerdings, wenn ich auf die Schaltfläche klicken und es bringt meinen Anteil Blatt, ich wählen Sie die Anwendung, die ich teilen möchten und es nicht hinzufügen/attach den Kontakt Daten wie vorgesehen. Wie erreiche ich das?

Antwort

6

Der Trick hier ist, den Kontakt zu VCard (.vcf) Datei CNContactVCardSerialization.dataWithContacts mit zu speichern, übergeben Sie dann die Datei URL zum UIActivityViewController. Die Aktivitätsansicht Controller erkennt das vCard-Format von der Dateierweiterung, und zeigt die Anwendungen, wo das Format unterstützt wird (zum Beispiel Nachrichten, Post, Notizen, Fallschirmabwurf, etc)

Beispiel:

@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

Danke - ich meine erste Post mit einer neuen Frage gerade aktualisiert. Ich denke, deine Antwort wird es jedoch lösen. Ich werde es ausprobieren und zu dir zurückkommen.Sehr geschätzt! –

+0

Vielen Dank! Das hat perfekt funktioniert. Ich verstehe es jetzt. Ich habe jedoch eine letzte Frage. Wenn ich den Kontakt teile, hat die .vcf einen langen Namen wie "6DD3C04D-08C1-44C7-8A7E-F08C6F0CB5CD.vcf". Kann ich das in JohnnyAppleeseed.vcf ändern, so wie Sie es erhalten, wenn Sie einen Kontakt aus Ihrem eigenen Adressbuch freigeben? EDIT: Oh, ich habe es! Ich habe .URLByAppendingPathComponent (NSUUID(). UUIDstring) übersehen. Ich danke dir sehr! –

+0

'CNContactFormatter' wird Ihnen dort helfen. Ich habe den Code aktualisiert, um zu zeigen, wie Sie ihn verwenden können. Es wird auf die UUID-Zeichenfolge zurückgesetzt, wenn der Kontakt keinen Namen hat (aus welchem ​​Grund auch immer) oder wenn Sie mehrere Kontakte gleichzeitig teilen (in diesem Fall ist die Verwendung des Vornamens wahrscheinlich nicht erwünscht). –

2

Sie können eine CNContact verwenden (erfordert iOS 9):

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

Es ist sehr einfach Kontakt aus Ihrem iOS-App zu erstellen und über die externen Anwendungen teilen.

Zuerst müssen Sie Share Button Aktion wie unten erstellen: -

-(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];  
} 

als Sie die Funktion aufrufen, unter dem Sie den Pfad der Kontaktkarte in oben-Taste Veranstaltung wird zurückkehren .

- (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; 
}