OWSContact from CNContact

Used in new contact picker for the Signal invite flow 

* populate emails
* nullability annotations

// FREEBIE
pull/1/head
Michael Kirk 9 years ago committed by GitHub
parent df756423f2
commit 3083e2929c

@ -1,6 +1,8 @@
#import <AddressBook/AddressBook.h>
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
*
* Contact represents relevant information related to a contact from the user's
@ -8,31 +10,39 @@
*
*/
@interface Contact : NSObject
@property (readonly, nonatomic) NSString *firstName;
@property (readonly, nonatomic) NSString *lastName;
@property (readonly, nonatomic) NSArray *parsedPhoneNumbers;
@property (readonly, nonatomic) NSArray *userTextPhoneNumbers;
@property (readonly, nonatomic) NSArray *emails;
@property (readonly, nonatomic) NSString *notes;
@class CNContact;
@class PhoneNumber;
- (NSString *)fullName;
@interface Contact : NSObject
@property (nullable, readonly, nonatomic) NSString *firstName;
@property (nullable, readonly, nonatomic) NSString *lastName;
@property (readonly, nonatomic) NSString *fullName;
@property (readonly, nonatomic) NSArray<PhoneNumber *> *parsedPhoneNumbers;
@property (readonly, nonatomic) NSArray<NSString *> *userTextPhoneNumbers;
@property (readonly, nonatomic) NSArray<NSString *> *emails;
@property (readonly, nonatomic) NSString *uniqueId;
#if TARGET_OS_IOS
@property (nullable, readonly, nonatomic) UIImage *image;
@property (readonly, nonatomic) ABRecordID recordID;
@property (nullable, nonatomic, readonly) CNContact *cnContact;
#endif // TARGET_OS_IOS
- (BOOL)isSignalContact;
- (NSArray<NSString *> *)textSecureIdentifiers;
#if TARGET_OS_IOS
- (instancetype)initWithContactWithFirstName:(NSString *)firstName
andLastName:(NSString *)lastName
andUserTextPhoneNumbers:(NSArray *)phoneNumbers
andImage:(UIImage *)image
- (instancetype)initWithContactWithFirstName:(nullable NSString *)firstName
andLastName:(nullable NSString *)lastName
andUserTextPhoneNumbers:(NSArray<NSString *> *)phoneNumbers
andImage:(nullable UIImage *)image
andContactID:(ABRecordID)record;
@property (readonly, nonatomic) UIImage *image;
@property (readonly, nonatomic) ABRecordID recordID;
#endif
- (instancetype)initWithContact:(CNContact *)contact;
#endif // TARGET_OS_IOS
@end
NS_ASSUME_NONNULL_END

@ -3,37 +3,92 @@
#import "SignalRecipient.h"
#import "TSStorageManager.h"
@import Contacts;
NS_ASSUME_NONNULL_BEGIN
@implementation Contact
#if TARGET_OS_IOS
- (instancetype)initWithContactWithFirstName:(NSString *)firstName
andLastName:(NSString *)lastName
- (instancetype)initWithContactWithFirstName:(nullable NSString *)firstName
andLastName:(nullable NSString *)lastName
andUserTextPhoneNumbers:(NSArray *)phoneNumbers
andImage:(UIImage *)image
andContactID:(ABRecordID)record {
andImage:(nullable UIImage *)image
andContactID:(ABRecordID)record
{
self = [super init];
if (!self) {
return self;
}
_firstName = firstName;
_lastName = lastName;
_uniqueId = [self.class uniqueIdFromABRecordId:record];
_recordID = record;
_userTextPhoneNumbers = phoneNumbers;
_parsedPhoneNumbers = [self.class parsedPhoneNumbersFromUserTextPhoneNumbers:phoneNumbers];
_image = image;
// Not using emails for old AB style contacts.
_emails = [NSMutableArray new];
return self;
}
- (instancetype)initWithContact:(CNContact *)contact
{
self = [super init];
if (self) {
_firstName = firstName;
_lastName = lastName;
_userTextPhoneNumbers = phoneNumbers;
_recordID = record;
_image = image;
NSMutableArray *parsedPhoneNumbers = [NSMutableArray array];
for (NSString *phoneNumberString in phoneNumbers) {
PhoneNumber *phoneNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumberString];
if (phoneNumber) {
[parsedPhoneNumbers addObject:phoneNumber];
}
if (!self) {
return self;
}
_cnContact = contact;
_firstName = contact.givenName;
_lastName = contact.familyName;
_uniqueId = contact.identifier;
NSMutableArray<NSString *> *phoneNumbers = [NSMutableArray new];
for (CNLabeledValue *phoneNumberField in contact.phoneNumbers) {
if ([phoneNumberField.value isKindOfClass:[CNPhoneNumber class]]) {
CNPhoneNumber *phoneNumber = (CNPhoneNumber *)phoneNumberField.value;
[phoneNumbers addObject:phoneNumber.stringValue];
}
}
_userTextPhoneNumbers = [phoneNumbers copy];
_parsedPhoneNumbers = [self.class parsedPhoneNumbersFromUserTextPhoneNumbers:phoneNumbers];
NSMutableArray<NSString *> *emailAddresses = [NSMutableArray new];
for (CNLabeledValue *emailField in contact.emailAddresses) {
if ([emailField.value isKindOfClass:[NSString class]]) {
[emailAddresses addObject:(NSString *)emailField.value];
}
}
_emails = [emailAddresses copy];
_parsedPhoneNumbers = parsedPhoneNumbers.copy;
if (contact.thumbnailImageData) {
_image = [UIImage imageWithData:contact.thumbnailImageData];
}
return self;
}
#endif
+ (NSString *)uniqueIdFromABRecordId:(ABRecordID)recordId
{
return [NSString stringWithFormat:@"ABRecordId:%d", recordId];
}
#endif // TARGET_OS_IOS
+ (NSArray<PhoneNumber *> *)parsedPhoneNumbersFromUserTextPhoneNumbers:(NSArray<NSString *> *)userTextPhoneNumbers
{
NSMutableArray<PhoneNumber *> *parsedPhoneNumbers = [NSMutableArray new];
for (NSString *phoneNumberString in userTextPhoneNumbers) {
PhoneNumber *phoneNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumberString];
if (phoneNumber) {
[parsedPhoneNumbers addObject:phoneNumber];
}
}
return [parsedPhoneNumbers copy];
}
- (NSString *)fullName {
NSMutableString *fullName = [NSMutableString string];
@ -70,3 +125,5 @@
}
@end
NS_ASSUME_NONNULL_END

@ -529,7 +529,7 @@ NS_ASSUME_NONNULL_BEGIN
break;
}
default: {
DDLogWarn(@"%@ Ignoring unknown group message type:%d", self.tag, dataMessage.group.type);
DDLogWarn(@"%@ Ignoring unknown group message type:%d", self.tag, (int)dataMessage.group.type);
}
}

Loading…
Cancel
Save