狠狠撸

狠狠撸Share a Scribd company logo
AddressBook to
Contacts
クラスメソッド株式会社
モバイルアプリサービス部
田中?孝明
自己紹介
名前 田中 孝明
出身 岡山県
iOS 開発歴 2011 ~ (ブランクあり)
入社歴 14
9月27日に福冈から来ました
AddressBook to Contacts
闲话休题
AddressBook
Contacts
Reference
? What's New in iOS 9.0
? Introducing the Contacts Framework for
iOS and OS X
? Address Book Framework Reference for
iOS
? Contacts Framework Reference
? http://qiita.com/koogawa/items/
44ce2e1fb127b884d835
Agenda
? 1. 連絡先について
? 2. AddressBookとContactsについて
? 3. Privacyについて
? 4. Fetchの違いについて
? 5. 連絡先の編集の違いについて
1. 連絡先について
連絡先について
? 連絡先に登録されているユーザーのデータベースを管理
連絡先について
? 名前
? 電話番号
? email
? 所属
? 住所
? 誕生日
? …etc
連絡先にアクセスするアプリ
? ユーザーの検索
? 友人の招待
? ユーザーの登録
活躍の場の例
? サポートデスクの連絡先を追加する
? 社員の連絡先を追加する
? 指定された连络先のみを削除する
2. AddressBookと
Contactsについて
AddressBookとContactsについて
? どちらにもUIとsu?xが付いているフレームワークがあ
り、連絡先の追加、参照、削除をする画面を提供してい
る
? CNContactPickerViewControllerを生成し、
presentViewControllerをするだけで簡単に
使用できる
ContactsUI
let contactPickerViewController =
CNContactPickerViewController()
contactPickerViewController.delegate = self
self.presentViewController(
contactPickerViewController,
animated: true,
completion: nil)
? 一覧表示
? グループ
?详细表示
?复数选択
地味…
What's New in iOS 9.0
? AddressBookフレームワークがiOS 9から
deprecatedに
? AddressBookUIの方もdeprecatedに
? 現時点ではiOS 9でも使えないこともない…
What's New in iOS 9.0
? iOS 9でContactsフレームワークが追加された
? iOS 9からしか使用できない
? iOS 8以下もサポートする場合は
AddressBookと共存させなければならない
AddressBookでは??だったものが
Contactsではxxになる、
といった観点で説明いたします。
AddressBook
? iOS専用の連絡先アクセスAPI
? Mac用は別に存在する
? Objective-C / Swift両方使用可能
? You must ensure that an instance of
ABAddressBookRef is used by only
one thread.
AddressBook
? CoreFoundation…
AddressBook to Contacts
メモリリーク怖い…
Contacts
? iOS / Macの連絡先アクセスAPI
? watchOS 2に対応
? Objective-C / Swift両方使用可能
? thread-safe(fetch & save)
Contacts
3. Privacyについて
Privacy
連絡先アクセス許可状態を取得
let status =
CNContactStore.authorizationStatusForEntityType
(.Contacts)
ABAuthorizationStatus status =
ABAddressBookGetAuthorizationStatus();
? AddressBook
? Contacts
AddressBook Contacts ステータス
CNAuthorizationStat
usNotDetermined
NotDetermined
許可/不許可問い合わ
せ前
CNAuthorizationStat
usRestricted
Restricted
管理者より機能制限
(ユーザー、アプリに
よる変更は不可)
CNAuthorizationStat
usDenied
Denied
ユーザーによって不許
可
CNAuthorizationStat
usAuthorized
Authorized
ユーザーによって許可
されている
AddressBook
? 連絡先アクセスの許可をユーザーに問い合わせる
CFErrorRef cfError = NULL;
ABAddressBookRef addressBook =
ABAddressBookCreateWithOptions(NULL,
&cfError);
ABAddressBookRequestAccessWithCompletion(
addressBook, ^(bool inGranted,
CFErrorRef inCfError) {
NSLog(@"inGranted: %d", inGranted);
});
Contacts
? 連絡先アクセスの許可をユーザーに問い合わせる
let store = CNContactStore()
store.requestAccessForEntityType(
.Contacts,
completionHandler:{
(granted: Bool, error: NSError?) -> Void in
print("granted: (granted)")
})
确认用のアラート
? 許可は設定>プライバシー>連絡先で変更可能
4. Fetchの違いに
ついて
AddressBook
? RecordIDを指定して取得
? 名前から検索
(ABAddressBookCopyPeopleWithName)
Contacts
? CNContact.identi?erを指定して取得
? 名前から検索(uni?edContactsMatchingPredicate)
連絡先データベースの作成
Contacts
AddressBook
CFErrorRef cfError = NULL;
ABAddressBookRef addressBook =
ABAddressBookCreateWithOptions(NULL,
&cfError);
let store = CNContactStore()
AddressBook
? RecordIDを指定して取得
? RecordIDはAddressBookデータベースに書き込
まれた一意の値
? 型はint 32
int32_t recordId =
(int32_t)recordIdNumber.intValue;
ABRecordRef person =
ABAddressBookGetPersonWithRecordID(
addressBook,
recordId);
Contacts
? CNContact.identi?erを使用して取得
? String型
? AddressBookのRecordIDと互換性がない
let identifier =
"035218FA-1E6E-4D1C-9708-76FBC0E55F28"
let contact = try
store.unifiedContactWithIdentifier(
identifier,
keysToFetch:[
CNContactGivenNameKey,
CNContactFamilyNameKey])
AddressBook
? 名前から検索
? 「姓」「姓読み」「名」「名読み」のどれか該
当するものをFetchする
? 戻り値はCFArrayRef…
NSString *name = @"Appleseed";
CFArrayRef contacts =
ABAddressBookCopyPeopleWithName(
addressBook,
(__bridge CFStringRef)name);
Contacts
? 名前から検索(uni?edContactsMatchingPredicate)
? keysToFetchにはFetchしてきたいプロパティのキーを指定
let predicate =
CNContact.predicateForContactsMatchingName(
“Appleseed")
let contacts = try
store.unifiedContactsMatchingPredicate(
predicate,
keysToFetch:[CNContactGivenNameKey,
CNContactFamilyNameKey])
Contacts
? keysToFetchに指定していないプロパティ
へはアクセスできない
let predicate =
CNContact.predicateForContactsMatchingName(
"Appleseed")
let contacts = try
store.unifiedContactsMatchingPredicate(
predicate,
keysToFetch:[CNContactGivenNameKey,
CNContactFamilyNameKey])
let contact = contacts.first
print("(contact!.identifier) (contact!.givenName)
(contact!.familyName) (contact!.phoneNumbers)")
Contacts
? アクセスする前にキーが指定されているかを
チェックする
if contact!.isKeyAvailable(
CNContactPhoneNumbersKey) {
Contacts
? フルネームを取得する際KeysToFetchに全て指定しない
let contacts = try
store.unifiedContactsMatchingPredicate(
predicate,
keysToFetch:[
CNContactGivenNameKey,
CNContactFamilyNameKey,
CNContactNamePrefixKey,
CNContactMiddleNameKey,
CNContactNameSuffixKey,
CNContactPhoneNumbersKey])
Contacts
? CNContactFommatterを使用する
let contacts = try
store.unifiedContactsMatchingPredicate(
predicate,
keysToFetch[
CNContactFormatter.
descriptorForRequiredKeysForStyle(.FullName),
CNContactPhoneNumbersKey])
比較
AddressBook Contacts
データベース ABAddressBookRef CNContactStore
連絡先 ABRecordRef CNContact
グループ ABRecordRef CNGroup
各プロパティ対応
AddressBook Contacts
FirstName(Takaaki)
kABPersonFirstName
Property
givenName
LastName(Tanaka)
kABPersonLastName
Property
familyName
MiddleName(F)
kABPersonMiddle
NameProperty
middleName
Pre?x(Mr.)
kABPersonPre?x
Property
namePre?x
Su?x(Jr.)
kABPersonSu?x
Property
nameSu?x
Nickname
kABPersonNickname
Property
nickname
? Conctacs.frameworkからはFetchしてくる必要がある
プロパティはキーを指定しなければならない
? AddressBookでIDから検索するロジックを実装してい
る場合はマイグレーション処理等で
Contact.identi?erに置き換える必要がある
5. 連絡先の編集の違い
AddressBook
? 新規追加の場合(全体)
CFErrorRef cfError = NULL;
ABAddressBookRef addressBook =
ABAddressBookCreateWithOptions(NULL, &cfError);
if (!addressBook) {
NSError *error = (__bridge_transfer NSError *)cfError;
NSLog(@"%s: %@", __PRETTY_FUNCTION__, error);
}
ABRecordRef person = ABPersonCreate();
ABRecordSetValue(person, kABPersonFirstNameProperty,
(__bridge CFTypeRef)@"John", &cfError);
ABRecordSetValue(person, kABPersonLastNameProperty,
(__bridge CFTypeRef)@"Appleseed", &cfError);
ABAddressBookAddRecord(addressBook, person, &cfError);
ABAddressBookSave(addressBook, &cfError);
AddressBook
? ABAddressBookRefを作成する
CFErrorRef cfError = NULL;
ABAddressBookRef addressBook =
ABAddressBookCreateWithOptions(
NULL, &cfError);
if (!addressBook) {
NSError *error =
(__bridge_transfer NSError *)cfError;
NSLog(@"%s: %@", __PRETTY_FUNCTION__, error);
}
AddressBook
? ABRecordRefを取得する
ABRecordRef person = ABPersonCreate();
ABRecordSetValue(person,
kABPersonFirstNameProperty,
(__bridge CFTypeRef)@"John", &cfError);
ABRecordSetValue(person,
kABPersonLastNameProperty,
(__bridge CFTypeRef)@"Appleseed", &cfError);
? 必要なプロパティをセットする
AddressBook
? MultiValueを追加する場合
CFErrorRef cfError = NULL;
ABMultiValueIdentifier identifier;
ABMultiValueRef multiTel =
ABMultiValueCreateMutable(kABMultiStringPropertyType);
CFStringRef label1 = kABPersonPhoneMainLabel;
NSString *value1 = @"012-345-6789";
ABMultiValueAddValueAndLabel(
multiTel, (__bridge CFTypeRef)(value1), label1, &identifier);
CFStringRef label2 = kABPersonPhoneIPhoneLabel;
NSString *value2 = @"111-222-3333";
ABMultiValueAddValueAndLabel(
multiTel, (__bridge CFTypeRef)(value2), label2, &identifier);
ABRecordSetValue(
person, kABPersonPhoneProperty, multiTel, &cfError);
CFRelease(multiTel);
AddressBook
? AddressBookに対する操作を指定する
? AddressBookに対するセーブを実施する
ABAddressBookAddRecord(
addressBook, person, &cfError);
ABAddressBookSave(addressBook, &cfError);
Contacts
? 新規追加の場合(全体)
let store = CNContactStore()
let contact = CNMutableContact()
contact.givenName = "John"
contact.familyName = "Appleseed"
let saveRequest = CNSaveRequest()
saveRequest.addContact(contact, toContainerWithIdentifier:nil)
do {
try store.executeSaveRequest(saveRequest)
} catch {
abort()
}
Contacts
? CNContactStoreを取得
? CNMutableContactを取得する
let store = CNContactStore()
let contact = CNMutableContact()
Contacts
? 必要なプロパティをセットする
contact.givenName = "John"
contact.familyName = "Appleseed"
Contacts
? MultiValueを追加する場合
let mainNumber =
CNLabeledValue(
label:CNLabelPhoneNumberMain,
value:"012-345-6789")
let iPhoneNumber =
CNLabeledValue(
label:CNLabelPhoneNumberiPhone,
value:"111-222-3333")
contact.phoneNumbers = [mainNumber, iPhoneNumber]
Contacts
? CNSaveRequestへデータベースへの操作を指定する
? CNContactStoreに対してセーブを実施する
let saveRequest = CNSaveRequest()
saveRequest.addContact(
contact, toContainerWithIdentifier:nil)
try store.executeSaveRequest(saveRequest)
Contacts Changed Noti?cations
? CNContactStoreDidChangeNoti?cation
? CNContactStoreに変更があった際に
NSNoti?cationCenterから通知を受ける
まとめ
? 新規作成、編集、削除ロジック部分はあまり変更はない
? Fetchのしかたに変更はあるが、大幅な変更はない
? RecordIDとIdenti?erに互換性がない
? Contacts.frameworkはiOS 9以降でしか使用できない
? AddressBookを使用している場合はContactsでも同じロジッ
クで実装し、iOS 8のサポート切れのタイミングで切り離せる
ようにするほうが良い
if #available(iOS 9.0, *) {
AddressBook to Contacts
AddressBook to Contacts
AddressBook to Contacts
ありがとうございました

More Related Content

AddressBook to Contacts