我在获得用户许可使用他的地址簿后第一次获得了很长的延迟(5-6秒) 。第一次之后,添加新的联系人视图控制器立即显示。 谁知道为什么会这样?我在IOS 7.1和8上使用Xcode 5或6 beta(同样的事情发生)
这就是我要求权限的方式:
ABAddressBookRef addressBook = NULL;
CFErrorRef error = NULL;
switch (ABAddressBookGetAuthorizationStatus()) {
case kABAuthorizationStatusAuthorized: {
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
[self addToContacts];
if (addressBook != NULL) CFRelease(addressBook);
break;
}
case kABAuthorizationStatusDenied: {
//NSLog(@"Access denied to address book");
NSString *msgString = @"You have denied access to contacts. Please go to settings to enable access, then try again.";
UIAlertView *returnAl = [[UIAlertView alloc] initWithTitle:@"Unable to save!" message:msgString delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[returnAl show];
[self performSelector:@selector(dismissAlert:) withObject:returnAl afterDelay:3];
break;
}
case kABAuthorizationStatusNotDetermined: {
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"Access was granted trying to add");
[self addToContacts];
} else {
NSLog(@"Access was not granted");
}
if (addressBook != NULL) CFRelease(addressBook);
});
break;
}
case kABAuthorizationStatusRestricted: {
NSLog(@"access restricted to address book");
NSString *msgString = @"You have denied access to contacts. Please go to settings to enable access, then try again.";
UIAlertView *returnAl = [[UIAlertView alloc] initWithTitle:@"Unable to save!" message:msgString delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[returnAl show];
[self performSelector:@selector(dismissAlert:) withObject:returnAl afterDelay:3];
break;
}
}
这是我发起添加新联系
的方式ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(nil,nil);
ABRecordRef person = ABPersonCreate();
// Setting basic properties
ABRecordSetValue(person, kABPersonFirstNameProperty, (__bridge CFTypeRef)(user[@"name"]) , nil);
ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFTypeRef)(user[@"surName"]), nil);
ABRecordSetValue(person, kABPersonJobTitleProperty, (__bridge CFTypeRef)(user[@"workTitle"]), nil);
//ABRecordSetValue(person, kABPersonDepartmentProperty, @"iPhone development department", nil);
ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFTypeRef)(user[@"company"]), nil);
ABRecordSetValue(person, kABPersonNoteProperty, @"Contact saved by introdU app", nil);
// Adding phone numbers
ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFTypeRef)(user[@"mobile"]), (CFStringRef)@"iPhone", NULL);
ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFTypeRef)(user[@"tel"]), (CFStringRef)@"Work", NULL);
//ABMultiValueAddValueAndLabel(phoneNumberMultiValue, @"08701234567", (CFStringRef)@"0870", NULL);
ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
if (phoneNumberMultiValue != NULL) { CFRelease(phoneNumberMultiValue); phoneNumberMultiValue = NULL; };
// Adding url
ABMutableMultiValueRef urlMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(urlMultiValue, (__bridge CFTypeRef)(user[@"url"]), kABPersonHomePageLabel, NULL);
ABRecordSetValue(person, kABPersonURLProperty, urlMultiValue, nil);
CFRelease(urlMultiValue);
// Adding emails
ABMutableMultiValueRef emailMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(emailMultiValue, (__bridge CFTypeRef)(user[@"email"]), (CFStringRef)@"Work", NULL);
//ABMultiValueAddValueAndLabel(emailMultiValue, @"ondrej.rafaj@fuerteint.com", (CFStringRef)@"Work", NULL);
ABRecordSetValue(person, kABPersonEmailProperty, emailMultiValue, nil);
CFRelease(emailMultiValue);
// Adding address
ABMutableMultiValueRef addressMultipleValue = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];
[addressDictionary setObject:user[@"address"] forKey:(NSString *)kABPersonAddressStreetKey];
[addressDictionary setObject:user[@"city"] forKey:(NSString *)kABPersonAddressCityKey];
[addressDictionary setObject:user[@"postalCode"] forKey:(NSString *)kABPersonAddressZIPKey];
[addressDictionary setObject:user[@"country"] forKey:(NSString *)kABPersonAddressCountryKey];
//[addressDictionary setObject:@"gb" forKey:(NSString *)kABPersonAddressCountryCodeKey];
ABMultiValueAddValueAndLabel(addressMultipleValue, (__bridge CFTypeRef)(addressDictionary), kABWorkLabel, NULL);
ABRecordSetValue(person, kABPersonAddressProperty, addressMultipleValue, nil);
CFRelease(addressMultipleValue);
ABPersonSetImageData(person, (__bridge CFTypeRef)(profileImageData), nil);
// Adding person to the address book
ABAddressBookAddRecord(addressBook, person, nil);
CFRelease(addressBook);
// Creating view controller for a new contact
ABNewPersonViewController *c = [[ABNewPersonViewController alloc] init];
[c setNewPersonViewDelegate:self];
[c setDisplayedPerson:person];
if (person != NULL) { CFRelease(person); person = NULL; };
[self.navigationController pushViewController:c animated:YES];
答案 0 :(得分:4)
这种情况正在发生,因为ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
的完成块是在任意队列上调用的。
因此,当您第一次运行此代码时,您将在任意队列上调用视图控制器演示文稿 - 每次在主队列中调用它时,它都可以正常工作。
您需要做的就是将完成块分配给主队列。
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"Access was granted trying to add");
dispatch_async(dispatch_get_main_queue(), ^{
[self addToContacts];
});
} else {
NSLog(@"Access was not granted");
}
if (addressBook != NULL) CFRelease(addressBook);
});