zoukankan      html  css  js  c++  java
  • iOS -------- 应用程序引用系统通讯录

    转自:http://www.cnblogs.com/ygm900/p/3472288.html

    由于ios系统对用户隐私的控制,第三方应用程序只能通过苹果官方接口调用系统通讯录,不能像android那样直接操作通讯录数据库。
         一般地,使用系统自带通讯录的方法有两种,一种是直接将整个通讯录引入到应用程序,另一种是逐条读取通讯录中的每一条联系人信息。下面我们就一一详解。

    1 直接引用整个通讯录

    使用的类:ABPeoplePickerNavigationController
    方法:

    复制代码
    在LocalAddressBookController.h文件中
    #import <UIKit/UIKit.h>
    #import <AddressBook/AddressBook.h>
    #import <AddressBookUI/AddressBookUI.h>
    @interface LocalAddressBookController : UIViewController<ABPersonViewControllerDelegate,ABPeoplePickerNavigationControllerDelegate,ABNewPersonViewControllerDelegate>
    {
        ABPeoplePickerNavigationController *picker;
        ABNewPersonViewController *personViewController;
    }
    @end
    
    在LocalAddressBookController.m文件中
    #import "LocalAddressBookController.h"
    #import "PublicHeader.h"
    
    @implementation LocalAddressBookController
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)didReceiveMemoryWarning
    {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
        
        // Release any cached data, images, etc that aren't in use.
    }
    
    #pragma mark - View lifecycle
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        picker = [[ABPeoplePickerNavigationController alloc]init];
        picker.view.frame = CGRectMake(0, 0, Screen_width, Screen_height-48);
        picker.peoplePickerDelegate = self;
        picker.delegate = self;                   //为了隐藏右上角的“取消”按钮
        [picker setHidesBottomBarWhenPushed:YES];
        [picker setNavigationBarHidden:NO animated:NO];//显示上方的NavigationBar和搜索框
        [self.view addSubview:picker.view];
    }
    
    #pragma mark UINavigationControllerDelegate methods
    //隐藏“取消”按钮
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f,0.0f,0.0f)];
        UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:custom];
        [viewController.navigationItem setRightBarButtonItem:btn animated:NO];
        [btn release];
        [custom release];
    }
    
    #pragma mark - peoplePickerDelegate Methods
    -(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
    {
    //    [picker setNavigationBarHidden:NO animated:NO];
        NSLog(@"%@", (NSString*)ABRecordCopyCompositeName(person)); 
        return YES;
    }
    -(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
    {
        
        return YES;
    }
    -(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
        return YES;
    }
     
    //“取消”按钮的委托响应方法
    -(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
    {
        //assigning control back to the main controller
        [picker dismissModalViewControllerAnimated:YES];
    }
    
    //……
    @end
    复制代码

    ios6 运行效果:

    ios7 运行效果:

    经验:

    当我们将系统通讯录整个引入的时候,在通讯录的右上角有一个系统自带的“取消”按钮。如何才能将这个取消按钮隐藏呢?

    (1)方法1:如果你的应用程序是用企业证书开发,不需要提交到appStore进行审核,那么答案非常简单,为响应的piker增加如下代码即可:

    [picker setAllowsCancel:NO];

    (2)方法二:上面的方法是非公开方法,是无法通过appStore审核的。如果想通过审核。可以尝试使用如下方法:

    复制代码
    前提:设置 picker.delegate = self;
    然后实现如下委托方法
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
      UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f,0.0f,0.0f)]; 
      UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:custom]; 
      //UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction)]; 
      [viewController.navigationItem setRightBarButtonItem:btn animated:NO]; 
      [btn release]; 
      [custom release]; 
    }
    复制代码

    或者:(比上面更好)

    复制代码
    前提:设置 picker.delegate = self;
    然后实现如下委托方法,下面实现的效果,要比上面的好。上面实现的效果,当点击“搜索”框时,“取消”按钮还会重新出现。
    - (void)navigationController:(UINavigationController *)navigationController
          willShowViewController:(UIViewController *)viewController
                        animated:(BOOL)animated {
        
        // Here we want to remove the 'Cancel' button, but only if we're showing
        // either of the ABPeoplePickerNavigationController's top two controllers
        if ([navigationController.viewControllers indexOfObject:viewController] <= 1) {
            viewController.navigationItem.rightBarButtonItem = nil;
        }
    }
    复制代码

    2、逐条读取通讯录中的每一条联系人信息。

    方法:在上述类中,直接添加如下方法即可

    复制代码
    在LocalAddressBookController.h文件中
    #import <UIKit/UIKit.h>
    #import <AddressBook/AddressBook.h>
    #import <AddressBookUI/AddressBookUI.h>
    @interface LocalAddressBookController : 
    {
        UITextView *textView;
    }
    @end
    
    在LocalAddressBookController.m文件中
    #import "LocalAddressBookController.h"
    #import "PublicHeader.h"
    
    @implementation LocalAddressBookController
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)didReceiveMemoryWarning
    {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
        
        // Release any cached data, images, etc that aren't in use.
    }
    
    #pragma mark - View lifecycle
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];    
        textView = [[UITextView alloc]initWithFrame:CGRectMake(0, 0, Screen_width, Screen_height)];
        [self getAddressBook];
        [self.view addSubview:textView];
    }
    
    //获取通讯录中的所有属性,并存储在 textView 中,已检验,切实可行。兼容io6 和 ios 7 ,而且ios7还没有权限确认提示。
    -(void)getAddressBook
    {
        ABAddressBookRef addressBook = ABAddressBookCreate();
        
        CFArrayRef results = ABAddressBookCopyArrayOfAllPeople(addressBook);
        
        for(int i = 0; i < CFArrayGetCount(results); i++)
        {
            ABRecordRef person = CFArrayGetValueAtIndex(results, i);
            //读取firstname
            NSString *personName = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
            if(personName != nil)
                textView.text = [textView.text stringByAppendingFormat:@"
    姓名:%@
    ",personName];
            //读取lastname
            NSString *lastname = (NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
            if(lastname != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",lastname];
            //读取middlename
            NSString *middlename = (NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty);
            if(middlename != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",middlename];
            //读取prefix前缀
            NSString *prefix = (NSString*)ABRecordCopyValue(person, kABPersonPrefixProperty);
            if(prefix != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",prefix];
            //读取suffix后缀
            NSString *suffix = (NSString*)ABRecordCopyValue(person, kABPersonSuffixProperty);
            if(suffix != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",suffix];
            //读取nickname呢称
            NSString *nickname = (NSString*)ABRecordCopyValue(person, kABPersonNicknameProperty);
            if(nickname != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",nickname];
            //读取firstname拼音音标
            NSString *firstnamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty);
            if(firstnamePhonetic != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",firstnamePhonetic];
            //读取lastname拼音音标
            NSString *lastnamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty);
            if(lastnamePhonetic != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",lastnamePhonetic];
            //读取middlename拼音音标
            NSString *middlenamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonMiddleNamePhoneticProperty);
            if(middlenamePhonetic != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",middlenamePhonetic];
            //读取organization公司
            NSString *organization = (NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
            if(organization != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",organization];
            //读取jobtitle工作
            NSString *jobtitle = (NSString*)ABRecordCopyValue(person, kABPersonJobTitleProperty);
            if(jobtitle != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",jobtitle];
            //读取department部门
            NSString *department = (NSString*)ABRecordCopyValue(person, kABPersonDepartmentProperty);
            if(department != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",department];
            //读取birthday生日
            NSDate *birthday = (NSDate*)ABRecordCopyValue(person, kABPersonBirthdayProperty);
            if(birthday != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",birthday];
            //读取note备忘录
            NSString *note = (NSString*)ABRecordCopyValue(person, kABPersonNoteProperty);
            if(note != nil)
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",note];
            //第一次添加该条记录的时间
            NSString *firstknow = (NSString*)ABRecordCopyValue(person, kABPersonCreationDateProperty);
            NSLog(@"第一次添加该条记录的时间%@
    ",firstknow);
            //最后一次修改該条记录的时间
            NSString *lastknow = (NSString*)ABRecordCopyValue(person, kABPersonModificationDateProperty);
            NSLog(@"最后一次修改該条记录的时间%@
    ",lastknow);
            
            //获取email多值
            ABMultiValueRef email = ABRecordCopyValue(person, kABPersonEmailProperty);
            int emailcount = ABMultiValueGetCount(email);
            for (int x = 0; x < emailcount; x++)
            {
                //获取email Label
                NSString* emailLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(email, x));
                //获取email值
                NSString* emailContent = (NSString*)ABMultiValueCopyValueAtIndex(email, x);
                textView.text = [textView.text stringByAppendingFormat:@"%@:%@
    ",emailLabel,emailContent];
            }
            //读取地址多值
            ABMultiValueRef address = ABRecordCopyValue(person, kABPersonAddressProperty);
            int count = ABMultiValueGetCount(address);
            
            for(int j = 0; j < count; j++)
            {
                //获取地址Label
                NSString* addressLabel = (NSString*)ABMultiValueCopyLabelAtIndex(address, j);
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",addressLabel];
                //获取該label下的地址6属性
                NSDictionary* personaddress =(NSDictionary*) ABMultiValueCopyValueAtIndex(address, j);
                NSString* country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey];
                if(country != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"国家:%@
    ",country];
                NSString* city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey];
                if(city != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"城市:%@
    ",city];
                NSString* state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey];
                if(state != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"省:%@
    ",state];
                NSString* street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey];
                if(street != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"街道:%@
    ",street];
                NSString* zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey];
                if(zip != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"邮编:%@
    ",zip];
                NSString* coutntrycode = [personaddress valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
                if(coutntrycode != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"国家编号:%@
    ",coutntrycode];
            }
            
            //获取dates多值
            ABMultiValueRef dates = ABRecordCopyValue(person, kABPersonDateProperty);
            int datescount = ABMultiValueGetCount(dates);
            for (int y = 0; y < datescount; y++)
            {
                //获取dates Label
                NSString* datesLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(dates, y));
                //获取dates值
                NSString* datesContent = (NSString*)ABMultiValueCopyValueAtIndex(dates, y);
                textView.text = [textView.text stringByAppendingFormat:@"%@:%@
    ",datesLabel,datesContent];
            }
            //获取kind值
            CFNumberRef recordType = ABRecordCopyValue(person, kABPersonKindProperty);
            if (recordType == kABPersonKindOrganization) {
                // it's a company
                NSLog(@"it's a company
    ");
            } else {
                // it's a person, resource, or room
                NSLog(@"it's a person, resource, or room
    ");
            }
            
            
            //获取IM多值
            ABMultiValueRef instantMessage = ABRecordCopyValue(person, kABPersonInstantMessageProperty);
            for (int l = 1; l < ABMultiValueGetCount(instantMessage); l++)
            {
                //获取IM Label
                NSString* instantMessageLabel = (NSString*)ABMultiValueCopyLabelAtIndex(instantMessage, l);
                textView.text = [textView.text stringByAppendingFormat:@"%@
    ",instantMessageLabel];
                //获取該label下的2属性
                NSDictionary* instantMessageContent =(NSDictionary*) ABMultiValueCopyValueAtIndex(instantMessage, l);
                NSString* username = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageUsernameKey];
                if(username != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"username:%@
    ",username];
                
                NSString* service = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageServiceKey];
                if(service != nil)
                    textView.text = [textView.text stringByAppendingFormat:@"service:%@
    ",service];
            }
            
            //读取电话多值
            ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
            for (int k = 0; k<ABMultiValueGetCount(phone); k++)
            {
                //获取电话Label
                NSString * personPhoneLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phone, k));
                //获取該Label下的电话值
                NSString * personPhone = (NSString*)ABMultiValueCopyValueAtIndex(phone, k);
                
                textView.text = [textView.text stringByAppendingFormat:@"%@:%@
    ",personPhoneLabel,personPhone];
            }
            
            //获取URL多值
            ABMultiValueRef url = ABRecordCopyValue(person, kABPersonURLProperty);
            for (int m = 0; m < ABMultiValueGetCount(url); m++)
            {
                //获取电话Label
                NSString * urlLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(url, m));
                //获取該Label下的电话值
                NSString * urlContent = (NSString*)ABMultiValueCopyValueAtIndex(url,m);
                
                textView.text = [textView.text stringByAppendingFormat:@"%@:%@
    ",urlLabel,urlContent];
            }
            
            //读取照片
            NSData *image = (NSData*)ABPersonCopyImageData(person);
            
            
            UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(200, 0, 50, 50)];
            [myImage setImage:[UIImage imageWithData:image]];
            myImage.opaque = YES;
            [textView addSubview:myImage];
        }
        
        CFRelease(results);
        CFRelease(addressBook);
    }
    //……
    @end
    复制代码

    ios7运行效果:

    参考:

    想扩展右上角“取消”按钮的可以看  http://d2100.com/questions/6864

    隐藏右上角“取消”按钮的方法 (有可行代码)   http://stackoverflow.com/questions/1611499/abpeoplepickernavigationcontroller-remove-cancel-button-without-using-privat

    如何使用ios addressBook 总结的很全面,有概括性 http://www.cnblogs.com/y041039/archive/2012/03/22/2411771.html

  • 相关阅读:
    mysql之四.表介绍
    mysql之三.mysql的工作流程
    mysql之二.mysql中的存储引擎
    mysql之一.初识mysql
    数据及表结构的导出
    迭代器和生成器
    python字符串格式化的几种方式
    关于global 和 nonlocal你需要注意的问题
    请编写一个函数实现将IP地址转换成一个整数
    Python中__repr__和__str__区别
  • 原文地址:https://www.cnblogs.com/sharkHZ/p/4983766.html
Copyright © 2011-2022 走看看