iOS開發--系統通訊錄的訪問與添加聯繫人

来源:http://www.cnblogs.com/Cloud-90/archive/2016/02/04/5181991.html
-Advertisement-
Play Games

公司項目有訪問通訊錄的需求,所以開始了探索之路。從開始的一無所知,到知識的漸漸清晰。這一切要感謝廣大無私分享的 “coder”,註:我是尊稱的語氣! 蘋果提供了訪問系統通訊錄的框架,以便開發者對系統通訊錄進行操作。(此demo為純代碼),想要訪問通訊錄,需要添加AddressBookUI.frame


  公司項目有訪問通訊錄的需求,所以開始了探索之路。從開始的一無所知,到知識的漸漸清晰。這一切要感謝廣大無私分享的 “coder”,註:我是尊稱的語氣!

  蘋果提供了訪問系統通訊錄的框架,以便開發者對系統通訊錄進行操作。(此demo為純代碼),想要訪問通訊錄,需要添加AddressBookUI.framework和AddressBook.framework兩個框架,添加的地點這裡就不在贅述了。在控制器內部首先import兩個頭文件,<AddressBook/AddressBook.h> 和 <AddressBookUI/AddressBookUI.h>,如下圖所示:

 1 //
 2 //  ZBSampleViewController.m
 3 //  ZBAddressBookDemo
 4 //
 5 //  Created by zhangb on 16/02/04.
 6 //  Copyright (c) 2016年 mbp. All rights reserved.
 7 //
 8 
 9 #import "ZBSampleViewController.h"
10 #import <AddressBook/AddressBook.h>
11 #import <AddressBookUI/AddressBookUI.h>

  首先為了方便演示與操作,這裡就以兩個按鈕的操作代替具體的訪問過程,當然具體操作要具體分析,這裡只是記錄訪問通訊錄,包括:1)查看聯繫人  2)向通訊錄內添加聯繫人。下麵是代碼示例:

  ABPeoplePickerNavigationController為展示系統通訊錄的控制器,並且需要遵循其代理方法。

1 #define IS_iOS8 [[UIDevice currentDevice].systemVersion floatValue] >= 8.0f
2 #define IS_iOS6 [[UIDevice currentDevice].systemVersion floatValue] >= 6.0f
3 
4 @interface ZBSampleViewController ()<ABPeoplePickerNavigationControllerDelegate>{
5 
6     ABPeoplePickerNavigationController *_abPeoplePickerVc;
7     
8 }

 

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     
 4     //1.打開通訊錄
 5     UIButton *openAddressBook = [UIButton buttonWithType:UIButtonTypeCustom];
 6     openAddressBook.frame = CGRectMake(100, 50, 100, 50);
 7     [openAddressBook setTitle:@"打開通訊錄" forState:UIControlStateNormal];
 8     openAddressBook.backgroundColor = [UIColor greenColor];
 9     [openAddressBook setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
10     [openAddressBook addTarget:self action:@selector(gotoAddressBook) forControlEvents:UIControlEventTouchUpInside];
11     [self.view addSubview:openAddressBook];
12     
13     //2.添加聯繫人
14     UIButton *addContacts = [UIButton buttonWithType:UIButtonTypeCustom];
15     addContacts.frame = CGRectMake(100, 150, 100, 50);
16     [addContacts setTitle:@"添加聯繫人" forState:UIControlStateNormal];
17     addContacts.backgroundColor = [UIColor greenColor];
18     [addContacts setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
19     [addContacts addTarget:self action:@selector(gotoAddContacts) forControlEvents:UIControlEventTouchUpInside];
20     [self.view addSubview:addContacts];
21 
22 }

  打開系統通訊錄方法為openAddressBook按鈕的點擊事件,請忽略按鈕的樣式O(∩_∩)O~;

  下麵的IS_iOS8為我定義的巨集,判斷系統的版本(上面有代碼示例)。

 1 /**
 2  打開通訊錄
 3  */
 4 - (void)gotoAddressBook{
 5     
 6     _abPeoplePickerVc = [[ABPeoplePickerNavigationController alloc] init];
 7     _abPeoplePickerVc.peoplePickerDelegate = self;
 8     
 9     //下麵的判斷是ios8之後才需要加的,不然會自動返回app內部
10     if(IS_iOS8){
11         
12         //predicateForSelectionOfPerson預設是true (當你點擊某個聯繫人查看詳情的時候會返回app),如果你預設為true 但是實現-peoplePickerNavigationController:didSelectPerson:property:identifier:
       代理方法也是可以的,與此同時不能實現peoplePickerNavigationController: didSelectPerson:不然還是會返回app。
13 //總之在ios8之後加上此句比較穩妥 14 _abPeoplePickerVc.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false]; 15 16 //predicateForSelectionOfProperty預設是true (當你點擊某個聯繫人的某個屬性的時候會返回app),此方法只要是預設值,無論你代理方法實現與否都會返回app。 17 // _abPeoplePickerVc.predicateForSelectionOfProperty = [NSPredicate predicateWithValue:false]; 18 19 //predicateForEnablingPerson預設是true,當設置為false時,所有的聯繫人都不能被點擊。 20 // _abPeoplePickerVc.predicateForEnablingPerson = [NSPredicate predicateWithValue:true]; 21 } 22 [self presentViewController:_abPeoplePickerVc animated:YES completion:nil]; 23 24 }

  這裡需要註意的是:

  在iOS8之後需要加_abPeoplePickerVc.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false];這句代碼,不然當你選擇通訊錄中的某個聯繫人的時候會直接返回app內部(類似crash)。predicateForSelectionOfPerson預設是true (當你點擊某個聯繫人查看詳情的時候會返回app),如果你預設為true 但是實現-peoplePickerNavigationController:didSelectPerson:property:identifier: 代理方法也是可以的,與此同時不能實現peoplePickerNavigationController: didSelectPerson:不然還是會返回app。

  _abPeoplePickerVc.predicateForSelectionOfProperty = [NSPredicate predicateWithValue:false];作用同上。但是_abPeoplePickerVc.predicateForEnablingPerson 的斷言語句必須為true,否則任何聯繫人你都不能選擇。上面的代碼中也有詳細描述。

 1 #pragma mark - ABPeoplePickerNavigationController的代理方法
 2 
 3 - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
 4     
 5     ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
 6     
 7     long index = ABMultiValueGetIndexForIdentifier(phone,identifier);
 8     
 9     NSString *phoneNO = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, index);
10     [phoneNO stringByReplacingOccurrencesOfString:@"-" withString:@""];
11     if (phone && phoneNO.length == 11) {
12         //TODO:獲取電話號碼要做的事情
13         
14         [peoplePicker dismissViewControllerAnimated:YES completion:nil];
15         return;
16     }else{
17         if (IS_iOS8){
18             UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:nil message:@"請選擇正確手機號" preferredStyle:UIAlertControllerStyleAlert];
19             UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
20                 [self dismissViewControllerAnimated:YES completion:nil];
21             }];
22             [tipVc addAction:cancleAction];
23             [self presentViewController:tipVc animated:YES completion:nil];
24             
25         }else{
26             UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"請選擇正確手機號" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil];
27             [alertView show];
28         }
29         //非ARC模式需要釋放對象
30 //        [alertView release];
31     }
32 }
33 
34 
35 - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person NS_AVAILABLE_IOS(8_0)
36 {
37     ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
38     personViewController.displayedPerson = person;
39     
40     [peoplePicker pushViewController:personViewController animated:YES];
41     //非ARC模式需要釋放對象
42 //    [personViewController release];
43 }
44 
45 /**
46  peoplePickerNavigationController點擊取消按鈕時調用
47  */
48 - (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
49 {
50     [peoplePicker dismissViewControllerAnimated:YES completion:nil];
51 }
52 
53 /**
54  iOS8被廢棄了,iOS8前查看聯繫人必須實現(點擊聯繫人可以繼續操作)
55  */
56 - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person NS_DEPRECATED_IOS(2_0, 8_0)
57 {
58     return YES;
59 }
60 
61 /**
62  iOS8被廢棄了,iOS8前查看聯繫人屬性必須實現(點擊聯繫人屬性可以繼續操作)
63  */
64 - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_DEPRECATED_IOS(2_0, 8_0)
65 {
66     ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
67     
68     long index = ABMultiValueGetIndexForIdentifier(phone,identifier);
69     
70     NSString *phoneNO = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, index);
71     phoneNO = [phoneNO stringByReplacingOccurrencesOfString:@"-" withString:@""];
72     NSLog(@"%@", phoneNO);
73     if (phone && phoneNO.length == 11) {
74         //TODO:獲取電話號碼要做的事情
75         
76         [peoplePicker dismissViewControllerAnimated:YES completion:nil];
77         return NO;
78     }else{
79         if (IS_iOS8){
80             UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:nil message:@"請選擇正確手機號" preferredStyle:UIAlertControllerStyleAlert];
81             UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
82                 [self dismissViewControllerAnimated:YES completion:nil];
83             }];
84             [tipVc addAction:cancleAction];
85             [self presentViewController:tipVc animated:YES completion:nil];
86             
87         }else{
88             UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"請選擇正確手機號" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil];
89             [alertView show];
90         }
91     }
92     return YES;
93 }

  ABPeoplePickerNavigationController的代理方法也很好理解,看字面意思就能夠猜出代理方法的執行時間與能夠做什麼。拿第一個代理方法說明一下,也就是- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier;第一個參數就不用說了,第二個參數 ABRecordRef 這是一個聯繫人的引用也可以說是一個記錄,你可以理解為一個聯繫人。第三個參數是聯繫人附帶屬性的ID,其實ABPropertyID是個int類型值。第四個參數是多值屬性的標簽。

  ABRecordCopyValue(ABRecordRef record, ABPropertyID property)返回一個CFTypeRef類型。此方法是從系統的通訊錄內,copy出用戶所選擇的某個聯繫人數據。返回類型要看參數傳遞的是什麼,第一個參數是聯繫人記錄,第二個參數是參數ID,也就是用戶選擇的聯繫人的某個屬性的ID。kABPersonPhoneProperty代表的是手機號碼屬性的ID,假如上面的ABRecordCopyValue的第二個參數傳遞kABPersonAddressProperty,則返回的是聯繫人的地址屬性。下麵是效果圖(因為是模擬器和真機有些差異)。

 

  下麵介紹下,向系統通訊錄內添加聯繫人。這裡我只設置了聯繫人的三個屬性:名字,電話,郵件,並將屬性存在了字典里。

1 -(instancetype)init{
2     if (self = [super init]) {
3         _infoDictionary = [NSMutableDictionary dictionaryWithCapacity:0];
4         [_infoDictionary setObject:@"張三" forKey:@"name"];
5         [_infoDictionary setObject:@"13000000000" forKey:@"phone"];
6         [_infoDictionary setObject:@"[email protected]" forKey:@"email"];
7     }
8     return self;
9 }

  因為蘋果越來越註重保護用戶的隱私,現在需要修改系統通訊錄內的聯繫人信息時,必須要用戶授權才可以進行。授權鑒定代碼為ABAddressBookRequestAccessWithCompletion(ABAddressBookRef addressBook,  ABAddressBookRequestAccessCompletionHandler completion) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);下麵的代碼中都有詳細描述。

  1 /**
  2  添加聯繫人
  3  */
  4 - (void)gotoAddContacts{
  5     
  6     //添加到通訊錄,判斷通訊錄是否存在
  7     if ([self isExistContactPerson]) {//存在,返回
  8         //提示
  9         if (IS_iOS8) {
 10             UIAlertController *tipVc  = [UIAlertController alertControllerWithTitle:@"提示" message:@"聯繫人已存在..." preferredStyle:UIAlertControllerStyleAlert];
 11             UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
 12                 [self dismissViewControllerAnimated:YES completion:nil];
 13             }];
 14             [tipVc addAction:cancleAction];
 15             [self presentViewController:tipVc animated:YES completion:nil];
 16         }else{
 17             UIAlertView *tip = [[UIAlertView alloc] initWithTitle:@"提示" message:@"聯繫人已存在..." delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
 18             [tip show];
 19             //        [tip release];
 20         }
 21         return;
 22     }else{//不存在  添加
 23         [self creatNewRecord];
 24     }
 25 }
 26 
 27 - (BOOL)isExistContactPerson{
 28     //這個變數用於記錄授權是否成功,即用戶是否允許我們訪問通訊錄
 29     int __block tip=0;
 30     
 31     BOOL __block isExist = NO;
 32     //聲明一個通訊簿的引用
 33     ABAddressBookRef addBook =nil;
 34     //因為在IOS6.0之後和之前的許可權申請方式有所差別,這裡做個判斷
 35     if (IS_iOS6) {
 36         //創建通訊簿的引用,第一個參數暫時寫NULL,官方文檔就是這麼說的,後續會有用,第二個參數是error參數
 37         CFErrorRef error = NULL;
 38         addBook=ABAddressBookCreateWithOptions(NULL, &error);
 39         //創建一個初始信號量為0的信號
 40         dispatch_semaphore_t sema=dispatch_semaphore_create(0);
 41         //申請訪問許可權
 42         ABAddressBookRequestAccessWithCompletion(addBook, ^(bool greanted, CFErrorRef error)        {
 43             //greanted為YES是表示用戶允許,否則為不允許
 44             if (!greanted) {
 45                 tip=1;
 46                 
 47             }else{
 48                 //獲取所有聯繫人的數組
 49                 CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);
 50                 //獲取聯繫人總數
 51                 CFIndex number = ABAddressBookGetPersonCount(addBook);
 52                 //進行遍歷
 53                 for (NSInteger i=0; i<number; i++) {
 54                     //獲取聯繫人對象的引用
 55                     ABRecordRef  people = CFArrayGetValueAtIndex(allLinkPeople, i);
 56                     //獲取當前聯繫人名字
 57                     NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
 58                     
 59                     if ([firstName isEqualToString:[_infoDictionary objectForKey:@"name"]]) {
 60                         isExist = YES;
 61                     }
 62                     
 63 //                    //獲取當前聯繫人姓氏
 64 //                    NSString*lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
 65 
 66 //獲取當前聯繫人中間名
 67 //                    NSString*middleName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));
 68 //                    //獲取當前聯繫人的名字首碼
 69 //                    NSString*prefix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonPrefixProperty));
 70 //                    //獲取當前聯繫人的名字尾碼
 71 //                    NSString*suffix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonSuffixProperty));
 72 //                    //獲取當前聯繫人的昵稱
 73 //                    NSString*nickName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNicknameProperty));
 74 //                    //獲取當前聯繫人的名字拼音
 75 //                    NSString*firstNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonFirstNamePhoneticProperty));
 76 //                    //獲取當前聯繫人的姓氏拼音
 77 //                    NSString*lastNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonLastNamePhoneticProperty));
 78 //                    //獲取當前聯繫人的中間名拼音
 79 //                    NSString*middleNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNamePhoneticProperty));
 80 //                    //獲取當前聯繫人的公司
 81 //                    NSString*organization=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonOrganizationProperty));
 82 //                    //獲取當前聯繫人的職位
 83 //                    NSString*job=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonJobTitleProperty));
 84 //                    //獲取當前聯繫人的部門
 85 //                    NSString*department=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonDepartmentProperty));
 86 //                    //獲取當前聯繫人的生日
 87 //                    NSString*birthday=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonBirthdayProperty));
 88 //                    NSMutableArray * emailArr = [[NSMutableArray alloc]init];
 89 //                    //獲取當前聯繫人的郵箱 註意是數組
 90 //                    ABMultiValueRef emails= ABRecordCopyValue(people, kABPersonEmailProperty);
 91 //                    for (NSInteger j=0; j<ABMultiValueGetCount(emails); j++) {
 92 //                        [emailArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, j))];
 93 //                    }
 94 //                    //獲取當前聯繫人的備註
 95 //                    NSString*notes=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNoteProperty));
 96 //                    //獲取當前聯繫人的電話 數組
 97 //                    NSMutableArray * phoneArr = [[NSMutableArray alloc]init];
 98 //                    ABMultiValueRef phones= ABRecordCopyValue(people, kABPersonPhoneProperty);
 99 //                    for (NSInteger j=0; j<ABMultiValueGetCount(phones); j++) {
100 //                        [phoneArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j))];
101 //                    }
102 //                    //獲取創建當前聯繫人的時間 註意是NSDate
103 //                    NSDate*creatTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonCreationDateProperty));
104 //                    //獲取最近修改當前聯繫人的時間
105 //                    NSDate*alterTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonModificationDateProperty));
106 //                    //獲取地址
107 //                    ABMultiValueRef address = ABRecordCopyValue(people, kABPersonAddressProperty);
108 //                    for (int j=0; j<ABMultiValueGetCount(address); j++) {
109 //                        //地址類型
110 //                        NSString * type = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(address, j));
111 //                        NSDictionary * temDic = (__bridge NSDictionary *)(ABMultiValueCopyValueAtIndex(address, j));
112 //                        //地址字元串,可以按需求格式化
113 //                        NSString * adress = [NSString stringWithFormat:@"國家:%@\n省:%@\n市:%@\n街道:%@\n郵編:%@",[temDic valueForKey:(NSString*)kABPersonAddressCountryKey],[temDic valueForKey:(NSString*)kABPersonAddressStateKey],[temDic valueForKey:(NSString*)kABPersonAddressCityKey],[temDic valueForKey:(NSString*)kABPersonAddressStreetKey],[temDic valueForKey:(NSString*)kABPersonAddressZIPKey]];
114 //                    }
115 //                    //獲取當前聯繫人頭像圖片
116 //                    NSData*userImage=(__bridge NSData*)(ABPersonCopyImageData(people));
117 //                    //獲取當前聯繫人紀念日
118 //                    NSMutableArray * dateArr = [[NSMutableArray alloc]init];
119 //                    ABMultiValueRef dates= ABRecordCopyValue(people, kABPersonDateProperty);
120 //                    for (NSInteger j=0; j<ABMultiValueGetCount(dates); j++) {
121 //                        //獲取紀念日日期
122 //                        NSDate * data =(__bridge NSDate*)(ABMultiValueCopyValueAtIndex(dates, j));
123 //                        //獲取紀念日名稱
124 //                        NSString * str =(__bridge NSString*)(ABMultiValueCopyLabelAtIndex(dates, j));
125 //                        NSDictionary * temDic = [NSDictionary dictionaryWithObject:data forKey:str];
126 //                        [dateArr addObject:temDic];
127 //                    }
128                 }
129                 
130                 
131             }
132             //發送一次信號
133             dispatch_semaphore_signal(sema);
134         });
135         //等待信號觸發
136         dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
137     }else{
138         
139         //IOS6之前
140         addBook =ABAddressBookCreate();
141         
142         //獲取所有聯繫人的數組
143         CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);
144         //獲取聯繫人總數
145         CFIndex number = ABAddressBookGetPersonCount(addBook);
146         //進行遍歷
147         for (NSInteger i=0; i<number; i++) {
148             //獲取聯繫人對象的引用
149             ABRecordRef  people = CFArrayGetValueAtIndex(allLinkPeople, i);
150             //獲取當前聯繫人名字
151             NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
152             
153             if ([firstName isEqualToString:[_infoDictionary objectForKey:@"name"]]) {
154                 isExist = YES;
155             }
156         }
157     }
158     
159     if (tip) {
160         //設置提示
161         if (IS_iOS8) {
162             UIAlertController *tipVc  = [UIAlertController alertControllerWithTitle:@"友情提示" message:@"請您設置允許APP訪問您的通訊錄\nSettings>General>Privacy" preferredStyle:UIAlertControllerStyleAlert];
163             UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
164                 [self dismissViewControllerAnimated:YES completion:nil];
165             }];
166             [tipVc addAction:cancleAction];
167             [tipVc presentViewController:tipVc animated:YES completion:nil];
168         }else{
169             UIAlertView * alart = [[UIAlertView alloc]initWithTitle:@"友情提示" message:@"請您設置允許APP訪問您的通訊錄\nSettings>General>Privacy" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
170             [alart show];
171             //非ARC
172 //            [alart release];
173         }
174     }
175     return isExist;
176 }
177 
178 //創建新的聯繫人
179 - (void)creatNewRecord
180 {
181     CFErrorRef error = NULL;
182     
183     //創建一個通訊錄操作對象
184     ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
185     
186     //創建一條新的聯繫人紀錄
187     ABRecordRef newRecord = ABPersonCreate();
188     
189     //為新聯繫人記錄添加屬性值
190     ABRecordSetValue(newRecord, kABPersonFirstNameProperty, (__bridge CFTypeRef)[_infoDictionary objectForKey:@"name"], &error);
191     
192     //創建一個多值屬性(電話)
193     ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType);
194     ABMultiValueAddValueAndLabel(multi, (__bridge CFTypeRef)[_infoDictionary objectForKey:@"phone"], kABPersonPhoneMobileLabel, NULL);
195     ABRecordSetValue(newRecord, kABPersonPhoneProperty, multi, &error);
196     
197     //添加email
198     ABMutableMultiValueRef multiEmail = ABMultiValueCreateMutable(kABMultiStringPropertyType);
199     ABMultiValueAddValueAndLabel(multiEmail, (__bridge CFTypeRef)([_infoDictionary objectForKey:@"email"]), kABWorkLabel, NULL);
200     ABRecordSetValue(newRecord, kABPersonEmailProperty, multiEmail, &error);
201     
202     
203     //添加記錄到通訊錄操作對象
204     ABAddressBookAddRecord(addressBook, newRecord, &error);
205     
206     //保存通訊錄操作對象
207     ABAddressBookSave(addressBook, &error);
208     
209     //通過此介面訪問系統通訊錄
210     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
211         
212         if (granted) {
213             //顯示提示
214             if (IS_iOS8) {

              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 估計他們上完課就再也不玩了,自己那段時間上完課。也就基本上很少來了,主要是 沒有什麼記錄的習慣,奇怪的是,每每到了心情不好的時候,總會想要寫點什麼。 不管怎麼樣還是出去花錢學習了一下,這段經歷。嗯,很難評價,事實上如果不留下一筆,那麼的確沒有什麼學習的意義。 所以,李飛要一點兒一點兒扳過來。 出去學
  • 本文是一個jdk.locks系列主題的頭篇,總體介紹JDK中Lock底層框架以及JDK中藉助該框架實現的各種同步手段。瞭解JDK基本的併發與同步的實現,對java併發編程更得心應手!
  • 在AOP中有幾個概念: — 方面(Aspect):一個關註點的模塊化,這個關註點實現可能另外橫切多個對象。事務管理是J2EE應用中一個很好的橫切關註點例子。方面用Spring的Advisor或攔截器實現。 — 連接點(Joinpoint):程式執行過程中明確的點,如方法的調用或特定的異常被拋出。 —
  • Spring 的優秀工具類盤點---轉 第 1 部分: 文件資源操作和 Web 相關工具類 http://www.ibm.com/developerworks/cn/java/j-lo-spring-utils1/ 文件資源操作 文件資源的操作是應用程式中常見的功能,如當上傳一個文件後將其保存在特定
  • 題目概要 : 四則運算題目生成 http://www.cnblogs.com/jiel/p/4810756.html github 地址 : https://github.com/YooRarely/object oriented.git 程式結構 : get_int 類 輸出整型答案(強制整型)
  • CocoaPods是什麼? 當你開發iOS應用時,會經常使用到很多第三方開源類庫,比如JSONKit,AFNetWorking等等。可能某個類庫又用到其他類庫,所以要使用它,必須得另外下載其他類庫,周而複始,可見手動一個個去下載所需類庫十分麻煩。另外一種常見情況是,你項目中用到的類庫有更新,你必須得
  • 第四組UI組件:AdapterView及其子類 AdapterView組件是一組重要的組件,AdapterView本身是一個抽象基類,它派生的子類在用法上十分相似,只是顯示界面有些不同。 繼承了ViewGroup,本質是容器,可以包括多個“列表項”。 顯示的多個“列表項”由Adapter提供,調用A
  • 安裝: Git客戶端網址:http://git-scm.com/download/ 根據自己的使用平臺下載對應的客戶端。這裡以Mac系統為例,當客戶端軟體安裝配置完畢後,打開AS的配置面板,找到Git的選項 在右邊的 Path to Git executable 找到Git的可執行程式,點擊右邊的T
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...