|  |  |  | //
 | 
					
						
							|  |  |  | //  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #import <SignalServiceKit/Contact.h>
 | 
					
						
							|  |  |  | #import <SignalServiceKit/ContactsManagerProtocol.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NS_ASSUME_NONNULL_BEGIN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @class ImageCache; | 
					
						
							|  |  |  | @class OWSPrimaryStorage; | 
					
						
							|  |  |  | @class SignalAccount; | 
					
						
							|  |  |  | @class UIFont; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Get latest Signal contacts, and be notified when they change. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | @interface OWSContactsManager : NSObject <ContactsManagerProtocol> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma mark - Setup
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (instancetype)init NS_UNAVAILABLE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (id)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (void)startObserving; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma mark - Accessors
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @property (nonnull, readonly) ImageCache *avatarCache; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @property (atomic, readonly) NSArray<Contact *> *allContacts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @property (atomic, readonly) NSDictionary<NSString *, Contact *> *allContactsMap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // order of the signalAccounts array respects the systems contact sorting preference
 | 
					
						
							|  |  |  | @property (atomic, readonly) NSArray<SignalAccount *> *signalAccounts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This will return an instance of SignalAccount for _known_ signal accounts.
 | 
					
						
							|  |  |  | - (nullable SignalAccount *)fetchSignalAccountForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | // This will always return an instance of SignalAccount.
 | 
					
						
							|  |  |  | - (SignalAccount *)fetchOrBuildSignalAccountForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | - (BOOL)hasSignalAccountForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (void)loadSignalAccountsFromCache; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma mark - System Contact Fetching
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Must call `requestSystemContactsOnce` before accessing this method
 | 
					
						
							|  |  |  | @property (nonatomic, readonly) BOOL isSystemContactsAuthorized; | 
					
						
							|  |  |  | @property (nonatomic, readonly) BOOL isSystemContactsDenied; | 
					
						
							|  |  |  | @property (nonatomic, readonly) BOOL systemContactsHaveBeenRequestedAtLeastOnce; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @property (nonatomic, readonly) BOOL supportsContactEditing; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Request systems contacts and start syncing changes. The user will see an alert
 | 
					
						
							|  |  |  | // if they haven't previously.
 | 
					
						
							|  |  |  | - (void)requestSystemContactsOnce; | 
					
						
							|  |  |  | - (void)requestSystemContactsOnceWithCompletion:(void (^_Nullable)(NSError *_Nullable error))completion; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Ensure's the app has the latest contacts, but won't prompt the user for contact
 | 
					
						
							|  |  |  | // access if they haven't granted it.
 | 
					
						
							|  |  |  | - (void)fetchSystemContactsOnceIfAlreadyAuthorized; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This variant will fetch system contacts if contact access has already been granted,
 | 
					
						
							|  |  |  | // but not prompt for contact access. Also, it will always notify delegates, even if
 | 
					
						
							|  |  |  | // contacts haven't changed, and will clear out any stale cached SignalAccounts
 | 
					
						
							|  |  |  | - (void)userRequestedSystemContactsRefreshWithCompletion:(void (^)(NSError *_Nullable error))completionHandler; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma mark - Util
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (BOOL)isSystemContact:(NSString *)recipientId; | 
					
						
							|  |  |  | - (BOOL)isSystemContactWithSignalAccount:(NSString *)recipientId; | 
					
						
							|  |  |  | - (BOOL)hasNameInSystemContactsForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | - (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier; | 
					
						
							|  |  |  | - (NSString *)displayNameForSignalAccount:(SignalAccount *)signalAccount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Used for sorting, respects system contacts name sort order preference. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | - (NSString *)comparableNameForSignalAccount:(SignalAccount *)signalAccount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Generally we prefer the formattedProfileName over the raw profileName so as to
 | 
					
						
							|  |  |  | // distinguish a profile name apart from a name pulled from the system's contacts.
 | 
					
						
							|  |  |  | // This helps clarify when the remote person chooses a potentially confusing profile name.
 | 
					
						
							|  |  |  | - (nullable NSString *)formattedProfileNameForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | - (nullable NSString *)profileNameForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | - (nullable NSString *)nameFromSystemContactsForRecipientId:(NSString *)recipientId; | 
					
						
							|  |  |  | - (NSString *)stringForConversationTitleWithPhoneIdentifier:(NSString *)recipientId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (nullable UIImage *)systemContactImageForPhoneIdentifier:(nullable NSString *)identifier; | 
					
						
							|  |  |  | - (nullable UIImage *)profileImageForPhoneIdentifier:(nullable NSString *)identifier; | 
					
						
							|  |  |  | - (nullable NSData *)profileImageDataForPhoneIdentifier:(nullable NSString *)identifier; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier; | 
					
						
							|  |  |  | - (NSAttributedString *)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount font:(UIFont *)font; | 
					
						
							|  |  |  | - (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font; | 
					
						
							|  |  |  | - (NSString *)contactOrProfileNameForPhoneIdentifier:(NSString *)recipientId; | 
					
						
							|  |  |  | - (NSAttributedString *)attributedContactOrProfileNameForPhoneIdentifier:(NSString *)recipientId; | 
					
						
							|  |  |  | - (NSAttributedString *)attributedContactOrProfileNameForPhoneIdentifier:(NSString *)recipientId | 
					
						
							|  |  |  |                                                              primaryFont:(UIFont *)primaryFont | 
					
						
							|  |  |  |                                                            secondaryFont:(UIFont *)secondaryFont; | 
					
						
							|  |  |  | - (NSAttributedString *)attributedContactOrProfileNameForPhoneIdentifier:(NSString *)recipientId | 
					
						
							|  |  |  |                                                        primaryAttributes:(NSDictionary *)primaryAttributes | 
					
						
							|  |  |  |                                                      secondaryAttributes:(NSDictionary *)secondaryAttributes; | 
					
						
							|  |  |  | @end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NS_ASSUME_NONNULL_END |