注册 登录
主题 : ABAddressBook相关API使用备忘录及讨论
级别: 圣骑士

UID: 2228
精华: 4
发帖: 73
可可豆: 7020 CB
威望: 7020 点
在线时间: 501(时)
注册时间: 2009-02-16
最后登录: 2014-10-30
0 楼:  发表于: 2010-03-19 06:42    发自: Web Page

ABAddressBook相关API使用备忘录及讨论   

最近在研究这个东西,并且提交了程序。
因为用了以下代码而被reject。
复制代码
  1. mABPersonViewController = [[ABPersonViewController alloc] init];
  2. [mABPersonViewController setAllowsDeletion:YES];

于是研究自己实现同样功能,于是也发现了API里有问题……

备忘录:
1,不要传递ABRecordRef,要坚持使用RecordID。比如下面代码
复制代码
  1. ABRecordRef recordRef = ABAddressBookGetPersonWithRecordID(addressBookRef,ABRecordGetRecordID([mPersonViewController displayedPerson]));

你会发现,recordRef和[mPersonViewController displayedPerson]的地址不一定是相同的。这里mPersonViewController是任何一个ABPersonViewController的实例,addressBookRef是你正在操作的AddressBook复本。因为它们来自不同的AddressBook复本,所以地址不同,所以无法相互混用。

2,ABAddressBookHasUnsavedChanges,这个函数是没有用的,总是返回NO。搜google搜很久了,才发现这个函数原来是无效的。从iPhone OS 2.x版本开始到现在3.x还依然存在这个问题。

3,还有一个bug是,即便我没有用setAllowsDeletion:YES这个非法设置,使用以下代码时还是可以看到删除联系人的按钮的。
复制代码
  1. - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
  2.         [personViewController setDisplayedPerson:person];
  3.         [personViewController setEditing:YES];
  4.         [peoplePicker pushViewController:personViewController animated:YES];
  5.     }
  6.     return NO;
  7. }

上面代码执行后,打开的联系人详细信息的界面,是正在编辑的界面,而且底部带有删除按钮……
但是,通过任何其他方法都无法实现这个效果。比如点“编辑”按钮时把当前ABPersonViewController设置成setEditing:YES,是没有删除按钮的……

问题:
因为ABAddressBookHasUnsavedChanges总是返回NO,所以我通过判断ABAddressBookRemoveRecord是否返回YES来判断通讯录是否被修改。是的话,直接ABAddressBookSave。
但是,有时候会出现如下错误,google里搜索这个关键词的结果为0。
sqlite3 error in CPRecordStoreSaveWithPreAndPostCallbacksAndTransactionType: cannot commit - no transaction is active

后来尝试下面这个之前提到的非法代码,测试后发现,使用官方的“删除联系人”按钮也会有这个错误提示……于是我就纳闷了……不知道大家是怎么解决这个问题的?
复制代码
  1. mABPersonViewController = [[ABPersonViewController alloc] init];
  2. [mABPersonViewController setAllowsDeletion:YES];


另外,要避免通讯录整个丢失,我总结的规律是
  1. 必须总是使用同一个AddressBook复本,也就是说,所操作的ABAddressBookRef地址是同一个。避免创建更多的复本,有时候退出程序时就有可能丢失整个数据库……
  2. 多线程操作同一个AddressBook复本时,必须避免同时操作……
现在我的程序还在继续大负荷测试。之前总是因为一些细节问题而造成整个通讯录丢失,这是一个非常严重的问题……
[ 此帖被bobgreen在2010-03-19 12:48重新编辑 ]

清空我的评分动态本帖最近评分记录: 共可可豆条评分记录
gagaga 贡献值 +5 2008-09-19
隐藏评分记录
级别: 版主

状态: 连续签到 - [144天]
UID: 491
精华: 6
发帖: 1766
可可豆: 112205 CB
威望: 112852 点
在线时间: 8537(时)
注册时间: 2008-08-19
最后登录: 2019-02-28
1 楼:  发表于: 2010-03-19 10:11    发自: Web Page
非常棒!
难得的经验啊!呵呵,bob先生,小僧想起官方最新的一个sample
贴在这里,供大家对比学习:
http://developer.apple.com/iphone/library/samplecode/QuickContacts/index.html

p.s.
这个是官方的第一个关于AddressBook的例子噢,之前都是Stanford或者cookbook的例子,
难免有些误导,哈哈!
这个例子简单易懂,抛砖引玉,在例子少的情况下,多读文档,事半功倍!
 Developer
------------------------------------------------------------
Η αγάπη ποτέ δεν αποτυγχάνει.
愛是永不止息。
Love never fails.

    --《圣经.新约》哥林多前书第13章
级别: 圣骑士

UID: 2228
精华: 4
发帖: 73
可可豆: 7020 CB
威望: 7020 点
在线时间: 501(时)
注册时间: 2009-02-16
最后登录: 2014-10-30
2 楼:  发表于: 2010-03-19 17:54    发自: Web Page
多谢补充˜
我也看过那个例子,有些地方写的太简单了。比如这里
复制代码
  1. -(void)showNewPersonViewController
  2. {
  3.     ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];
  4.     picker.newPersonViewDelegate = self;
  5.     UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:picker];
  6.     [self presentModalViewController:navigation animated:YES];
  7.     [picker release];
  8.     [navigation release];   
  9. }


其实,这里面少了很关键的一步,如下
复制代码
  1. picker.addressBook = 其他代码共用的AddressBookRef;

如果没有这句话的话,每次执行这段代码,都会建立一个新的AddressBook复本。这段代码多执行几遍后,整个通讯录就丢失了……很无奈的问题……
级别: 侠客
UID: 17864
精华: 0
发帖: 94
可可豆: 913 CB
威望: 913 点
在线时间: 55(时)
注册时间: 2010-04-19
最后登录: 2017-08-01
3 楼:  发表于: 2010-05-04 13:19    发自: Web Page
最近也在看这个呢。。好悲剧啊。。组信息读不出来啊
级别: 侠客
UID: 17864
精华: 0
发帖: 94
可可豆: 913 CB
威望: 913 点
在线时间: 55(时)
注册时间: 2010-04-19
最后登录: 2017-08-01
4 楼:  发表于: 2010-05-05 15:10    发自: Web Page
我现在就遇到了通讯录信息被整个销毁了。。。原因未知呢。。
级别: 新手上路
UID: 12879
精华: 0
发帖: 20
可可豆: 200 CB
威望: 200 点
在线时间: 36(时)
注册时间: 2010-01-11
最后登录: 2016-04-08
5 楼:  发表于: 2010-06-04 09:47    发自: Web Page
引用
引用第2楼bobgreen于2010-03-19 17:54发表的  :
多谢补充˜
我也看过那个例子,有些地方写的太简单了。比如这里
[code]
-(void)showNewPersonViewController
{
.......


QuickContacts这个例子是调用出系统的通讯录吗?我是新手,看的不是很明白。
我只需要读取出系统通讯录的数据,然后自己处理界面。
级别: 新手上路
UID: 1105
精华: 0
发帖: 2
可可豆: 763 CB
威望: 763 点
在线时间: 119(时)
注册时间: 2008-10-21
最后登录: 2017-05-16
6 楼:  发表于: 2010-06-04 12:43    发自: Web Page
http://itunes.apple.com/us/app/id320859535?mt=8

这个是我去年做的通讯录相关的东西(公司作品),请大家试用,欢迎批评指正
这个东西对于频繁刷机的我们来说,应该有点用。

关于实现的具体技术,也欢迎大家一起探讨
级别: 精灵王
UID: 13726
精华: 0
发帖: 465
可可豆: 4721 CB
威望: 4721 点
在线时间: 615(时)
注册时间: 2010-02-03
最后登录: 2014-10-07
7 楼:  发表于: 2010-06-04 23:06    发自: Web Page
很重要的东西,
来学习了~
级别: 骑士
UID: 21153
精华: 0
发帖: 200
可可豆: 1390 CB
威望: 2000 点
在线时间: 745(时)
注册时间: 2010-06-03
最后登录: 2016-10-12
8 楼:  发表于: 2010-06-27 17:51    发自: Web Page
我和五楼的同问 ....
级别: 风云使者

UID: 7444
精华: 8
发帖: 326
可可豆: 61624 CB
威望: 63424 点
在线时间: 4572(时)
注册时间: 2009-07-31
最后登录: 2017-08-18
9 楼:  发表于: 2010-06-27 18:05    发自: Web Page
引用
引用第8楼cctv于2010-06-27 17:51发表的  :
我和五楼的同问 ....



处理数据的话用addressbook里面的api,不要用addressbookui的viewcontroller

开源项目WBShareKit,欢迎共同维护~绝世唐门

CocoaChina社区转载内容已尽可能注明出处,如未能核实来源或转发内容图片有权利瑕疵的,请及时联系社区进行修改或删除【联系方式QQ : 3442093904 邮箱:support@cocoachina.com】文章内容为作者独立观点,不代表CocoaChina社区立场。版权归原作者所有,如申请授权请联系作者,因文章侵权CocoaChina社区不承担任何法律及连带责任。

描述
快速回复

关注本帖(如果有新回复会站内信通知您)

发帖、回帖都会得到可观的积分奖励。查看论坛积分规则

按"Ctrl+Enter"直接提交
    顶部