Merge branch 'charlesmchen/contactParsingPerf'

pull/1/head
Matthew Chen 8 years ago
commit c7d25a66ad

@ -88,21 +88,30 @@ class SystemContactsFetcher: NSObject {
}
private func updateContacts() {
AssertIsOnMainThread()
systemContactsHaveBeenRequestedAtLeastOnce = true
var systemContacts = [CNContact]()
do {
let contactFetchRequest = CNContactFetchRequest(keysToFetch: allowedContactKeys)
try contactStore.enumerateContacts(with: contactFetchRequest) { (contact, _) -> Void in
systemContacts.append(contact)
let contactStore = self.contactStore
let allowedContactKeys = self.allowedContactKeys
DispatchQueue.global().async {
var systemContacts = [CNContact]()
do {
let contactFetchRequest = CNContactFetchRequest(keysToFetch: allowedContactKeys)
try contactStore.enumerateContacts(with: contactFetchRequest) { (contact, _) -> Void in
systemContacts.append(contact)
}
} catch let error as NSError {
Logger.error("\(self.TAG) Failed to fetch contacts with error:\(error)")
assertionFailure()
}
} catch let error as NSError {
Logger.error("\(self.TAG) Failed to fetch contacts with error:\(error)")
assertionFailure()
}
let contacts = systemContacts.map { Contact(systemContact: $0) }
self.delegate?.systemContactsFetcher(self, updatedContacts: contacts)
let contacts = systemContacts.map { Contact(systemContact: $0) }
DispatchQueue.main.async {
self.delegate?.systemContactsFetcher(self, updatedContacts: contacts)
}
}
}
private func startObservingContactChanges() {

@ -19,6 +19,8 @@ NSString *const kTSStorageManagerOWSContactsSyncingLastMessageKey =
@interface OWSContactsSyncing ()
@property (nonatomic, readonly) dispatch_queue_t serialQueue;
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) OWSMessageSender *messageSender;
@property (nonatomic) BOOL isRequestInFlight;
@ -70,50 +72,57 @@ NSString *const kTSStorageManagerOWSContactsSyncingLastMessageKey =
{
AssertIsOnMainThread();
if (self.isRequestInFlight) {
// De-bounce. It's okay if we ignore some new changes;
// `sendSyncContactsMessageIfPossible` is called fairly
// often so we'll sync soon.
return;
if (!self.serialQueue) {
_serialQueue = dispatch_queue_create("org.whispersystems.contacts.syncing", DISPATCH_QUEUE_SERIAL);
}
OWSSyncContactsMessage *syncContactsMessage =
[[OWSSyncContactsMessage alloc] initWithContactsManager:self.contactsManager];
NSData *messageData = [syncContactsMessage buildPlainTextAttachmentData];
NSData *lastMessageData =
[[TSStorageManager sharedManager] objectForKey:kTSStorageManagerOWSContactsSyncingLastMessageKey
inCollection:kTSStorageManagerOWSContactsSyncingCollection];
dispatch_async(self.serialQueue, ^{
if (lastMessageData && [lastMessageData isEqual:messageData]) {
// Ignore redundant contacts sync message.
return;
}
if (self.isRequestInFlight) {
// De-bounce. It's okay if we ignore some new changes;
// `sendSyncContactsMessageIfPossible` is called fairly
// often so we'll sync soon.
return;
}
self.isRequestInFlight = YES;
OWSSyncContactsMessage *syncContactsMessage =
[[OWSSyncContactsMessage alloc] initWithContactsManager:self.contactsManager];
[self.messageSender sendTemporaryAttachmentData:[syncContactsMessage buildPlainTextAttachmentData]
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{
DDLogInfo(@"%@ Successfully sent contacts sync message.", self.tag);
NSData *messageData = [syncContactsMessage buildPlainTextAttachmentData];
[[TSStorageManager sharedManager] setObject:messageData
forKey:kTSStorageManagerOWSContactsSyncingLastMessageKey
inCollection:kTSStorageManagerOWSContactsSyncingCollection];
NSData *lastMessageData =
[[TSStorageManager sharedManager] objectForKey:kTSStorageManagerOWSContactsSyncingLastMessageKey
inCollection:kTSStorageManagerOWSContactsSyncingCollection];
dispatch_async(dispatch_get_main_queue(), ^{
self.isRequestInFlight = NO;
});
if (lastMessageData && [lastMessageData isEqual:messageData]) {
// Ignore redundant contacts sync message.
return;
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send contacts sync message with error: %@", self.tag, error);
dispatch_async(dispatch_get_main_queue(), ^{
self.isRequestInFlight = NO;
});
}];
self.isRequestInFlight = YES;
[self.messageSender sendTemporaryAttachmentData:[syncContactsMessage buildPlainTextAttachmentData]
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{
DDLogInfo(@"%@ Successfully sent contacts sync message.", self.tag);
[[TSStorageManager sharedManager] setObject:messageData
forKey:kTSStorageManagerOWSContactsSyncingLastMessageKey
inCollection:kTSStorageManagerOWSContactsSyncingCollection];
dispatch_async(self.serialQueue, ^{
self.isRequestInFlight = NO;
});
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send contacts sync message with error: %@", self.tag, error);
dispatch_async(self.serialQueue, ^{
self.isRequestInFlight = NO;
});
}];
});
}
- (void)sendSyncContactsMessageIfPossible

Loading…
Cancel
Save