Require AddressBook permission.

Signal requires the AddressBook permission to use the app at the
moment. This avoids the edgecases where a user doesn’t allow access to
his address book and then tries to use the app. We’re also doing a
significantly better job at explaining why we need this permission to
the user.
pull/1/head
Frederic Jacobs 10 years ago
parent 0090030f3d
commit c95f190140

@ -50,7 +50,7 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSContactsUsageDescription</key>
<string>Signal uses your AddressBook as contacts list. We do not store your contacts on the server.</string>
<string>Signal uses your contacts to find users you know. We do not store your contacts on the server.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Signal needs access to your microphone to make and receive phone calls.</string>
<key>UIAppFonts</key>

@ -46,7 +46,11 @@ static NSString * const kURLHostVerifyPrefix = @"verify";
[logger addLoggingCallback:^(NSString *category, id details, NSUInteger index) {}];
[Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]];
[Environment.getCurrent.phoneDirectoryManager startUntilCancelled:nil];
if ([TSAccountManager isRegistered]) {
[Environment.getCurrent.contactsManager doAfterEnvironmentInitSetup];
}
[Environment.getCurrent initCallListener];
[[TSStorageManager sharedManager] setupDatabase];
@ -151,6 +155,7 @@ static NSString * const kURLHostVerifyPrefix = @"verify";
if ([TSAccountManager isRegistered]) {
// We're double checking that the app is active, to be sure since we can't verify in production env due to code signing.
[TSSocketManager becomeActiveFromForeground];
[[Environment getCurrent].contactsManager verifyABPermission];
}
[self removeScreenProtection];

@ -41,6 +41,8 @@ typedef void(^ABReloadRequestCompletionBlock)(NSArray *contacts);
+(BOOL)name:(NSString *)nameString matchesQuery:(NSString *)queryString;
+(BOOL)phoneNumber:(PhoneNumber *)phoneNumber matchesQuery:(NSString *)queryString;
- (void)verifyABPermission;
- (NSArray*)allContacts;
- (NSArray*)signalContacts;
- (NSArray*)textSecureContacts;

@ -27,6 +27,7 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL*);
}
return self;
}
-(void) doAfterEnvironmentInitSetup {
[self setupAddressBook];
[observableContactsController watchLatestValueOnArbitraryThread:^(NSArray *latestContacts) {
@ -46,6 +47,12 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL*);
[life cancel];
}
- (void)verifyABPermission {
if (!addressBookReference) {
[self setupAddressBook];
}
}
#pragma mark - Notification Handlers
-(void) registerNotificationHandlers{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatedDirectoryHandler:) name:NOTIFICATION_DIRECTORY_UPDATE object:nil];
@ -88,7 +95,9 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &creationError);
checkOperationDescribe(nil == creationError, [((__bridge NSError *)creationError) localizedDescription]) ;
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
// TO DO: DISPLAY ALERT
if (!granted) {
[ContactsManager blockingContactDialog];
}
});
[observableContactsController updateValue:[self getContactsFromAddressBook:addressBookRef]];
}
@ -103,6 +112,20 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
}
}
+ (void)blockingContactDialog{
UIAlertController *controller = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"AB_PERMISSION_MISSING_TITLE", nil)
message:NSLocalizedString(@"AB_PERMISSION_MISSING_BODY", nil)
preferredStyle:UIAlertControllerStyleAlert];
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"AB_PERMISSION_MISSING_ACTION", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}]];
[[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:controller animated:YES completion:nil];
}
- (void)setupLatestRedPhoneUsers:(NSArray *)users {
if (users) {
latestWhisperUsersById = [ContactsManager keyContactsById:users];
@ -126,6 +149,7 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &creationError);
assert((addressBookRef == nil) == (creationError != nil));
if (creationError != nil) {
[self blockingContactDialog];
return [TOCFuture futureWithFailure:(__bridge_transfer id)creationError];
}
@ -138,6 +162,7 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
[futureAddressBookSource trySetResult:addressBook];
});
} else {
[self blockingContactDialog];
[futureAddressBookSource trySetFailure:(__bridge id)requestAccessError];
}
});

@ -9,6 +9,7 @@
#import "CodeVerificationViewController.h"
#import "Environment.h"
#import "ContactsManager.h"
#import "PhoneNumberDirectoryFilterManager.h"
#import "RPServerRequestsManager.h"
#import "LocalizableText.h"
@ -62,7 +63,19 @@
[self registerWithSuccess:^{
[_submitCodeSpinner stopAnimating];
[Environment.getCurrent.phoneDirectoryManager forceUpdate];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
[self.navigationController dismissViewControllerAnimated:YES completion:^{
UIAlertController *controller = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"REGISTER_CONTACTS_WELCOME", nil)
message:NSLocalizedString(@"REGISTER_CONTACTS_BODY", nil)
preferredStyle:UIAlertControllerStyleAlert];
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"REGISTER_CONTACTS_CONTINUE", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[Environment.getCurrent.contactsManager doAfterEnvironmentInitSetup];
}]];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:controller animated:YES completion:nil];
}];
} failure:^(NSError *error) {
[self showAlertForError:error];
[self enableServerActions:YES];

Loading…
Cancel
Save