IOSについてローカルレコード情報を取得する(iOS 9.0前後を含む)
blog:developfan.com
簡単な本:http://www.jianshu.com/u/9fed08d0ebfb
ios開発では,ユーザのローカルの通信録を取得する機能がますます頻繁に出現し,七両自身も自社のプロジェクトで出会ったローカルの通信録情報を取得する機能(通称「シードユーザ機能」,恐ろしい).これに対して七両は、自分がローカルの通信録を使っているときの注意点をまとめ、皆さんの役に立つことを願っています.
まず、ローカルの通信録を取得する情報について、アップルはios 9.0の後に別の使用方法(controller)を発表し、前のsearchcontrollerとsearchBarに似ている.この7つの部分はここで2つの部分に分けられ、ios 9.0の前とios 9.0の後の2つの部分にまとめられている.
一、iOS 9.0前
まず七両の自分で書いたコードを添付します.
アップルの通信録に対する操作実装は、sqliteとsqlite 3の管理実装方式を類比することができ、通信録を使用する際にsqlite 3のような管理オブジェクトを呼び出す必要がある.
自分の習慣は通信録の操作過程を単例に書き、具体的には以下の通りである.
.hファイル
.mファイル
その後、通信録のデータをcontrollerに参照する方法は以下の通りです.
残りの余分な単一値属性に異なるフィールドが必要な場合、コードのABRecordCopyValueメソッドはC言語の辞書として理解できます.を選択します.
二、iOS 9.0以降
アップルはContactsUIの使用を推奨し、具体的な使用方法は以下の通りである.
詳細は次のとおりです.
簡単な本:http://www.jianshu.com/u/9fed08d0ebfb
ios開発では,ユーザのローカルの通信録を取得する機能がますます頻繁に出現し,七両自身も自社のプロジェクトで出会ったローカルの通信録情報を取得する機能(通称「シードユーザ機能」,恐ろしい).これに対して七両は、自分がローカルの通信録を使っているときの注意点をまとめ、皆さんの役に立つことを願っています.
まず、ローカルの通信録を取得する情報について、アップルはios 9.0の後に別の使用方法(controller)を発表し、前のsearchcontrollerとsearchBarに似ている.この7つの部分はここで2つの部分に分けられ、ios 9.0の前とios 9.0の後の2つの部分にまとめられている.
一、iOS 9.0前
まず七両の自分で書いたコードを添付します.
アップルの通信録に対する操作実装は、sqliteとsqlite 3の管理実装方式を類比することができ、通信録を使用する際にsqlite 3のような管理オブジェクトを呼び出す必要がある.
自分の習慣は通信録の操作過程を単例に書き、具体的には以下の通りである.
.hファイル
#import
#import
#import
typedef void(^YFAddressBookBlock)(BOOL canRead, ABAuthorizationStatus authorStatus);
@interface YFAddressBookManger : NSObject
@property (nonatomic, assign) ABAddressBookRef addressBook;
//
+ (instancetype)shareManger;
//
- (void)canReadAddressBookWithBlock:(YFAddressBookBlock)block;
- (void)gotoSetting:(UIViewController *)vc;
@end
.mファイル
#import "YFAddressBookManger.h"
@implementation YFAddressBookManger
+ (instancetype)shareManger{
static YFAddressBookManger *manger = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!manger) {
manger = [[YFAddressBookManger alloc]init];
}
});
return manger;
}
- (id)init{
self = [super init];
if (self) {
_addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
}
return self;
}
//
- (void)canReadAddressBookWithBlock:(YFAddressBookBlock)block{
ABAuthorizationStatus authStatus = ABAddressBookGetAuthorizationStatus();
if (authStatus == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
//
block(NO,kABAuthorizationStatusDenied);
}else{
block(YES,0);
}
});
});
}else if (authStatus == kABAuthorizationStatusAuthorized){
block(YES,0);
}else{
block(NO,authStatus);
}
}
//
- (void)gotoSetting:(UIViewController *)vc{
NSString *appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleDisplayName"];
if (!appName) appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleName"];
NSString *message = [NSString stringWithFormat:@" %@ \" - - \" ,\r %@ 。",[UIDevice currentDevice].model,appName];
UIAlertController *alertVC = [[UIAlertController alloc]init];
[UIAlertController alertControllerWithTitle:@" " message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@" " style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@" " style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
[alertVC addAction:cancleAction];
[alertVC addAction:sureAction];
}
@end
その後、通信録のデータをcontrollerに参照する方法は以下の通りです.
#pragma mark -
- (void)getDataSource{
if (_dataSource == nil) {
_dataSource = [NSMutableArray new];
}
[[YFAddressBookManger shareManger]canReadAddressBookWithBlock:^(BOOL canRead, ABAuthorizationStatus authorStatus) {
if (canRead) {
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex num = ABAddressBookGetPersonCount(addressBook);
for (NSInteger i = 0; i < num; i++) {
ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
ABMultiValueRef phones = ABRecordCopyValue(people, kABPersonPhoneProperty);
for (int k = 0; k
残りの余分な単一値属性に異なるフィールドが必要な場合、コードのABRecordCopyValueメソッドはC言語の辞書として理解できます.を選択します.
二、iOS 9.0以降
アップルはContactsUIの使用を推奨し、具体的な使用方法は以下の通りである.
pragma mark -
/* ,
@param picker
@param contact /
(void)contactPicker:(CNContactPickerViewController )picker didSelectContact:(CNContact )contact{
// 1. NSString *firstName = contact.givenName;
NSString *lastName = contact.familyName;
NSLog(@"%@ %@", firstName, lastName);
// 2. NSArray *phoneNumers = contact.phoneNumbers;
for (CNLabeledValue *labelValue in phoneNumers) {
CNPhoneNumber *phoneNumber = labelValue.value;
NSString *phoneValue = phoneNumber.stringValue;
NSString *phoneLabel = labelValue.label;
NSLog(@"%@ %@", phoneValue, phoneLabel);
}
}
/* ,
@param contactProperty
*/
(void)contactPicker:(CNContactPickerViewController )picker didSelectContactProperty:(CNContactProperty )contactProperty{}
詳細は次のとおりです.
// 1.
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
// 2. ,
if (status != CNAuthorizationStatusAuthorized) return;
// 3.
// 3.1.
CNContactStore *store = [[CNContactStore alloc] init];
// 3.2.
// keys , /
NSArray *fetchKeys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:fetchKeys];
// 3.3.
NSError *error = nil;
[store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
// stop
// 1.
NSString *firstname = contact.givenName;
NSString *lastname = contact.familyName;
NSLog(@"%@ %@", firstname, lastname);
// 2.
NSArray *phones = contact.phoneNumbers;
// 3.
for (CNLabeledValue *labelValue in phones) {
CNPhoneNumber *phoneNumber = labelValue.value;
NSLog(@"%@ %@", phoneNumber.stringValue, labelValue.label);
}
}];