Add conversion methods between vcard, system contacts and ows contacts.

pull/1/head
Matthew Chen 7 years ago
parent 0d8cfc5403
commit bd7c8e4a4b

@ -6,6 +6,7 @@
NS_ASSUME_NONNULL_BEGIN
@class CNContact;
@class OWSSignalServiceProtosDataMessage;
@class TSAttachment;
@class YapDatabaseReadWriteTransaction;
@ -108,6 +109,21 @@ typedef NS_ENUM(NSUInteger, OWSContactAddressType) {
@interface OWSContacts : NSObject
#pragma mark - VCard Serialization
+ (nullable CNContact *)systemContactForVCardData:(NSData *)data;
+ (nullable NSData *)vCardDataForSystemContact:(CNContact *)systemContact;
#pragma mark - System Contact Conversion
+ (nullable OWSContact *)contactForSystemContact:(CNContact *)systemContact;
+ (nullable CNContact *)systemContactForContact:(OWSContact *)contact;
#pragma mark -
+ (nullable OWSContact *)contactForVCardData:(NSData *)data;
+ (nullable NSData *)vCardDataContact:(OWSContact *)contact;
@end
NS_ASSUME_NONNULL_END

@ -346,6 +346,8 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSContacts
#pragma mark - VCard Serialization
+ (nullable CNContact *)systemContactForVCardData:(NSData *)data
{
OWSAssert(data);
@ -366,6 +368,28 @@ NS_ASSUME_NONNULL_BEGIN
return contacts.firstObject;
}
+ (nullable NSData *)vCardDataForSystemContact:(CNContact *)systemContact
{
OWSAssert(systemContact);
NSError *error;
NSData *_Nullable data = [CNContactVCardSerialization dataWithContacts:@[
systemContact,
]
error:&error];
if (!data || error) {
OWSProdLogAndFail(@"%@ could not serialize to vcard: %@", self.logTag, error);
return nil;
}
if (data.length < 1) {
OWSProdLogAndFail(@"%@ empty vcard data: %@", self.logTag, error);
return nil;
}
return data;
}
#pragma mark - System Contact Conversion
+ (nullable OWSContact *)contactForSystemContact:(CNContact *)systemContact
{
if (!systemContact) {
@ -461,8 +485,135 @@ NS_ASSUME_NONNULL_BEGIN
}
}
+ (nullable CNContact *)systemContactForContact:(OWSContact *)contact
{
if (!contact) {
OWSProdLogAndFail(@"%@ Missing contact.", self.logTag);
return nil;
}
if (!contact.isValid) {
OWSProdLogAndFail(@"%@ Invalid contact.", self.logTag);
return nil;
}
CNMutableContact *systemContact = [CNMutableContact new];
systemContact.givenName = contact.givenName;
systemContact.middleName = contact.middleName;
systemContact.familyName = contact.familyName;
systemContact.namePrefix = contact.namePrefix;
systemContact.nameSuffix = contact.nameSuffix;
// TODO: Display name.
// contact.displayName = [CNContactFormatter stringFromContact:contact
// style:CNContactFormatterStyleFullName]; contact.organizationName = contact.organizationName.ows_stripped;
NSMutableArray<CNLabeledValue<CNPhoneNumber *> *> *systemPhoneNumbers = [NSMutableArray new];
for (OWSContactPhoneNumber *phoneNumber in contact.phoneNumbers) {
if (!phoneNumber.isValid) {
OWSProdLogAndFail(@"%@ invalid phone number.", self.logTag);
continue;
}
switch (phoneNumber.phoneType) {
case OWSContactPhoneType_Home:
[systemPhoneNumbers
addObject:[CNLabeledValue
labeledValueWithLabel:CNLabelHome
value:[CNPhoneNumber
phoneNumberWithStringValue:phoneNumber.phoneNumber]]];
break;
case OWSContactPhoneType_Mobile:
[systemPhoneNumbers
addObject:[CNLabeledValue
labeledValueWithLabel:CNLabelPhoneNumberMobile
value:[CNPhoneNumber
phoneNumberWithStringValue:phoneNumber.phoneNumber]]];
break;
case OWSContactPhoneType_Work:
[systemPhoneNumbers
addObject:[CNLabeledValue
labeledValueWithLabel:CNLabelWork
value:[CNPhoneNumber
phoneNumberWithStringValue:phoneNumber.phoneNumber]]];
break;
default:
[systemPhoneNumbers
addObject:[CNLabeledValue
labeledValueWithLabel:phoneNumber.label
value:[CNPhoneNumber
phoneNumberWithStringValue:phoneNumber.phoneNumber]]];
break;
}
}
systemContact.phoneNumbers = systemPhoneNumbers;
NSMutableArray<CNLabeledValue<NSString *> *> *systemEmails = [NSMutableArray new];
for (OWSContactEmail *email in contact.emails) {
if (!email.isValid) {
OWSProdLogAndFail(@"%@ invalid email.", self.logTag);
continue;
}
switch (email.emailType) {
case OWSContactEmailType_Home:
[systemEmails addObject:[CNLabeledValue labeledValueWithLabel:CNLabelHome value:email.email]];
break;
case OWSContactEmailType_Mobile:
[systemEmails addObject:[CNLabeledValue labeledValueWithLabel:@"Mobile" value:email.email]];
break;
case OWSContactEmailType_Work:
[systemEmails addObject:[CNLabeledValue labeledValueWithLabel:CNLabelWork value:email.email]];
break;
default:
[systemEmails addObject:[CNLabeledValue labeledValueWithLabel:email.label value:email.email]];
break;
}
}
systemContact.emailAddresses = systemEmails;
NSMutableArray<CNLabeledValue<CNPostalAddress *> *> *systemAddresses = [NSMutableArray new];
for (OWSContactAddress *address in contact.addresses) {
if (!address.isValid) {
OWSProdLogAndFail(@"%@ invalid address.", self.logTag);
continue;
}
CNMutablePostalAddress *systemAddress = [CNMutablePostalAddress new];
systemAddress.street = address.street;
// TODO: Is this the correct mapping?
// systemAddress.subLocality = address.neighborhood;
systemAddress.city = address.city;
// TODO: Is this the correct mapping?
// systemAddress.subAdministrativeArea = address.region;
systemAddress.state = address.region;
systemAddress.postalCode = address.postcode;
// TODO: Should we be using 2-letter codes, 3-letter codes or names?
systemAddress.ISOCountryCode = address.country;
switch (address.addressType) {
case OWSContactAddressType_Home:
[systemAddresses addObject:[CNLabeledValue labeledValueWithLabel:CNLabelHome value:systemAddress]];
break;
case OWSContactAddressType_Work:
[systemAddresses addObject:[CNLabeledValue labeledValueWithLabel:CNLabelWork value:systemAddress]];
break;
default:
[systemAddresses addObject:[CNLabeledValue labeledValueWithLabel:address.label value:systemAddress]];
break;
}
}
systemContact.postalAddresses = systemAddresses;
// TODO: Avatar
// @property (readonly, copy, nullable, NS_NONATOMIC_IOSONLY) NSData *imageData;
// @property (readonly, copy, nullable, NS_NONATOMIC_IOSONLY) NSData *thumbnailImageData;
return systemContact;
}
#pragma mark -
+ (nullable OWSContact *)contactForVCardData:(NSData *)data
{
OWSAssert(data);
CNContact *_Nullable systemContact = [self systemContactForVCardData:data];
if (!systemContact) {
return nil;
@ -470,6 +621,17 @@ NS_ASSUME_NONNULL_BEGIN
return [self contactForSystemContact:systemContact];
}
+ (nullable NSData *)vCardDataContact:(OWSContact *)contact
{
OWSAssert(contact);
CNContact *_Nullable systemContact = [self systemContactForContact:contact];
if (!systemContact) {
return nil;
}
return [self vCardDataForSystemContact:systemContact];
}
@end
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save