为什么发送邮件时如何抄送同一个联系人突然增加好几个

我用outlook邮箱,已经把来联系人的邮箱都添加到了通讯簿,也有名字,可是为什么发邮件给我的时候还是显示_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
我用outlook邮箱,已经把来联系人的邮箱都添加到了通讯簿,也有名字,可是为什么发邮件给我的时候还是显示
我用outlook邮箱,已经把来联系人的邮箱都添加到了通讯簿,也有名字,可是为什么发邮件给我的时候还是显示邮箱,而不是显示联系人的名字,向各位大虾求教
我有更好的答案
。比如你设置为这很正常啊。还记不记得你设置邮箱账户的时候第一个步骤就是设置显示名字:此处将会让你发送的邮件显示在对方上的名字。。windows还有详细介绍说明:jack那么由你发送的所有邮件在对方的收件箱里发件人都会显示为jack它不会因为你的通讯录而发送改变。
我说的是对方的邮件在我的邮箱里不显示名字,只显示邮箱地址
那就是对方没设置显示名字呗。。。你可以自己试验一下的,很快就可以明白我说的是不是真的!
采纳率:28%
com/zhidao/wh%3D600%2C800/sign=b80dddeb9beafc4bfb267e/b219ebc4bdc824f1e178a82b8011469.jpg" esrc="http://b.hiphotos./zhidao/pic/item/b219ebc4bdc824f1e178a82b8011469;&<img class="ikqb_img" src="http://b.要添加一个名为“电子邮件显示为”的列&nbsp://b;添加方法outlook2007&nbsp.baidu
为您推荐:
其他类似问题
发邮件的相关知识
等待您来回答7被浏览842分享邀请回答/tagit/16 条评论分享收藏感谢收起0添加评论分享收藏感谢收起写回答怎么在Win7系统电脑上创建“联系人”快速发送邮件的方法【图文】-系统城·电脑系统下载之家
当前位置: &
& 怎么在Win7系统电脑上创建“联系人”快速发送邮件的方法【图文】
怎么在Win7系统电脑上创建“联系人”快速发送邮件的方法【图文】
&&&&很多用户由于工作需要常常会需要发送邮件,你还每次都需先登陆邮箱来发送吗,那效率就低了,为了帮助用户快速发送邮件,现小编以为例,给大家介绍创建“联系人”功能实现快速发送邮件的方法!操作步骤:1、在win7系统桌面空白处右键选择“新建——联系人”选项。2、在打开的窗口中,填入联系人的姓名、电子邮件地址等详细信息,还可放联系人的头像上去,然后点击“添加”按钮,这样联系人就添加好了。&3、到网上下载live&mail软件并根据提示安装在电脑上,启动Windows&Live&Mail的时候,会弹出“添加电子邮件帐户”的向导窗口,然后直接在向导窗口中把自己的信息,之后点击“下一步”。4、打开控制面板,然后找到“默认程序”中的“设置默认程序”,在左侧弹出的“程序”列表框中单击“Windwos&Live&Mail”选项,然后单击“将此程序设置为默认值”,点击确定即可。& & & 通过以上设置后,返回到桌面就可看到桌面生成了一个联系人的图标,双击联系人图标,打开点击发送“电子邮件”,在弹出来的页面中就可直接编辑内容,给联系人快捷发送邮件了,操作非常便捷简单。更多精彩内容欢迎继续关注系统城官网!
我要分享:
怎么在Win7系统电脑上创建“联系人”快速发送邮件的方法【图文】相关教程
热&门推&荐
&热门教程推荐
12345678910
&热门系统专题
&Win7系统推荐
&|&&|&本站发布的系统与软件仅为个人学习测试使用,请在下载后24小时内删除,不得用于任何商业用途,否则后果自负,请支持购买微软正版软件!
如侵犯到您的权益,请及时通知我们,我们会及时处理。
Copyright @ 2011 系统城为什么我会收到这一“联系人记录Whois验证”电子邮件以及它是什么?
联络记录Whois验证邮件,以及与此相似的邮件,都是(互联网名称与数字地址分配机构)新规定的一部分。该规定于我站签署时起生效。基本上讲,您须要验证任何与通用顶级域(gTLD)关联的联络信息,例如。该电子邮件将在以下时间发出:您并选择它作为的相关记录您,该记录被设为您的一个或多个gTLD的相关记录您购买了将会使用您的的gTLD且该记录未被验证编辑联络记录时,在您点击“保存联络信息”后就可看到联络记录Whois验证邮件是否已经发出。如果已经发出,则会在“gTLD验证”区域有所显示。您也可以在此选择。您可访问Dynadot账户中的“域名”下拉菜单中的“联络记录”查看您的Whois联络记录是否已被验证。请看最右端一栏的“通用顶级域(gTLD)验证”,而如果联络记录已被验证,则您会看到“是”;如果未验证,且不需验证(这种情况可能出现,因为该联络记录尚未被任何TLD使用,或被一个非gTLD使用),则显示为“否”;或显示为“验证中”,即联络记录Whois验证邮件已发送给您,且您需要完成验证。请看以下示例(点击放大):您也可以在自己的Dynadot账户的通知区域查看是否有Whois验证通知。您还可以在该区域通过我站的账户信息Whois验证邮件(下列示例第二行)查看是否需要对账户信息进行验证。如果您未能在街道联络记录Whois验证邮件内15日验证您的Whois联络记录,则将不能对其进行管理。这就是说,在联络信息验证前,您将无法或。更多信息:,
推荐给朋友我们的论坛是您提出有关域名及网站问题的完美场所
关注Dynadot动态,获得小窍门、信息及超值产品吧,更多信息请关注我们的博客!
与Dynadot专家取得联系,即刻解答您的问题
域名网站资源顶级域名国家域名iOS之短信,邮件,通信录技术的完美实现
今天给大家详细介绍一下iOS之短信,邮件,通信录技术的具体实现
1. 系统应用之短信,邮件
在开发某些应用时可能希望能够调用iOS系统内置的电话、短信、邮件、应用,此时你可以直接使用UIApplication的OpenURL:方法指定特定的协议来打开不同的系统应用。常用的协议如下:
打电话:tel:或者tel://、telprompt:或telprompt://(拨打电话前有提示)
发短信:sms:或者sms://
发送邮件:mailto:或者mailto://
启动浏览器:http:或者https://
下面以一个简单的demo演示如何调用上面几种系统应用:
#import &ViewController.h&
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
#pragma mark - UI事件
- (IBAction)callClicK:(UIButton *)sender {
NSString *phoneNumber=@&&;
NSString *url=[NSString stringWithFormat:@&tel://%@&,phoneNumber];//这种方式会直接拨打电话
NSString *url=[NSString stringWithFormat:@&telprompt://%@&,phoneNumber];//这种方式会提示用户确认是否拨打电话
[self openUrl:url];
//发送短信
- (IBAction)sendMessageClick:(UIButton *)sender {
NSString *phoneNumber=@&&;
NSString *url=[NSString stringWithFormat:@&sms://%@&,phoneNumber];
[self openUrl:url];
//发送邮件
- (IBAction)sendEmailClick:(UIButton *)sender {
NSString *mailAddress=@&&;
NSString *url=[NSString stringWithFormat:@&mailto://%@&,mailAddress];
[self openUrl:url];
//浏览网页
- (IBAction)browserClick:(UIButton *)sender {
NSString *url=@&/kenshincui&;
[self openUrl:url];
#pragma mark - 私有方法
-(void)openUrl:(NSString *)urlStr{
//注意url中包含协议名称,iOS根据协议确定调用哪个应用,例如发送邮件是&sms://&其中&//&可以省略写成&sms:&(其他协议也是如此)
NSURL *url=[NSURL URLWithString:urlStr];
UIApplication *application=[UIApplication sharedApplication];
if(![application canOpenURL:url]){
NSLog(@&无法打开\&%@\&,请确保此应用已经正确安装.&,url);
[[UIApplication sharedApplication] openURL:url];
不难发现当openURL:方法只要指定一个URL Schame并且已经安装了对应的应用程序就可以打开此应用。当然,如果是自己开发的应用也可以调用openURL方法来打开。假设你现在开发了一个应用A,如果用户机器上已经安装了此应用,并且在应用B中希望能够直接打开A。那么首先需要确保应用A已经配置了Url Types,具体方法就是在plist文件中添加URL types节点并配置URL Schemas作为具体协议,配置URL identifier作为这个URL的唯一标识,如下图
然后就可以调用openURL方法像打开系统应用一样打开第三方应用程序了:
//打开第三方应用
- (IBAction)thirdPartyApplicationClick:(UIButton *)sender {
NSString *url=@&cmj://myparams&;
[self openUrl:url];
就像调用系统应用一样,协议后面可以传递一些参数(例如上面传递的myparams),这样一来在应用中可以在AppDelegate的-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation代理方法中接收参数并解析。
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
NSString *str=[NSString stringWithFormat:@&url:%@,source application:%@,params:%@&,url,sourceApplication,[url host]];
NSLog(@&%@&,str);
return YES;//是否打开
2. 系统服务之短信与邮件
调用系统内置的应用来发送短信、邮件相当简单,但是这么操作也存在着一些弊端:当你点击了发送短信(或邮件)操作之后直接启动了系统的短信(或邮件)应用程序,我们的应用其实此时已经处于一种挂起状态,发送完(短信或邮件)之后无法自动回到应用界面。如果想要在应用程序内部完成这些操作则可以利用iOS中的MessageUI.framework,它提供了关于短信和邮件的UI接口供开发者在应用程序内部调用。从框架名称不难看出这是一套UI接口,提供有现成的短信和邮件的编辑界面,开发人员只需要通过的方式给短信和邮件控制器设置对应的参数即可。
在MessageUI.framework中主要有两个控制器类分别用于发送短信(MFMessageComposeViewController)和邮件(MFMailComposeViewController),它们均继承于UINavigationController。由于两个类使用方法十分类似,这里主要介绍一下MFMessageComposeViewController使用步骤:
创建MFMessageComposeViewController对象。
设置收件人recipients、信息正文body,如果运行商支持主题和附件的话可以设置主题subject、附件attachments(可以通过canSendSubject、canSendAttachments方法判断是否支持)
设置代理messageComposeDelegate(注意这里不是delegate属性,因为delegate属性已经留给UINavigationController,MFMessageComposeViewController没有覆盖此属性而是重新定义了一个代理),实现代理方法获得发送状态。
下面自定义一个发送短信的界面演示MFMessageComposeViewController的使用:
vcew0ru49rbM0MWx4Lyt0rPD5qGjPGJyIC8+DQo8aW1nIGFsdD0="这里写图片描述" src="/uploadfile/Collfiles/.png" title="\" />
实现代码:
KCSendMessageViewController.m
iOSSystemApplication
Created by Kenshin Cui on 14/04/05.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &KCSendMessageViewController.h&
@interface KCSendMessageViewController ()
@property (weak, nonatomic) IBOutlet UITextField *
@property (weak, nonatomic) IBOutlet UITextField *
@property (weak, nonatomic) IBOutlet UITextField *
@property (weak, nonatomic) IBOutlet UITextField *
@implementation KCSendMessageViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
#pragma mark - UI事件
- (IBAction)sendMessageClick:(UIButton *)sender {
//如果能发送文本信息
if([MFMessageComposeViewController canSendText]){
MFMessageComposeViewController *messageController=[[MFMessageComposeViewController alloc]init];
messageController.recipients=[self.receivers.text componentsSeparatedByString:@&,&];
//信息正文
messageController.body=self.body.
//设置代理,注意这里不是delegate而是messageComposeDelegate
messageController.messageComposeDelegate=
//如果运行商支持主题
if([MFMessageComposeViewController canSendSubject]){
messageController.subject=self.subject.
//如果运行商支持附件
if ([MFMessageComposeViewController canSendAttachments]) {
/*第一种方法*/
//messageController.attachments=...;
/*第二种方法*/
NSArray *attachments= [self.attachments.text componentsSeparatedByString:@&,&];
if (attachments.count&0) {
[attachments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *path=[[NSBundle mainBundle]pathForResource:obj ofType:nil];
NSURL *url=[NSURL fileURLWithPath:path];
[messageController addAttachmentURL:url withAlternateFilename:obj];
/*第三种方法*/
NSString *path=[[NSBundle mainBundle]pathForResource:@&photo.jpg& ofType:nil];
NSURL *url=[NSURL fileURLWithPath:path];
NSData *data=[NSData dataWithContentsOfURL:url];
attatchData:文件数据
uti:统一类型标识,标识具体文件类型,详情查看:帮助文档中System-Declared Uniform Type Identifiers
fileName:展现给用户看的文件名称
[messageController addAttachmentData:data typeIdentifier:@&public.image&
filename:@&photo.jpg&];
[self presentViewController:messageController animated:YES completion:nil];
#pragma mark - MFMessageComposeViewController代理方法
//发送完成,不管成功与否
-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{
switch (result) {
case MessageComposeResultSent:
NSLog(@&发送成功.&);
case MessageComposeResultCancelled:
NSLog(@&取消发送.&);
NSLog(@&发送失败.&);
[self dismissViewControllerAnimated:YES completion:nil];
这里需要强调一下:
.1) MFMessageComposeViewController的代理不是通过delegate属性指定的而是通过messageComposeDelegate指定的。
.2) 可以通过几种方式来指定发送的附件,在这个过程中请务必指定文件的后缀,否则在发送后无法正确识别文件类别(例如如果发送的是一张jpg图片,在发送后无法正确查看图片)。
.3) 无论发送成功与否代理方法-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result都会执行,通过代理参数中的result来获得发送状态。
其实只要熟悉了MFMessageComposeViewController之后,那么用于发送邮件的MFMailComposeViewController用法和步骤完全一致,只是功能不同。下面看一下MFMailComposeViewController的使用:
#import &KCSendEmailViewController.h&
@interface KCSendEmailViewController ()
@property (weak, nonatomic) IBOutlet UITextField *toT//收件人
@property (weak, nonatomic) IBOutlet UITextField *ccR//抄送人
@property (weak, nonatomic) IBOutlet UITextField *bccR//密送人
@property (weak, nonatomic) IBOutlet UITextField * //主题
@property (weak, nonatomic) IBOutlet UITextField *//正文
@property (weak, nonatomic) IBOutlet UITextField *//附件
@implementation KCSendEmailViewController
- (void)viewDidLoad {
[super viewDidLoad];
#pragma mark - UI事件
- (IBAction)sendEmailClick:(UIButton *)sender {
//判断当前是否能够发送邮件
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailController=[[MFMailComposeViewController alloc]init];
//设置代理,注意这里不是delegate,而是mailComposeDelegate
mailController.mailComposeDelegate=
//设置收件人
[mailController setToRecipients:[self.toTecipients.text componentsSeparatedByString:@&,&]];
//设置抄送人
if (self.ccRecipients.text.length&0) {
[mailController setCcRecipients:[self.ccRecipients.text componentsSeparatedByString:@&,&]];
//设置密送人
if (self.bccRecipients.text.length&0) {
[mailController setBccRecipients:[self.bccRecipients.text componentsSeparatedByString:@&,&]];
//设置主题
[mailController setSubject:self.subject.text];
//设置内容
[mailController setMessageBody:self.body.text isHTML:YES];
//添加附件
if (self.attachments.text.length&0) {
NSArray *attachments=[self.attachments.text componentsSeparatedByString:@&,&] ;
[attachments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *file=[[NSBundle mainBundle] pathForResource:obj ofType:nil];
NSData *data=[NSData dataWithContentsOfFile:file];
[mailController addAttachmentData:data mimeType:@&image/jpeg& fileName:obj];//第二个参数是mimeType类型,jpg图片对应image/jpeg
[self presentViewController:mailController animated:YES completion:nil];
#pragma mark - MFMailComposeViewController代理方法
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
switch (result) {
case MFMailComposeResultSent:
NSLog(@&发送成功.&);
case MFMailComposeResultSaved://如果存储为草稿(点取消会提示是否存储为草稿,存储后可以到系统邮件应用的对应草稿箱找到)
NSLog(@&邮件已保存.&);
case MFMailComposeResultCancelled:
NSLog(@&取消发送.&);
NSLog(@&发送失败.&);
if (error) {
NSLog(@&发送邮件过程中发生错误,错误信息:%@&,error.localizedDescription);
[self dismissViewControllerAnimated:YES completion:nil];
运行效果:
2.2. 通讯录
iOS中带有一个Contacts应用程序来管理联系人,但是有些时候我们希望自己的应用能够访问或者修改这些信息,这个时候就要用到AddressBook.framework框架。iOS中的通讯录是存储在中的,由于iOS的权限设计,开发人员是不允许直接访问通讯录数据库的,必须依靠AddressBook提供的标准API来实现通讯录操作。通过AddressBook.framework开发者可以从底层去操作AddressBook.framework的所有信息,但是需要注意的是这个框架是基于C语言编写的,无法使用ARC来管理内存,开发者需要自己管理内存。下面大致介绍一下通讯录操作中常用的类型:
.1) ABAddressBookRef:代表通讯录对象,通过该对象开发人员不用过多的关注通讯录的存储方式,可以直接以透明的方式去访问、保存(在使用AddressBook.framework操作联系人时,所有的增加、删除、修改后都必须执行保存操作,类似于Core Data)等。
.2) ABRecordRef:代表一个通用的记录对象,可以是一条联系人信息,也可以是一个群组,可以通过ABRecordGetRecordType()函数获得具体类型。如果作为联系人(事实上也经常使用它作为联系人),那么这个记录记录了一个完整的联系人信息(姓名、性别、电话、邮件等),每条记录都有一个唯一的ID标示这条记录(可以通过ABRecordGetRecordID()函数获得)。
.3) ABPersonRef:代表联系人信息,很少直接使用,实际开发过程中通常会使用类型为&kABPersonType&的ABRecordRef来表示联系人(由此可见ABPersonRef其实是一种类型为&kABPersonType&的ABRecordRef)
.4)ABGroupRef:代表群组,与ABPersonRef类似,很少直接使用ABGroupRef,而是使用类型为&kABGroupType&的ABRecordRef来表示群组,一个群组可以包含多个联系人,一个联系人也同样可以多个群组。
由于通讯录操作的关键是对ABRecordRef的操作,首先看一下常用的操作通讯录记录的方法:
ABPersonCreate():创建一个类型为&kABPersonType&的ABRecordRef。
ABRecordCopyValue():取得指定属性的值。
ABRecordCopyCompositeName():取得联系人(或群组)的复合信息(对于联系人则包括:姓、名、公司等信息,对于群组则返回组名称)。
ABRecordSetValue():设置ABRecordRef的属性值。注意在设置ABRecordRef的值时又分为单值属性和多值属性:单值属性设置只要通过ABRecordSetValue()方法指定属性名和值即可;多值属性则要先通过创建一个ABMutableMultiValueRef类型的变量,然后通过ABMultiValueAddValueAndLabel()方法依次添加属性值,最后通过ABRecordSetValue()方法将ABMutableMultiValueRef类型的变量设置为记录值。
ABRecordRemoveValue():删除指定的属性值。
由于联系人访问时(读取、设置、删除时)牵扯到大量联系人属性,可以到ABPerson.h中查询或者直接到帮助文档&Personal Information Properties&
通讯录的访问步骤一般如下:
调用ABAddressBookCreateWithOptions()方法创建通讯录对象ABAddressBookRef。 调用ABAddressBookRequestAccessWithCompletion()方法获得用户授权访问通讯录。 调用ABAddressBookCopyArrayOfAllPeople()、ABAddressBookCopyPeopleWithName()方法查询联系人信息。 调用ABAddressBookCopyArrayOfAllPeople()、ABAddressBookCopyPeopleWithName()方法查询联系人信息。 也就是说如果要修改或者删除都需要首先查询对应的联系人,然后修改或删除后提交更改。如果用户要增加一个联系人则不用进行查询,直接调用ABPersonCreate()方法创建一个ABRecord然后设置具体的属性,调用ABAddressBookAddRecord方法添加即可
下面就通过一个示例演示一下如何通过ABAddressBook.framework访问通讯录,这个例子中通过一个UITableViewController模拟一下通讯录的查看、删除、添加操作。
主控制器视图,用于显示联系人,修改删除联系人:
KCContactViewController.h
定义一个协议作为代理
@protocol KCContactDelegate
//新增或修改联系人
-(void)editPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workN
//取消修改或新增
-(void)cancelE
@interface KCContactTableViewController : UITableViewController
KCContactViewController.m
#import &KCContactTableViewController.h&
#import &KCAddPersonViewController.h&
@interface KCContactTableViewController ()
@property (assign,nonatomic) ABAddressBookRef addressB//通讯录
@property (strong,nonatomic) NSMutableArray *allP//通讯录所有人员
@property (assign,nonatomic) int isM//标识是修改还是新增,通过选择cell进行导航则认为是修改,否则视为新增
@property (assign,nonatomic) UITableViewCell *selectedC//当前选中的单元格
@implementation KCContactTableViewController
#pragma mark - 控制器视图
- (void)viewDidLoad {
[super viewDidLoad];
//请求访问通讯录并初始化数据
[self requestAddressBook];
//由于在整个视图控制器周期内addressBook都驻留在内存中,所有当控制器视图销毁时销毁该对象
-(void)dealloc{
if (self.addressBook!=NULL) {
CFRelease(self.addressBook);
#pragma mark - UI事件
//点击删除按钮
- (IBAction)trashClick:(UIBarButtonItem *)sender {
self.tableView.editing=!self.tableView.
#pragma mark - UITableView数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.allPerson.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identtityKey=@&myTableViewCellIdentityKey1&;
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:identtityKey];
if(cell==nil){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identtityKey];
//取得一条人员记录
ABRecordRef recordRef=(__bridge ABRecordRef)self.allPerson[indexPath.row];
//取得记录中得信息
NSString *firstName=(__bridge NSString *) ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);//注意这里进行了强转,不用自己释放资源
NSString *lastName=(__bridge NSString *)ABRecordCopyValue(recordRef, kABPersonLastNameProperty);
ABMultiValueRef phoneNumbersRef= ABRecordCopyValue(recordRef, kABPersonPhoneProperty);//获取手机号,注意手机号是ABMultiValueRef类,有可能有多条
NSArray *phoneNumbers=(__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumbersRef);//取得CFArraryRef类型的手机记录并转化为NSArrary
long count= ABMultiValueGetCount(phoneNumbersRef);
for(int i=0;i0) {
cell.detailTextLabel.text=(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNumbersRef, 0));
if(ABPersonHasImageData(recordRef)){//如果有照片数据
NSData *imageData= (__bridge NSData *)(ABPersonCopyImageData(recordRef));
cell.imageView.image=[UIImage imageWithData:imageData];
cell.imageView.image=[UIImage imageNamed:@&avatar&];//没有图片使用默认头像
//使用cell的tag存储记录id
cell.tag=ABRecordGetRecordID(recordRef);
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
ABRecordRef recordRef=(__bridge ABRecordRef )self.allPerson[indexPath.row];
[self removePersonWithRecord:recordRef];//从通讯录删除
[self.allPerson removeObjectAtIndex:indexPath.row];//从数组移除
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];//从列表删除
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
#pragma mark - UITableView代理方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
self.isModify=1;
self.selectedCell=[tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:@&AddPerson& sender:self];
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@&AddPerson&]){
UINavigationController *navigationController=(UINavigationController *)segue.destinationViewC
//根据导航控制器取得添加/修改人员的控制器视图
KCAddPersonViewController *addPersonController=(KCAddPersonViewController *)navigationController.topViewC
addPersonController.delegate=
//如果是通过选择cell进行的导航操作说明是修改,否则为添加
if (self.isModify) {
UITableViewCell *cell=self.selectedC
addPersonController.recordID=(ABRecordID)cell.//设置
NSArray *array=[cell.textLabel.text componentsSeparatedByString:@& &];
if (array.count&0) {
addPersonController.firstNameText=[array firstObject];
if (array.count&1) {
addPersonController.lastNameText=[array lastObject];
addPersonController.workPhoneText=cell.detailTextLabel.
#pragma mark - KCContact代理方法
-(void)editPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{
if (self.isModify) {
UITableViewCell *cell=self.selectedC
NSIndexPath *indexPath= [self.tableView indexPathForCell:cell];
[self modifyPersonWithRecordID:(ABRecordID)cell.tag firstName:firstName lastName:lastName workNumber:workNumber];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
[self addPersonWithFirstName:firstName lastName:lastName workNumber:workNumber];//通讯簿中添加信息
[self initAllPerson];//重新初始化数据
[self.tableView reloadData];
self.isModify=0;
-(void)cancelEdit{
self.isModify=0;
#pragma mark - 私有方法
请求访问通讯录
-(void)requestAddressBook{
//创建通讯录对象
self.addressBook=ABAddressBookCreateWithOptions(NULL, NULL);
//请求访问用户通讯录,注意无论成功与否block都会调用
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error) {
if (!granted) {
NSLog(@&未获得通讯录访问权限!&);
[self initAllPerson];
取得所有通讯录记录
-(void)initAllPerson{
//取得通讯录访问授权
ABAuthorizationStatus authorization= ABAddressBookGetAuthorizationStatus();
//如果未获得授权
if (authorization!=kABAuthorizationStatusAuthorized) {
NSLog(@&尚未获得通讯录访问授权!&);
//取得通讯录中所有人员记录
CFArrayRef allPeople= ABAddressBookCopyArrayOfAllPeople(self.addressBook);
self.allPerson=(__bridge NSMutableArray *)allP
//释放资源
CFRelease(allPeople);
删除指定的记录
@param recordRef 要删除的记录
-(void)removePersonWithRecord:(ABRecordRef)recordRef{
ABAddressBookRemoveRecord(self.addressBook, recordRef, NULL);//删除
ABAddressBookSave(self.addressBook, NULL);//删除之后提交更改
根据姓名删除记录
-(void)removePersonWithName:(NSString *)personName{
CFStringRef personNameRef=(__bridge CFStringRef)(personName);
CFArrayRef recordsRef= ABAddressBookCopyPeopleWithName(self.addressBook, personNameRef);//根据人员姓名查找
CFIndex count= CFArrayGetCount(recordsRef);//取得记录数
for (CFIndex i=0; i
新增或修改控制器视图,用于显示一个联系人的信息或者新增一个联系人:
KCAddPersonViewController.h
@protocol KCContactD
@interface KCAddPersonViewController : UIViewController
@property (assign,nonatomic) int recordID;//通讯录记录id,如果ID不为0则代表修改否则认为是新增
@property (strong,nonatomic) NSString *firstNameT
@property (strong,nonatomic) NSString *lastNameT
@property (strong,nonatomic) NSString *workPhoneT
@property (strong,nonatomic) id
KCAddPersonViewController.m
#import &KCAddPersonViewController.h&
#import &KCContactTableViewController.h&
@interface KCAddPersonViewController ()
@property (weak, nonatomic) IBOutlet UITextField *firstN
@property (weak, nonatomic) IBOutlet UITextField *lastN
@property (weak, nonatomic) IBOutlet UITextField *workP
@implementation KCAddPersonViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
#pragma mark - UI事件
- (IBAction)cancelClick:(UIBarButtonItem *)sender {
[self.delegate cancelEdit];
[self dismissViewControllerAnimated:YES completion:nil];
- (IBAction)doneClick:(UIBarButtonItem *)sender {
//调用代理方法
[self.delegate editPersonWithFirstName:self.firstName.text lastName:self.lastName.text workNumber:self.workPhone.text];
[self dismissViewControllerAnimated:YES completion:nil];
#pragma mark - 私有方法
-(void)setupUI{
if (self.recordID) {//如果ID不为0则认为是修改,此时需要初始化界面
self.firstName.text=self.firstNameT
self.lastName.text=self.lastNameT
self.workPhone.text=self.workPhoneT
运行效果:
1.上文中所指的以Ref结尾的对象事实上是该对象的指针(或引用),在C语言的框架中多数类型会以Ref结尾,这个类型本身就是一个指针,定义时不需要加&*&。
2.通常方法中包含copy、create、new、retain等关键字的方法创建的变量使用之后需要调用对应的release方法释放。例如:使用ABPersonCreate();创建完ABRecordRef变量后使用CFRelease()方法释放。
3.在与很多C语言框架交互时可以都存在Obj-C和C语言类型之间的转化(特别是Obj-C和Core Foundation框架中的一些转化),此时可能会用到桥接,只要在强转之后前面加上&__bridge&即可,经过桥接转化后的类型不需要再去手动维护内存,也就不需要使用对应的release方法释放内存。
4.AddressBook框架中很多类型的创建、属性设置等都是以这个类型名开发头的方法来创建的,事实上如果大家熟悉了其他框架会发现也都是类似的,这是Apple开发中约定俗成的命名规则(特别是C语言框架)。例如:要给ABRecordRef类型的变量设置属性则可以通过ABRecordSetValue()方法完成。
AddressBookUI
使用AddressBook.framework来操作通讯录特点就是可以对通讯录有更加精确的控制,但是缺点就是面对大量C语言API稍嫌麻烦,于是Apple官方提供了另一套框架供开发者使用,那就是AddressBookUI.framework。例如前面查看、新增、修改人员的界面这个框架就提供了现成的控制器视图供开发者使用。下面是这个框架中提供的控制器视图:
1. ABPersonViewController:用于查看联系人信息(可设置编辑)。需要设置displayedPerson属性来设置要显示或编辑的联系人。
2. ABNewPersonViewController:用于新增联系人信息。
3. ABUnknownPersonViewController:用于显示一个未知联系人(尚未保存的联系人)信息。需要设置displayedPerson属性来设置要显示的未知联系人。
以上三个控制器视图均继承于UIViewController,在使用过程中必须使用一个UINavigationController进行包装,否则只能看到视图内容无法进行操作(例如对于ABNewPersonViewController如果不使用UINavigationController进行包装则没有新增和取消按钮),同时注意包装后的控制器视图不需要处理具体新增、修改逻辑(增加和修改的处理逻辑对应的控制器视图内部已经完成),但是必须处理控制器的关闭操作(调用dismissViewControllerAnimated::方法),并且可以通过代理方法获得新增、修改的联系人。下面看一下三个控制器视图的代理方法:
ABPersonViewController的displayViewDelegate代理方法:
-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:
(ABMultiValueIdentifier)identifier:此方法会在选择了一个联系人属性后触发,四个参数分别代表:使用的控制器视图、所查看的联系人、所选则的联系人属性、该属性是否是多值属性。
2. ABNewPersonViewController的newPersonViewDelegate代理方法:
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person:点击取消或完成后触发,如果参数中的person为NULL说明点击了取消,否则说明点击了完成。无论是取消还是完成操作,此方法调用时保存操作已经进行完毕,不需要在此方法中自己保存联系人信息。
3. ABUnkownPersonViewcontroller的unkownPersonViewDelegate代理方法:
-(void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownCardViewController didResolveToPerson:(ABRecordRef)person:保存此联系人时调用,调用后将此联系人返回。
-(BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier:选择一个位置联系人属性之后执行,返回值代表是否执行默认的选择操作(例如如果是手机号,默认操作会拨打此电话)
除了上面三类控制器视图在AddressBookUI中还提供了另外一个控制器视图ABPeoplePickerNavigationController,它与之前介绍的UIImagePickerController、MPMediaPickerController类似,只是他是用来选择一个联系人的。这个控制器视图本身继承于UINavigationController,视图自身的&组&、&取消&按钮操作不需要开发者来完成(例如开发者不用在点击取消是关闭当前控制器视图,它自身已经实现了关闭方法),当然这里主要说一下这个控制器视图的peoplePickerDelegate代理方法:
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person:选择一个联系人后执行。此代理方法实现后代理方法&-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier&不会再执行。并且一旦实现了这个代理方法用户只能选择到联系人视图,无法查看具体联系人的信息。
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker:用户点击取消后执行。
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier:选择联系人具体的属性后执行,注意如果要执行此方法则不能实现-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person代理方法,此时如果点击一个具体联系人会导航到联系人详细信息界面,用户点击具体的属性后触发此方法。
下面就看一下上面四个控制器视图的使用方法,在下面的程序中定义了四个按钮,点击不同的按钮调用不同的控制器视图用于演示:
#import &ViewController.h&
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
#pragma mark - UI事件
//添加联系人
- (IBAction)addPersonClick:(UIButton *)sender {
ABNewPersonViewController *newPersonController=[[ABNewPersonViewController alloc]init];
//设置代理
newPersonController.newPersonViewDelegate=
//注意ABNewPersonViewController必须包装一层UINavigationController才能使用,否则不会出现取消和完成按钮,无法进行保存等操作
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:newPersonController];
[self presentViewController:navigationController animated:YES completion:nil];
- (IBAction)unknownPersonClick:(UIButton *)sender {
ABUnknownPersonViewController *unknownPersonController=[[ABUnknownPersonViewController alloc]init];
//设置未知人员
ABRecordRef recordRef=ABPersonCreate();
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, @&Kenshin&, NULL);
ABRecordSetValue(recordRef, kABPersonLastNameProperty, @&Cui&, NULL);
ABMultiValueRef multiValueRef=ABMultiValueCreateMutable(kABStringPropertyType);
ABMultiValueAddValueAndLabel(multiValueRef, @&&, kABHomeLabel, NULL);
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
unknownPersonController.displayedPerson=recordR
//设置代理
unknownPersonController.unknownPersonViewDelegate=
//设置其他属性
unknownPersonController.allowsActions=YES;//显示标准操作按钮
unknownPersonController.allowsAddingToAddressBook=YES;//是否允许将联系人添加到地址簿
CFRelease(multiValueRef);
CFRelease(recordRef);
//使用导航控制器包装
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:unknownPersonController];
[self presentViewController:navigationController animated:YES completion:nil];
- (IBAction)showPersonClick:(UIButton *)sender {
ABPersonViewController *personController=[[ABPersonViewController alloc]init];
//设置联系人
ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordRef recordRef= ABAddressBookGetPersonWithRecordID(addressBook, 1);//取得id为1的联系人记录
personController.displayedPerson=recordR
//设置代理
personController.personViewDelegate=
//设置其他属性
personController.allowsActions=YES;//是否显示发送信息、共享联系人等按钮
personController.allowsEditing=YES;//允许编辑
personController.displayedProperties=@[@(kABPersonFirstNameProperty),@(kABPersonLastNameProperty)];//显示的联系人属性信息,默认显示所有信息
//使用导航控制器包装
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:personController];
[self presentViewController:navigationController animated:YES completion:nil];
- (IBAction)selectPersonClick:(UIButton *)sender {
ABPeoplePickerNavigationController *peoplePickerController=[[ABPeoplePickerNavigationController alloc]init];
//设置代理
peoplePickerController.peoplePickerDelegate=
[self presentViewController:peoplePickerController animated:YES completion:nil];
#pragma mark - ABNewPersonViewController代理方法
//完成新增(点击取消和完成按钮时调用),注意这里不用做实际的通讯录增加工作,此代理方法调用时已经完成新增,当保存成功的时候参数中得person会返回保存的记录,如果点击取消person为NULL
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person{
//如果有联系人信息
if (person) {
NSLog(@&%@ 信息保存成功.&,(__bridge NSString *)(ABRecordCopyCompositeName(person)));
NSLog(@&点击了取消.&);
//关闭模态视图窗口
[self dismissViewControllerAnimated:YES completion:nil];
#pragma mark - ABUnknownPersonViewController代理方法
//保存未知联系人时触发
-(void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownCardViewController didResolveToPerson:(ABRecordRef)person{
if (person) {
NSLog(@&%@ 信息保存成功!&,(__bridge NSString *)(ABRecordCopyCompositeName(person)));
[self dismissViewControllerAnimated:YES completion:nil];
//选择一个人员属性后触发,返回值YES表示触发默认行为操作,否则执行代理中自定义的操作
-(BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (person) {
NSLog(@&选择了属性:%i,值:%@.&,property,(__bridge NSString *)ABRecordCopyValue(person, property));
return NO;
#pragma mark - ABPersonViewController代理方法
//选择一个人员属性后触发,返回值YES表示触发默认行为操作,否则执行代理中自定义的操作
-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (person) {
NSLog(@&选择了属性:%i,值:%@.&,property,(__bridge NSString *)ABRecordCopyValue(person, property));
return NO;
#pragma mark - ABPeoplePickerNavigationController代理方法
//选择一个联系人后,注意这个代理方法实现后属性选择的方法将不会再调用
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person{
if (person) {
NSLog(@&选择了%@.&,(__bridge NSString *)(ABRecordCopyCompositeName(person)));
//选择属性之后,注意如果上面的代理方法实现后此方法不会被调用
//-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (person && property) {
NSLog(@&选择了属性:%i,值:%@.&,property,(__bridge NSString *)ABRecordCopyValue(person, property));
//点击取消按钮
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{
NSLog(@&取消选择.&);
为了让大家可以更加清楚的看到几个控制器视图的使用,这里并没有结合前面的UITableViewController来使用,事实上大家结合前面UITableViewController可以做一个完善的通讯录应用。}

我要回帖

更多关于 发送邮件时抄送人 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信