重點(diǎn) (二十九) : 通訊錄

如何訪問(wèn)用戶的通訊錄

在iOS中,有2個(gè)框架可以訪問(wèn)用戶的通訊錄

AddressBookUI.framework

提供了聯(lián)系人列表界面归榕、聯(lián)系人詳情界面班利、添加聯(lián)系人界面等

一般用于選擇聯(lián)系人

AddressBook.framework

純C語(yǔ)言的API,僅僅是獲得聯(lián)系人數(shù)據(jù)

沒(méi)有提供UI界面展示,需要自己搭建聯(lián)系人展示界面

里面的數(shù)據(jù)類型大部分基于Core Foundation框架梯找,使用起來(lái)極其蛋疼

從iOS6開始,需要得到用戶的授權(quán)才能訪問(wèn)通訊錄益涧,因此在使用之前锈锤,需要檢查用戶是否已經(jīng)授權(quán)

獲得通訊錄的授權(quán)狀態(tài):ABAddressBookGetAuthorizationStatus()

授權(quán)狀態(tài)

kABAuthorizationStatusNotDetermined

用戶還沒(méi)有決定是否授權(quán)你的程序進(jìn)行訪問(wèn)

kABAuthorizationStatusRestricted

iOS設(shè)備上的家長(zhǎng)控制或其它一些許可配置阻止程序與通訊錄數(shù)據(jù)庫(kù)進(jìn)行交互

kABAuthorizationStatusDenied

用戶明確的拒絕了你的程序?qū)νㄓ嶄浀脑L問(wèn)

kABAuthorizationStatusAuthorized

用戶已經(jīng)授權(quán)給你的程序?qū)νㄓ嶄涍M(jìn)行訪問(wèn)

申請(qǐng)?jiān)L問(wèn)通訊錄

實(shí)例化通訊錄對(duì)象

ABAddressBookRefaddressBook = ABAddressBookCreateWithOptions(NULL, NULL);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(boolgranted, CFErrorReferror) {

if (granted)

{

    NSLog(@"授權(quán)成功!");

} else {

    NSLog(@"授權(quán)失敗!");

}

});

CFRelease(addressBook);

提示:申請(qǐng)通訊錄訪問(wèn)授權(quán)的代碼闲询,通常放在AppDelegate中

聯(lián)系人屬性定義

所有的屬性常量值都定義在了ABPerson.h頭文件中

聯(lián)系人屬性包括以下類型:

簡(jiǎn)單屬性:姓久免、名等

多重屬性:電話號(hào)碼、電子郵件等

組合屬性:地址等

注意:使用ABRecordCopyValue可以從一條Person記錄中獲取到對(duì)應(yīng)的記錄扭弧,但是后續(xù)處理則需要根據(jù)記錄的具體類型加以區(qū)分

簡(jiǎn)單屬性

一個(gè)聯(lián)系人就是一個(gè)ABRecordRef阎姥,每個(gè)聯(lián)系人都有自己的屬性,比如名字鸽捻、電話呼巴、郵件等

使用ABRecordCopyValue函數(shù)可以從ABRecordRef中獲得聯(lián)系人的簡(jiǎn)單屬性(例如:一個(gè)字符串)

ABRecordCopyValue函數(shù)接收2個(gè)參數(shù)

第1個(gè)參數(shù)是ABRecordRef實(shí)例

第2個(gè)參數(shù)是屬性關(guān)鍵字,定義在ABPerson.h中

ABPersonCopyLocalizedPropertyName函數(shù)可以根據(jù)指定的關(guān)鍵字獲取對(duì)應(yīng)的標(biāo)簽文本

獲得所有的聯(lián)系人數(shù)據(jù)

獲取所有聯(lián)系人記錄

CFArrayRefarray = ABAddressBookCopyArrayOfAllPeople(addressBook);

NSInteger count = CFArrayGetCount(array);

for (NSInteger i =0; i < count; ++i) {

取出一條記錄

ABRecordRef person =

CFArrayGetValueAtIndex(array, i);

取出個(gè)人記錄中的詳細(xì)信息

名

CFStringRef firstNameLabel =

ABPersonCopyLocalizedPropertyName(kABPersonFirstNameProperty);

CFStringRef firstName =

ABRecordCopyValue(person, kABPersonFirstNameProperty);

CFStringRef

lastNameLabel = ABPersonCopyLocalizedPropertyName(kABPersonLastNameProperty);

姓

CFStringRef lastName = ABRecordCopyValue(person,

kABPersonLastNameProperty);

NSLog(@"%@ %@ - %@ %@", lastNameLabel,

lastName, firstNameLabel, firstName);

}

CoreFoundation 與 Foundation之間的橋接

  1. 獲取通訊錄引用

ABAddressBookRefaddressBook = ABAddressBookCreateWithOptions(NULL, nil);

  1. 獲取所有聯(lián)系人記錄

NSArray*array = (__bridge NSArray *)(ABAddressBookCopyArrayOfAllPeople(addressBook));

for (NSInteger i = 0;
i < array.count; i++) {

    取出一條記錄

    ABRecordRef

person = (__bridge ABRecordRef)(array[i]);

    取出個(gè)人記錄中的詳細(xì)信息

    NSString *firstNameLabel

= (__bridge NSString*)(ABPersonCopyLocalizedPropertyName(kABPersonFirstNameProperty));

NSString *firstName = (__bridge NSString*)(ABRecordCopyValue(person, kABPersonFirstNameProperty));

NSString *lastNameLabel

= (__bridge NSString*)(ABPersonCopyLocalizedPropertyName(kABPersonLastNameProperty));

NSString *lastName = (__bridge NSString*)(ABRecordCopyValue(person, kABPersonLastNameProperty));

NSLog(@"%@ %@ - %@ %@", lastNameLabel,

lastName, firstNameLabel, firstName);

}

CFRelease(addressBook);

結(jié)論:轉(zhuǎn)換看起來(lái)很美~~~

多重屬性

聯(lián)系人的有些屬性值就沒(méi)這么簡(jiǎn)單御蒲,一個(gè)屬性可能會(huì)包含多個(gè)值

比如郵箱衣赶,分為工作郵箱、住宅郵箱厚满、其他郵箱等

比如電話府瞄,分為工作電話、住宅電話碘箍、其他電話等

如果是復(fù)雜屬性遵馆,那么ABRecordCopyValue函數(shù)返回的就是ABMultiValueRef類型的數(shù)據(jù),例如郵箱或者電話

取電話號(hào)碼

ABMultiValueRefphones = ABRecordCopyValue(person, kABPersonPhoneProperty);

取記錄數(shù)量

NSInteger phoneCount =ABMultiValueGetCount(phones);

遍歷所有的電話號(hào)碼

for (NSInteger i = 0;
i < phoneCount; i++) {

獲取復(fù)雜屬性的方法

電話標(biāo)簽

CFStringRefphoneLabel = ABMultiValueCopyLabelAtIndex(phones, i);

本地化電話標(biāo)簽

CFStringRef
phoneLocalLabel = ABAddressBookCopyLocalizedLabel(phoneLabel);

電話號(hào)碼

CFStringRef phoneNumber
= ABMultiValueCopyValueAtIndex(phones, i);

添加聯(lián)系人的步驟

添加聯(lián)系人的步驟

通過(guò)ABPersonCreate函數(shù)創(chuàng)建一個(gè)新的聯(lián)系人(返回ABRecordRef)

通過(guò)ABRecordSetValue函數(shù)設(shè)置聯(lián)系人的屬性

通過(guò)ABAddressBookAddRecord函數(shù)將聯(lián)系人添加到通訊錄數(shù)據(jù)庫(kù)中

通過(guò)ABAddressBookSave函數(shù)保存剛才所作的修改

可以通過(guò)ABAddressBookHasUnsavedChanges函數(shù)判斷是否有未保存的修改

當(dāng)決定是否更改通訊錄數(shù)據(jù)庫(kù)后,你可以分別使用 AbAddressBookSave 或 ABAddressBookRevert 方式來(lái)保存或放棄更改

添加群組的步驟

添加群組的步驟大體和添加聯(lián)系人一致

通過(guò)ABPersonCreate函數(shù)創(chuàng)建一個(gè)新的組(返回ABRecordRef)

通過(guò)ABRecordSetValue函數(shù)設(shè)置組名

通過(guò)ABAddressBookAddRecord函數(shù)將組添加到通訊錄數(shù)據(jù)庫(kù)中

通過(guò)ABAddressBookSave函數(shù)保存剛才所作的修改

操作聯(lián)系人的頭像

想操作聯(lián)系人的頭像丰榴,有以下函數(shù)

BPersonHasImageData

判斷通訊錄中的聯(lián)系人是否有圖片

ABPersonCopyImageData

取得圖片數(shù)據(jù)(假如有的話)

ABPersonSetImageData

設(shè)置聯(lián)系人的圖片數(shù)據(jù)

*******************筆記**********************


一. 通訊錄獲取

  1. 通訊錄應(yīng)用場(chǎng)景

  2. 最常見(jiàn)的是一些即時(shí)通訊APP, 關(guān)聯(lián)聯(lián)系人;

  1. 通訊錄獲取方案

1.AddressBookUI.framework 框架

提供了聯(lián)系人列表界面货邓、聯(lián)系人詳情界面、添加聯(lián)系人界面等

一般用于選擇聯(lián)系人

2.AddressBook.framework 框架

純C語(yǔ)言的API多艇,僅僅是獲得聯(lián)系人數(shù)據(jù)

沒(méi)有提供UI界面展示逻恐,需要自己搭建聯(lián)系人展示界面

里面的數(shù)據(jù)類型大部分基于Core Foundation框架,使用起來(lái)極其蛋疼

3.ContactsUI.framework (iOS9.0最新框架)

方案1/方案2 的替代品

4.第三方框架
RHAddressBook

對(duì)AddressBook.framework框架的封裝

  1. 獲取通訊錄-AddressBookUI

  2. 實(shí)現(xiàn)步驟

1.創(chuàng)建選擇聯(lián)系人的控制器

2.設(shè)置代理(用來(lái)接收用戶選擇的聯(lián)系人信息)

3.彈出聯(lián)系人控制器

4.實(shí)現(xiàn)代理

5.在對(duì)應(yīng)的代理方法中獲取聯(lián)系人信息

  1. 具體代碼實(shí)現(xiàn)

1.創(chuàng)建選擇聯(lián)系人的控制器

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

2.設(shè)置代理(用來(lái)接收用戶選擇的聯(lián)系人信息)

ppnc.peoplePickerDelegate
= self;

3.彈出聯(lián)系人控制器

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

4.實(shí)現(xiàn)代理

  1. 選中某個(gè)聯(lián)系人時(shí)調(diào)用
  • (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController
    *)peoplePicker didSelectPerson:(ABRecordRef)person

{

}

  1. 選中某個(gè)聯(lián)系人某個(gè)屬性時(shí)調(diào)用
  • (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController
    *)peoplePicker didSelectPerson:(ABRecordRef)person
    property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier

{

}

  1. 點(diǎn)擊了取消按鈕會(huì)執(zhí)行該方法
  • (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController
    *)peoplePicker

{

}

5.在對(duì)應(yīng)的代理方法中獲取聯(lián)系人信息

  1. 獲取選中聯(lián)系人的姓名(姓l(shuí)astname和名firstname)

CFStringRef
firstname = ABRecordCopyValue(person, kABPersonFirstNameProperty);

CFStringRef
lastname = ABRecordCopyValue(person, kABPersonLastNameProperty);

NSString
*firstName = (__bridge_transfer NSString
*)(firstname);

NSString
*lastName = (__bridge_transfer NSString
*)(lastname);

NSLog(@"%@ %@", firstName, lastName);

  1. 獲取聯(lián)系人的電話號(hào)碼

ABMultiValueRef
phones = ABRecordCopyValue(person, kABPersonPhoneProperty);

CFIndex
count = ABMultiValueGetCount(phones);

for (CFIndex i = 0; i < count; i++) {

NSString *phoneLabel = (__bridge_transfer
NSString *)ABMultiValueCopyLabelAtIndex(phones, i);

NSString *phoneValue = (__bridge_transfer
NSString *)ABMultiValueCopyValueAtIndex(phones, i);

NSLog(@"label : %@ value : %@",
phoneLabel, phoneValue);

}

  1. 釋放不再使用的對(duì)象

CFRelease(phones);

  1. 獲取通訊錄-AddressBook

  2. 實(shí)現(xiàn)步驟

1.請(qǐng)求授權(quán)

2.判斷授權(quán)狀態(tài), 如果已授權(quán), 則繼續(xù); 未授權(quán), 則提示用戶, 并返回;

3.創(chuàng)建通訊錄對(duì)象

4.從通信錄對(duì)象中, 獲取所有的聯(lián)系人

5.遍歷所有的聯(lián)系人

6.釋放不再使用的對(duì)象

  1. 代碼實(shí)現(xiàn)

1.請(qǐng)求授權(quán)

1.獲取授權(quán)的狀態(tài)

ABAuthorizationStatus
status = ABAddressBookGetAuthorizationStatus();

2.判斷授權(quán)狀態(tài),如果是未決定狀態(tài),才需要請(qǐng)求

if (status == kABAuthorizationStatusNotDetermined)
{

2.1.創(chuàng)建通信錄對(duì)象

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

2.2.請(qǐng)求授權(quán)

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {

  if (granted) {

        NSLog(@"授權(quán)成功");


  } else {

        NSLog(@"授權(quán)失敗");


  }

});

}

2.判斷授權(quán)狀態(tài), 如果已授權(quán), 則繼續(xù); 未授權(quán), 則提示用戶, 并返回;

1.獲取授權(quán)的狀態(tài)

ABAuthorizationStatus
status = ABAddressBookGetAuthorizationStatus();

2.如果用戶已經(jīng)授權(quán)

if (status != kABAuthorizationStatusAuthorized)return;

3.創(chuàng)建通訊錄對(duì)象

ABAddressBookRef
addressBook = ABAddressBookCreateWithOptions(NULL,
NULL);

4.從通信錄對(duì)象中, 獲取所有的聯(lián)系人

CFArrayRef
peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);

5.遍歷所有的聯(lián)系人

5.遍歷所有的聯(lián)系人(每一個(gè)聯(lián)系人都是一條記錄)

CFIndex
peopleCount = CFArrayGetCount(peopleArray);

for (CFIndex i = 0; i < peopleCount; i++) {

6.獲取到聯(lián)系人

ABRecordRef person = CFArrayGetValueAtIndex(peopleArray, i);

7.獲取姓名

NSString *lastname = (__bridge_transfer
NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

NSString *firstName = (__bridge_transfer
NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);

NSLog(@"%@ %@", lastname,
firstName);

}

6.釋放不再使用的對(duì)象

CFRelease(peopleArray);

CFRelease(addressBook);

  1. 獲取通訊錄-第三方框架RHAddressBook

  2. 實(shí)現(xiàn)步驟

1.集成框架

2.使用框架獲取所有聯(lián)系人信息

  1. 具體實(shí)現(xiàn)

1.集成框架

  1. 將整個(gè)工程拖入項(xiàng)目
  1. 添加工程依賴

Build
Phases -> Target Dependencies -> +

  1. 添加鏈接項(xiàng)

Build
Settings -> Other Linker Flags -> -ObjC -all_load

  1. 導(dǎo)入框架頭文件

import <RHAddressBook/AddressBoook.h>

2.使用框架獲取所有聯(lián)系人信息

請(qǐng)求授權(quán)

  1. 獲取授權(quán)狀態(tài)

RHAuthorizationStatus
status = [RHAddressBook authorizationStatus];

if (status == RHAuthorizationStatusNotDetermined)

{

2. 創(chuàng)建通訊錄對(duì)象

RHAddressBook *addressBook = [[RHAddressBook alloc] init];

3. 請(qǐng)求授權(quán)

[addressBook requestAuthorizationWithCompletion:^(bool granted, NSError *error) {

  if (granted)


  {

        NSLog(@"授權(quán)成功!");


  }


  else


  {

        NSLog(@"授權(quán)失敗");


  }

}];

}

獲取聯(lián)系人信息

  1. 判斷當(dāng)前授權(quán)狀態(tài)

RHAuthorizationStatus
status = [RHAddressBook authorizationStatus];

if (status != RHAuthorizationStatusAuthorized) {

return;

}

  1. 創(chuàng)建通訊錄對(duì)象

RHAddressBook
*addressBook = [[RHAddressBook alloc] init];

  1. 獲取所有聯(lián)系人

NSArray
*peoples = addressBook.people;

  1. 遍歷所有聯(lián)系人

for (RHPerson *person in
peoples)

{

4.1 獲取聯(lián)系人姓名

NSString *firstName = person.firstName;

NSString *lastName = person.lastName;

NSLog(@"%@---%@",
firstName, lastName);

4.2 獲取聯(lián)系人電話

RHMultiStringValue *mv = person.phoneNumbers;

for (int
i = 0; i < mv.count; i ++)

{

    4.2.1 獲取電話標(biāo)簽


  NSString *label = [mv labelAtIndex:i];


 

    4.2.2 獲取電話號(hào)碼


  NSString *phone = [mv valueAtIndex:i];


  NSLog(@"%@--%@",

label, phone);

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市复隆,隨后出現(xiàn)的幾起案子拨匆,更是在濱河造成了極大的恐慌,老刑警劉巖挽拂,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惭每,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡亏栈,警方通過(guò)查閱死者的電腦和手機(jī)台腥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)绒北,“玉大人黎侈,你說(shuō)我怎么就攤上這事∶朴危” “怎么了峻汉?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脐往。 經(jīng)常有香客問(wèn)我休吠,道長(zhǎng),這世上最難降的妖魔是什么业簿? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任瘤礁,我火速辦了婚禮,結(jié)果婚禮上梅尤,老公的妹妹穿的比我還像新娘柜思。我一直安慰自己,他們只是感情好克饶,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布酝蜒。 她就那樣靜靜地躺著,像睡著了一般矾湃。 火紅的嫁衣襯著肌膚如雪亡脑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天邀跃,我揣著相機(jī)與錄音霉咨,去河邊找鬼。 笑死拍屑,一個(gè)胖子當(dāng)著我的面吹牛途戒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播僵驰,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼喷斋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼唁毒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起星爪,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤浆西,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后顽腾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體近零,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年抄肖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了久信。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡漓摩,死狀恐怖裙士,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幌甘,我是刑警寧澤潮售,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站锅风,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鞍泉。R本人自食惡果不足惜皱埠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咖驮。 院中可真熱鬧边器,春花似錦、人聲如沸托修。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)睦刃。三九已至砚嘴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涩拙,已是汗流浹背际长。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兴泥,地道東北人工育。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像搓彻,于是被迫代替她去往敵國(guó)和親如绸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嘱朽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在ios中,有兩個(gè)框架可以訪問(wèn)用戶的通訊錄 AddressBookUI.framework提供了聯(lián)系人列表界面, ...
    Manba_小洛閱讀 976評(píng)論 4 12
  • 內(nèi)容概述 iOS給我們提供了四個(gè)框架來(lái)供我們使用:iOS9之前,有AddressBookUI.framewor...
    leesum閱讀 1,177評(píng)論 0 3
  • 在開發(fā)一些應(yīng)用中,我們?nèi)绻枰猧Phone設(shè)備中的通訊錄信息怔接√掠荆或者,需要開發(fā)通訊錄相關(guān)的一些功能蜕提。那么就需要了解一...
    鄉(xiāng)村小子閱讀 1,134評(píng)論 0 1
  • 獲取通訊錄大體分兩大種森书、四小種,兩大種分別是基于address框架和contacts框架開發(fā)的谎势,四小種就是這兩大種...
    NSlog先生閱讀 904評(píng)論 0 0
  • 文/馬吉祥 我愿為水凛膏,在明亮里折射璀璨 在時(shí)光的浪里獨(dú)守一份初心 我愿為水 坦坦蕩蕩,靜靜謐謐 我愿把生命用最美的...
    馬吉祥閱讀 369評(píng)論 0 1