session-ios/Signal/src/util/OWSContactsSyncing.m

141 lines
4.3 KiB
Mathematica
Raw Normal View History

//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSContactsSyncing.h"
#import "OWSContactsManager.h"
#import "TSAccountManager.h"
#import <SignalServiceKit/MIMETypeUtil.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSSyncContactsMessage.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSStorageManager.h>
2017-04-19 16:28:24 +02:00
NS_ASSUME_NONNULL_BEGIN
NSString *const kTSStorageManagerOWSContactsSyncingCollection = @"kTSStorageManagerOWSContactsSyncingCollection";
NSString *const kTSStorageManagerOWSContactsSyncingLastMessageKey =
@"kTSStorageManagerOWSContactsSyncingLastMessageKey";
@interface OWSContactsSyncing ()
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) OWSMessageSender *messageSender;
@property (nonatomic) BOOL isRequestInFlight;
@end
@implementation OWSContactsSyncing
- (instancetype)initWithContactsManager:(OWSContactsManager *)contactsManager
messageSender:(OWSMessageSender *)messageSender
{
self = [super init];
if (!self) {
return self;
}
OWSAssert(contactsManager);
OWSAssert(messageSender);
_contactsManager = contactsManager;
_messageSender = messageSender;
OWSSingletonAssert();
__weak OWSContactsSyncing *weakSelf = self;
[contactsManager.getObservableContacts watchLatestValue:^(id latestValue) {
[weakSelf sendSyncContactsMessageIfPossible];
}
onThread:[NSThread mainThread]
untilCancelled:nil];
return self;
}
#pragma mark - Methods
- (void)sendSyncContactsMessageIfNecessary
{
2017-04-19 16:28:24 +02:00
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;
}
OWSSyncContactsMessage *syncContactsMessage =
[[OWSSyncContactsMessage alloc] initWithContactsManager:self.contactsManager];
NSData *messageData = [syncContactsMessage buildPlainTextAttachmentData];
NSData *lastMessageData =
[[TSStorageManager sharedManager] objectForKey:kTSStorageManagerOWSContactsSyncingLastMessageKey
inCollection:kTSStorageManagerOWSContactsSyncingCollection];
if (lastMessageData && [lastMessageData isEqual:messageData]) {
// Ignore redundant contacts sync message.
return;
}
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(dispatch_get_main_queue(), ^{
self.isRequestInFlight = NO;
});
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send contacts sync message with error: %@", self.tag, error);
dispatch_async(dispatch_get_main_queue(), ^{
self.isRequestInFlight = NO;
});
}];
}
- (void)sendSyncContactsMessageIfPossible
{
2017-04-19 16:28:24 +02:00
AssertIsOnMainThread();
if (![self.contactsManager hasAddressBook]) {
// Don't bother until the contacts manager has finished setup.
return;
}
[[TSAccountManager sharedInstance] ifRegistered:YES
runAsync:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self sendSyncContactsMessageIfNecessary];
});
}];
}
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
@end
2017-04-19 16:28:24 +02:00
NS_ASSUME_NONNULL_END