在程序中集成地址簿、电子邮件和地图功能

地址簿

iOS通过两个框架提供了全面的地址簿数据库访问功能:Address Book和Address Book UI。

Address Book UI框架是一组用户界面类,封装了Address Book框架,并向用户提供了使用联系人信息的标准方式。通过使用Address Book UI框架的界面,用户可以在地址薄中浏览、搜索和选择联系人,显示并编辑选定联系人的信息,以及创建新的联系人。

要使用框架Address Book UI,需要将其加入到项目中,并导入其接口文件:

#import <AddressBook/AddressBook.h>

ABPeoplePickerNavigationController类提供一个显示地址薄UI的视图控制器,使用方法如下:

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];

picker.peoplePickerDelegate = self;

[self presentViewController:picker animated:YES completion:nil];

显示地址簿后,需要处理用户的选择;主要通过实现委托ABPeoplePickerNavigationControllerDelegate的三个方法:

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier

第一个方法处理用户的取消操作。

第二个方法处理用户的第一次选择,在这个方法里可以获取用户的所有信息集合;当这个方法返回YES,将允许用户进一步选择。

第三个方法处理用户的第二次选择,在这个方法里可以获取用户选择的单项;当这个方法返回YES,将允许用户进一步选择。

在项目中使用地址簿示例:

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/ABPeoplePickerNavigationController.h>

@interface ViewController : UIViewController <ABPeoplePickerNavigationControllerDelegate>

@end

 

#import "ViewController.h"

@interface ViewController ()
- (IBAction)btnTestClickHandler:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)btnTestClickHandler:(id)sender
{
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];

    picker.peoplePickerDelegate = self;

    [self presentViewController:picker animated:YES completion:nil];
}

//取消选择
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

//一次触发
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    //first name
    NSString *strFirstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSLog(@"first name: %@",strFirstName);
    
    //email
    ABMultiValueRef emailAddresses = ABRecordCopyValue(person, kABPersonEmailProperty);
    
    if(ABMultiValueGetCount(emailAddresses)>1)
    {
        NSString *strSecondEmail = (__bridge NSString *)ABMultiValueCopyValueAtIndex(emailAddresses, 1);
        NSLog(@"第二个Email: %@",strSecondEmail);
    }
    
    //phone number
    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
    
    NSString *strPhone = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
    NSLog(@"电话号码:%@",strPhone);
    
    return YES;
}

//二次触发
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    if(property == kABPersonPhoneProperty)
    {
        NSLog(@"你选择的是电话号码");
    }
    
    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, property);
    
    for(CFIndex i=0; i<ABMultiValueGetCount(phoneNumbers); i++)
    {
        if(identifier == ABMultiValueGetIdentifierAtIndex(phoneNumbers, i))
        {
            NSString *strPhone = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, i);
            NSLog(@"你选择的内容:%@",strPhone);
        }
    }
    return NO;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 

电子邮件

在项目里使用框架Message UI可以很方便的发送电子邮件,只需要初始化一个MFMailComposeViewController对象来显示发邮件的界面就可以了,具体发送操作由iOS自动完成。

需要遵守一个协议:MFMailComposeViewControllerDelegate。该协议定义了一个清理方法:mailComposeController:didFinishWithResult:error,将在用户使用完邮件书写窗口后被调用。在大多数情况下,这个方法只需关闭邮件书写视图控制器即可。如果想进一步获悉邮件书写视图关闭的原因,可查看result(其类型为MFMailComposeResult)的值。其取值为下述常量之一:

MFMailComposeResultCancelledMFMailComposeResultSavedMFMailComposeResultSentMFMailComposeResultFailed

在项目中发送电子邮件示例:

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

@interface ViewController : UIViewController <UINavigationControllerDelegate, MFMailComposeViewControllerDelegate>

@end

 

#import "ViewController.h"

@interface ViewController ()
- (IBAction)btnTestClickHandler:(id)sender;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)btnTestClickHandler:(id)sender
{
    MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
    
    NSArray *emailAddresses = [[NSArray alloc] initWithObjects:@"me@qq.com", nil];
    
    mailComposer.delegate = self;
    
    [mailComposer setToRecipients:emailAddresses];
    
    [self presentViewController:mailComposer animated:YES completion:nil];
}

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog(@"Mail cancelled");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"Mail saved");
            break;
        case MFMailComposeResultSent:
            NSLog(@"Mail sent");
            break;
        case MFMailComposeResultFailed:
            NSLog(@"Mail sent failure: %@", [error localizedDescription]);
            break;
        default:
            break;
    }
    
    // Close the Mail Interface
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 

地图功能

通过使用iOS的Map Kit,可以将地图嵌入到视图中,并提供显示该地图所需的所有图块(图像)。它在需要时处理滚动、缩放和图块加载。Map Kit还能执行反向地理编码(reverse geocoding),即根据坐标获取位置信息(国家、州、城市、地址)。

无需编写任何代码就可使用Map Kit — 只需在Interface Builder将一个MKMapView实例加入到视图中,并可在Attributes Inspector中设置多个属性以进一步定制它。记得需要添加链接库MapKit.framework。

如果要以编程方式控制地图,首先需要导入框架Map Kit的接口文件:

#import <MapKit/MapKit.h>

需要操纵地图时,大多数情况下都需要添加框架Core Location并导入其接口文件:

#import <CoreLocation/CoreLocation.h>

还需要定义一个地图区域。区域(region)是一个MKCoordinateRegion结构(而不是对象),它包含成员center和span。

center — CLLocationCoordinate2D结构,包含成员longitude(经度)和latitude(纬度)。

span — 指定从中心出发向东西南北延伸多少度。一个纬度相当于69英里;在赤道上,一个经度也相当于69英里。通过将区域的跨度(span)设置为较小的值,如0.2,可将地图的覆盖范围缩小到绕重点几英里。

MKCoordinateRegion mapRegion;
mapRegion.center.longitude = 90.0;
mapRegion.center.latitude = 33.0;
mapRegion.span.longitudeDelta = 0.2;
mapRegion.span.latitudeDelta = 0.2;
[self.myMap setRegion:mapRegion animated:YES];

在应用程序中可以给地图添加标注,通常需要实现一个MKAnnotaion View子类,它描述了标注的外观以及应显示的信息。

对于加入到地图中的每个标注,都需要一个描述其位置的地点标识对象(MKPlaceMark)。

//设置标记
CLLocationCoordinate2D myCoordinate;
myCoordinate.longitude = 90.0;
myCoordinate.latitude = 33.0;

MKPlacemark *myMarker = [[MKPlacemark alloc] initWithCoordinate:myCoordinate addressDictionary:self.myAddress];
[self.myMap addAnnotation:myMarker];
//删除标记
//[self.myMap removeAnnotation:myMarker];

上面的代码的myAddress来自@property (nonatomic, readonly) NSDictionary *myAddress;这里只简单的声明了引用,实际应用中可能是从地址簿条目中获取的(通过邮编得到经纬度),也可能是根据ASPerson参考文档中Address属性的定义手工创建的。

添加标注时,iOS自动完成其他工作。Apple提供了一个MKAnnotationView子类—MKPinAnnotationView。当您添加标记时,iOS自动创建一个MKPinAnnotationView实例(一颗图钉),如果要定制图钉,必须实现地图视图的委托方法mapView:viewForAnnotation:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myspot"];
    
    pin.animatesDrop = YES;  //是否以动画方式出现
    pin.canShowCallout = YES; //触摸时,是否能显示额外信息
    pin.pinColor = MKPinAnnotationColorPurple; //图标颜色
    return pin;
}

需要设置MKMapView实例的delegate属性才能生效。

posted @ 2014-06-10 17:26  CoderWayne  阅读(741)  评论(0编辑  收藏  举报