iOS開(kāi)發(fā)------獲取系統(tǒng)聯(lián)系人(Contacts篇)

Contacts.framework是Apple在 iOS9.0 替代AddressBook.framework的框架,至于AddressBook是做什么的框架,樓主默認(rèn)看到博文的開(kāi)發(fā)者是知道的 O(∩_∩)O。

如果想了解AddressBook的使用歡迎查看一下樓主之前關(guān)于AddressBook的博文,本篇不做過(guò)多的綴余:
iOS開(kāi)發(fā)------獲取系統(tǒng)聯(lián)系人(AddressBook篇)
iOS開(kāi)發(fā)------操作通訊錄(AddressBook篇)&通訊錄UI(AddressBookUI篇)

每次iOS發(fā)布新的版本(甚至每年的WWDC大會(huì)舉行完畢)很多敏銳的開(kāi)發(fā)者都準(zhǔn)備或者對(duì)新版本特性進(jìn)行適配。當(dāng)然這些大神肯定會(huì)在iOS9發(fā)布后在第一時(shí)間對(duì)通訊錄功能進(jìn)行適配,一些稍微不太敏銳的開(kāi)發(fā)者鑒于AddressBook在iOS9下初次提醒以及討厭適配的繁瑣,也就不以為然。

但隨著iOS10的發(fā)布,那么適配相關(guān)框架就顯得格外重要(不是說(shuō)AddressBook不能使用了,但為了項(xiàng)目的健壯性以及良好的體驗(yàn)性,還是非常建議第一時(shí)間適配的。當(dāng)然,這句話不僅限于Contacts部分)。

如果大家的項(xiàng)目還需要適配iOS8(當(dāng)然,大多數(shù)公司肯定是也不會(huì)拋棄iOS7的用戶),那么使用AddressBook是必然的;但如果在iOS9+的系統(tǒng)上,樓主還是非常建議使用最新的Contacts.framework框架的.

個(gè)人推薦的主要是下面兩點(diǎn)原因(來(lái)源于樓主查看官方文檔,編寫Demo以及使用instruments的體會(huì)):

  1. AddressBook與其他相關(guān)廢棄框架相似一樣 (ex:ALAsset-圖片庫(kù)),語(yǔ)言風(fēng)格更接近于C語(yǔ)言(當(dāng)然也可以說(shuō)就是C語(yǔ)言),不在ARC管理之下(對(duì)于習(xí)慣使用ARC下的開(kāi)發(fā)者算是不小的挑戰(zhàn)),使用不太便利并容易造成內(nèi)存泄露。

  2. 新的框架無(wú)論在查看開(kāi)發(fā)文檔、使用、讀取速度還是靈活性都遠(yuǎn)好于廢棄框架,內(nèi)存泄露易于查找以及補(bǔ)漏。

這里還是要分享一下源碼,樓主整合AddressBook.framework以及Contacts.framework的DEMO

預(yù)覽圖

左邊為AddressBook框架進(jìn)行的演示,右邊為Contact框架進(jìn)行的演示.
根據(jù)不同的版本進(jìn)行自動(dòng)適配,如果是iOS9,自動(dòng)使用Contact.framework.

使用AddressBook.framework
使用Contacts.framework


權(quán)限描述

在iOS10上由于權(quán)限有很多的坑,本博文的內(nèi)容需要使用通訊錄權(quán)限.
那么不要忘記在項(xiàng)目的info.plist文件中加入如下描述:Privacy - Contacts Usage Description,描述字符串:RITL want to use your Contacts(這個(gè)隨意),盡可能的寫點(diǎn)東西吧,聽(tīng)說(shuō)如果不寫上線可能會(huì)被Apple拒絕..

獲取權(quán)限-CNContactStore

負(fù)責(zé)獲得權(quán)限、請(qǐng)求權(quán)限以及執(zhí)行操作請(qǐng)求的類就是CNContactStore,具體Demo中的代碼如下:

/**
 檢測(cè)權(quán)限并作響應(yīng)的操作
 */
- (void)__checkAuthorizationStatus
{
    //這里有一個(gè)枚舉類:CNEntityType,不過(guò)沒(méi)關(guān)系,只有一個(gè)值:CNEntityTypeContacts
    switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts])
    {
            //存在權(quán)限
        case CNAuthorizationStatusAuthorized:
            //獲取通訊錄
            [self __obtainContacts:self.completeBlock];
            break;
            
            //權(quán)限未知
        case CNAuthorizationStatusNotDetermined:
            //請(qǐng)求權(quán)限
            [self __requestAuthorizationStatus];break;
            
            //如果沒(méi)有權(quán)限
        case CNAuthorizationStatusRestricted:
        case CNAuthorizationStatusDenied://需要提示
            self.defendBlock();break;
    }
}


請(qǐng)求聯(lián)系人列表-CNContactStore

這里有幾種比較常用的思路

1.使用自帶的枚舉方法一次性獲得所有的屬性

// 使用枚舉方法對(duì)所有的聯(lián)系人對(duì)象(CNContact)進(jìn)行列出,該方法是同步的
- (BOOL)enumerateContactsWithFetchRequest:(CNContactFetchRequest *)fetchRequest
                                    error:(NSError *__nullable *__nullable)error
                               usingBlock:(void (^)(CNContact *contact, BOOL *stop))block;

2.先獲取所有聯(lián)系人的identifier,再根據(jù)identifier讀取聯(lián)系人信息(Demo中使用的該思路)

// 通過(guò)identifer獲得一個(gè)唯一的CNContact
- (nullable CNContact *)unifiedContactWithIdentifier:(NSString *)identifier
                                         keysToFetch:(NSArray<id<CNKeyDescriptor>> *)keys
                                               error:(NSError *__nullable *__nullable)error;


遍歷請(qǐng)求類-CNContactFetchRequest

感覺(jué)這里介紹一下CNContactFetchRequest類還是有必要的,畢竟當(dāng)初在這里也是浪費(fèi)了點(diǎn)時(shí)間,它是一個(gè)遍歷請(qǐng)求的類,我們可以通過(guò)初始化該類的實(shí)例對(duì)象,告訴contactStore我們需要遍歷contact的某些屬性:

//實(shí)例化CNContactFetchRequest對(duì)象,通過(guò)一個(gè)遍歷鍵的描述數(shù)組
- (instancetype)initWithKeysToFetch:(NSArray <id<CNKeyDescriptor>>*)keysToFetch NS_DESIGNATED_INITIALIZER;


鍵值描述協(xié)議-CNKeyDescriptor

如果我們單純的進(jìn)入開(kāi)發(fā)文檔,我們會(huì)發(fā)現(xiàn)他是一個(gè)空協(xié)議,剛開(kāi)始看到這里的時(shí)候樓主表示很蒙B

//沒(méi)有任何的required和optional方法
@protocol CNKeyDescriptor <NSObject, NSSecureCoding, NSCopying>
@end

但很快就發(fā)現(xiàn)了下面這個(gè)Category

// //Allows contact property keys to be used with keysToFetch.
// 允許contact的屬性鍵作為遍歷的鍵
@interface NSString (Contacts) <CNKeyDescriptor>
@end

如果還是有點(diǎn)疑惑,那么相信看到下面就不會(huì)再有困惑了呢。沒(méi)錯(cuò),可以直接將下列字符串當(dāng)成CNKeyDescriptor對(duì)象寫入數(shù)組

//標(biāo)識(shí)符
CONTACTS_EXTERN NSString * const CNContactIdentifierKey                      NS_AVAILABLE(10_11, 9_0);
//姓名前綴
CONTACTS_EXTERN NSString * const CNContactNamePrefixKey                      NS_AVAILABLE(10_11, 9_0);
//姓名
CONTACTS_EXTERN NSString * const CNContactGivenNameKey                       NS_AVAILABLE(10_11, 9_0);
//中間名
CONTACTS_EXTERN NSString * const CNContactMiddleNameKey                      NS_AVAILABLE(10_11, 9_0);
//姓氏
CONTACTS_EXTERN NSString * const CNContactFamilyNameKey                      NS_AVAILABLE(10_11, 9_0);
//之前的姓氏(ex:國(guó)外的女士)
CONTACTS_EXTERN NSString * const CNContactPreviousFamilyNameKey              NS_AVAILABLE(10_11, 9_0);
//姓名后綴
CONTACTS_EXTERN NSString * const CNContactNameSuffixKey                      NS_AVAILABLE(10_11, 9_0);
//昵稱
CONTACTS_EXTERN NSString * const CNContactNicknameKey                        NS_AVAILABLE(10_11, 9_0);
//公司(組織)
CONTACTS_EXTERN NSString * const CNContactOrganizationNameKey                NS_AVAILABLE(10_11, 9_0);
//部門
CONTACTS_EXTERN NSString * const CNContactDepartmentNameKey                  NS_AVAILABLE(10_11, 9_0);
//職位
CONTACTS_EXTERN NSString * const CNContactJobTitleKey                        NS_AVAILABLE(10_11, 9_0);
//名字的拼音或音標(biāo)
CONTACTS_EXTERN NSString * const CNContactPhoneticGivenNameKey               NS_AVAILABLE(10_11, 9_0);
//中間名的拼音或音標(biāo)
CONTACTS_EXTERN NSString * const CNContactPhoneticMiddleNameKey              NS_AVAILABLE(10_11, 9_0);
//形式的拼音或音標(biāo)
CONTACTS_EXTERN NSString * const CNContactPhoneticFamilyNameKey              NS_AVAILABLE(10_11, 9_0);
//公司(組織)的拼音或音標(biāo)(iOS10 才開(kāi)始存在的呢)
CONTACTS_EXTERN NSString * const CNContactPhoneticOrganizationNameKey        NS_AVAILABLE(10_12, 10_0);
//生日
CONTACTS_EXTERN NSString * const CNContactBirthdayKey                        NS_AVAILABLE(10_11, 9_0);
//農(nóng)歷
CONTACTS_EXTERN NSString * const CNContactNonGregorianBirthdayKey            NS_AVAILABLE(10_11, 9_0);
//備注
CONTACTS_EXTERN NSString * const CNContactNoteKey                            NS_AVAILABLE(10_11, 9_0);
//頭像
CONTACTS_EXTERN NSString * const CNContactImageDataKey                       NS_AVAILABLE(10_11, 9_0);
//頭像的縮略圖
CONTACTS_EXTERN NSString * const CNContactThumbnailImageDataKey              NS_AVAILABLE(10_11, 9_0);
//頭像是否可用
CONTACTS_EXTERN NSString * const CNContactImageDataAvailableKey              NS_AVAILABLE(10_12, 9_0);
//類型
CONTACTS_EXTERN NSString * const CNContactTypeKey                            NS_AVAILABLE(10_11, 9_0);
//電話號(hào)碼
CONTACTS_EXTERN NSString * const CNContactPhoneNumbersKey                    NS_AVAILABLE(10_11, 9_0);
//郵箱地址
CONTACTS_EXTERN NSString * const CNContactEmailAddressesKey                  NS_AVAILABLE(10_11, 9_0);
//住址
CONTACTS_EXTERN NSString * const CNContactPostalAddressesKey                 NS_AVAILABLE(10_11, 9_0);
//其他日期
CONTACTS_EXTERN NSString * const CNContactDatesKey                           NS_AVAILABLE(10_11, 9_0);
//url地址
CONTACTS_EXTERN NSString * const CNContactUrlAddressesKey                    NS_AVAILABLE(10_11, 9_0);
//關(guān)聯(lián)人
CONTACTS_EXTERN NSString * const CNContactRelationsKey                       NS_AVAILABLE(10_11, 9_0);
//社交
CONTACTS_EXTERN NSString * const CNContactSocialProfilesKey                  NS_AVAILABLE(10_11, 9_0);
//即時(shí)通信
CONTACTS_EXTERN NSString * const CNContactInstantMessageAddressesKey         NS_AVAILABLE(10_11, 9_0);


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

// RITLContactNameObject獲取姓名屬性的類目方法
-(void)contactObject:(CNContact *)contact
{
    [super contactObject:contact];
    
    //設(shè)置姓名屬性
    self.nickName = contact.nickname;                   //昵稱
    self.givenName = contact.givenName;                 //名字
    self.familyName = contact.familyName;               //姓氏
    self.middleName = contact.middleName;               //中間名
    self.namePrefix = contact.namePrefix;               //名字前綴
    self.nameSuffix = contact.nameSuffix;               //名字的后綴
    self.phoneticGivenName = contact.phoneticGivenName; //名字的拼音或音標(biāo)
    self.phoneticFamilyName = contact.phoneticFamilyName;//姓氏的拼音或音標(biāo)
    self.phoneticMiddleName = contact.phoneticMiddleName;//中間名的拼音或音標(biāo)
    
#ifdef __IPHONE_10_0
    self.phoneticOrganizationName = contact.phoneticOrganizationName;//公司(組織)的拼音或音標(biāo)
#endif
}


獲取聯(lián)系人的類型

這里需要判斷一下該屬性是否可用(不只該屬性,所有的屬性都應(yīng)先判斷一下)不然會(huì)拋出異常.

/**
 *  獲得聯(lián)系人類型信息
 */
+ (RITLContactType)__contactTypeProperty
{
    if (![self.currentContact isKeyAvailable:CNContactTypeKey])
    {
        return RITLContactTypeUnknown;//沒(méi)有可用就是未知
    }
    
    else if (self.currentContact.contactType == CNContactTypeOrganization)
    {
        return RITLContactTypeOrigination;//如果是組織
    }
    
    else{
        return RITLContactTypePerson;
    }
}


獲得聯(lián)系人的頭像圖片

/**
 *  獲得聯(lián)系人的頭像圖片
 */
+ (UIImage * __nullable)__contactHeadImagePropery
{
    //縮略圖Data
    if ([self.currentContact isKeyAvailable:CNContactThumbnailImageDataKey])
    {
        NSData * thumImageData = self.currentContact.thumbnailImageData;
        
        return [UIImage imageWithData:thumImageData];
    }
    return nil;
}


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

/**
 *  獲得電話號(hào)碼對(duì)象數(shù)組
 */
+ (NSArray <RITLContactPhoneObject *> *)__contactPhoneProperty
{
    
    if (![self.currentContact isKeyAvailable:CNContactPhoneNumbersKey])
    {
        return @[];
    }
    
    //外傳數(shù)組
    NSMutableArray <RITLContactPhoneObject *> * phones = [NSMutableArray arrayWithCapacity:self.currentContact.phoneNumbers.count];
    
    for (CNLabeledValue * phoneValue in self.currentContact.phoneNumbers)
    {
        //初始化PhoneObject對(duì)象
        RITLContactPhoneObject * phoneObject = [RITLContactPhoneObject new];
        
        //setValue
        phoneObject.phoneTitle = [CNLabeledValue localizedStringForLabel:phoneValue.label];
        phoneObject.phoneNumber = ((CNPhoneNumber *)phoneValue.value).stringValue;
        
        [phones addObject:phoneObject];
    }
    
    return [NSArray arrayWithArray:phones];
}


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

/**
 *  獲得工作的相關(guān)屬性
 */
+ (RITLContactJobObject *)__contactJobProperty
{
    RITLContactJobObject * jobObject = [[ RITLContactJobObject alloc]init];
    
    if ([self.currentContact isKeyAvailable:CNContactJobTitleKey])
    {
        //setValue
        jobObject.jobTitle = self.currentContact.jobTitle;
        jobObject.departmentName = self.currentContact.departmentName;
        jobObject.organizationName = self.currentContact.organizationName;
    }

    return jobObject;
}


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

/**
 *  獲得Email對(duì)象的數(shù)組
 */
+ (NSArray <RITLContactEmailObject *> *)__contactEmailProperty
{
    if (![self.currentContact isKeyAvailable:CNContactEmailAddressesKey])
    {
        return @[];
    }
    
    //外傳數(shù)組
    NSMutableArray <RITLContactEmailObject *> * emails = [NSMutableArray arrayWithCapacity:self.currentContact.emailAddresses.count];
    
    for (CNLabeledValue * emailValue in self.currentContact.emailAddresses)
    {
        //初始化RITLContactEmailObject對(duì)象
        RITLContactEmailObject * emailObject = [[RITLContactEmailObject alloc]init];
        
        //setValue
        emailObject.emailTitle =  [CNLabeledValue localizedStringForLabel:emailValue.label];
        emailObject.emailAddress = emailValue.value;
        
        [emails addObject:emailObject];
        
    }
    
    return [NSArray arrayWithArray:emails];
}


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

/**
 *  獲得Address對(duì)象的數(shù)組
 */
+ (NSArray <RITLContactAddressObject *> *)__contactAddressProperty
{
    if (![self.currentContact isKeyAvailable:CNContactPostalAddressesKey]) {
        
        return @[];
        
    }
    
    //外傳數(shù)組
    NSMutableArray <RITLContactAddressObject *> * addresses = [NSMutableArray arrayWithCapacity:self.currentContact.postalAddresses.count];
    
    for (CNLabeledValue * addressValue in self.currentContact.postalAddresses)
    {
        //初始化地址對(duì)象
        RITLContactAddressObject * addressObject = [[RITLContactAddressObject alloc]init];
        
        //setValues
        addressObject.addressTitle =  [CNLabeledValue localizedStringForLabel:addressValue.label];
        
        //setDetailValue
        [addressObject contactObject:addressValue.value];
        
        //add object
        [addresses addObject:addressObject];
    }
    
    return [NSArray arrayWithArray:addresses];
}


獲得聯(lián)系人的生日信息

/**
 *  獲得生日的相關(guān)屬性
 */
+ (RITLContactBrithdayObject *)__contactBrithdayProperty
{
    //實(shí)例化對(duì)象
    RITLContactBrithdayObject * brithdayObject = [[RITLContactBrithdayObject alloc]init];
    
    
    if ([self.currentContact isKeyAvailable:CNContactBirthdayKey])
    {
        //set value
        brithdayObject.brithdayDate = [self.currentContact.birthday.calendar dateFromComponents:self.currentContact.birthday];
        brithdayObject.leapMonth = self.currentContact.birthday.isLeapMonth;
    }

    if ([self.currentContact isKeyAvailable:CNContactNonGregorianBirthdayKey])
    {
        brithdayObject.calendar = self.currentContact.nonGregorianBirthday.calendar.calendarIdentifier;
        brithdayObject.era = self.currentContact.nonGregorianBirthday.era;
        brithdayObject.day = self.currentContact.nonGregorianBirthday.day;
        brithdayObject.month = self.currentContact.nonGregorianBirthday.month;
        brithdayObject.year = self.currentContact.nonGregorianBirthday.year;
    }

    //返回對(duì)象
    return brithdayObject;
}


獲取聯(lián)系人的即時(shí)通信信息

/**
 *  獲得即時(shí)通信賬號(hào)相關(guān)信息
 */
+ (NSArray <RITLContactInstantMessageObject *> *)__contactMessageProperty
{
    if (![self.currentContact isKeyAvailable:CNContactInstantMessageAddressesKey])
    {
        return @[];
    }
    
    //存放數(shù)組
    NSMutableArray <RITLContactInstantMessageObject *> * instantMessages = [NSMutableArray arrayWithCapacity:self.currentContact.instantMessageAddresses.count];
    
    for (CNLabeledValue * instanceAddressValue in self.currentContact.instantMessageAddresses)
    {
        RITLContactInstantMessageObject * instaceObject = [[RITLContactInstantMessageObject alloc]init];
        
        //set value
        instaceObject.identifier = instanceAddressValue.identifier;
        instaceObject.service = ((CNInstantMessageAddress *)instanceAddressValue.value).service;
        instaceObject.userName = ((CNInstantMessageAddress *)instanceAddressValue.value).username;
        
        //add
        [instantMessages addObject:instaceObject];
    }
    
    return [NSArray arrayWithArray:instantMessages];
}


獲得聯(lián)系人的關(guān)聯(lián)人信息

/**
 *  獲得聯(lián)系人的關(guān)聯(lián)人信息
 */
+ (NSArray <RITLContactRelatedNamesObject *> *)__contactRelatedNamesProperty
{
    if (![self.currentContact isKeyAvailable:CNContactRelationsKey])
    {
        return @[];
    }
    
    //存放數(shù)組
    NSMutableArray <RITLContactRelatedNamesObject *> * relatedNames = [NSMutableArray arrayWithCapacity:self.currentContact.contactRelations.count];
    
    for (CNLabeledValue * relationsValue in self.currentContact.contactRelations)
    {
        RITLContactRelatedNamesObject * relatedObject = [[RITLContactRelatedNamesObject alloc]init];
        
        //set value
        relatedObject.identifier = relationsValue.identifier;
        relatedObject.relatedTitle =  [CNLabeledValue localizedStringForLabel:relationsValue.label];
        relatedObject.relatedName = ((CNContactRelation *)relationsValue.value).name;
        
        [relatedNames addObject:relatedObject];
        
    }

    return [NSArray arrayWithArray:relatedNames];
}


獲取聯(lián)系人的社交簡(jiǎn)介信息

/**
 *  獲得聯(lián)系人的社交簡(jiǎn)介信息
 */
+ (NSArray <RITLContactSocialProfileObject *> *)__contactSocialProfilesProperty
{
    if (![self.currentContact isKeyAvailable:CNContactSocialProfilesKey])
    {
        return @[];
    }
    
    //外傳數(shù)組
    NSMutableArray <RITLContactSocialProfileObject *> * socialProfiles = [NSMutableArray arrayWithCapacity:self.currentContact.socialProfiles.count];
    
    for (CNLabeledValue * socialProfileValue in self.currentContact.socialProfiles) {
        
        RITLContactSocialProfileObject * socialProfileObject = [[RITLContactSocialProfileObject alloc]init];
        
        //獲得CNSocialProfile對(duì)象
        CNSocialProfile * socialProfile = socialProfileValue.value;

        //set value
        socialProfileObject.identifier = socialProfileValue.identifier;
        socialProfileObject.socialProfileTitle = socialProfile.service;
        socialProfileObject.socialProFileAccount = socialProfile.username;
        socialProfileObject.socialProFileUrl = socialProfile.urlString;
        
        [socialProfiles addObject:socialProfileObject];
    }
    
    return [NSArray arrayWithArray:socialProfiles];
}


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

/**
 獲得聯(lián)系人的備注信息
 */
+ (NSString * __nullable)__contactNoteProperty
{
    if ([self.currentContact isKeyAvailable:CNContactNoteKey])
    {
        return self.currentContact.note;
    }
    
    return nil;
}


接收外界通訊錄發(fā)生變化的方法

這里不再是直接使用C語(yǔ)言的函數(shù)賦址來(lái)進(jìn)行方法注冊(cè),方法更加的ObjC,選用了更多的通知中心。

/**
 添加變化監(jiān)聽(tīng)
 */
- (void)__addStoreDidChangeNotification
{
    if (self.notificationDidAdd == false)
    {
        //添加通知
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(__contactDidChange:) name:CNContactStoreDidChangeNotification object:nil];
        self.notificationDidAdd = !self.notificationDidAdd;
    }  
}

下面是執(zhí)行變化后的方法:

樓主的測(cè)試的時(shí)候通訊錄變化會(huì)連續(xù)觸發(fā)3次通知方法,后面的延遲3s就是解決連續(xù)觸發(fā)的問(wèn)題,也不知道是個(gè)人的程序出問(wèn)題還是Contact框架的bug,如果大家有什么好辦法或者什么好的建議,也請(qǐng)告知一下,十分感謝。

/**
 通訊錄發(fā)生變化進(jìn)行的回調(diào)

 @param notication 發(fā)送的通知
 */
- (void)__contactDidChange:(NSNotification *)notication
{
    //重新獲取通訊錄
    if (self.contactDidChange != nil )
    {
        //如果可以進(jìn)行回調(diào)
        if (self.shouldResponseContactChange == true)
        {
            //重新加載緩存
            [[RITLContactCatcheManager sharedInstace]reloadContactIdentifiers:^(NSArray<NSString *> * _Nonnull identifiers) {
                
                NSArray * contacts = [self __contactHandleWithIdentifiers:identifiers];
                
                //回調(diào)
                self.contactDidChange([contacts mutableCopy]);
            }];
            
            self.responseContactChange = false;
            
            //延遲3s
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                
                self.responseContactChange = true;
                
            });
        }
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,514評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,373評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,975評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,743評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,199評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,414評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,951評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,780評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,218評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,649評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,889評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,673評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

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

  • Swift版本點(diǎn)擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,479評(píng)論 7 249
  • 老板曾在酒桌上說(shuō)過(guò),找對(duì)象的,得考驗(yàn)他兩件事。第一件,便是灌醉他,看他酒后的真實(shí)模樣。第二件,便是拖著他,兩...
    sunshinelina閱讀 372評(píng)論 0 0
  • 前言 市面上招聘網(wǎng)站有很多,個(gè)人常用的是拉勾,但大街也很有特色,今天嘗試分析下這款app的產(chǎn)品邏輯。 大街網(wǎng)—中國(guó)...
    番茄湯圓閱讀 724評(píng)論 0 0
  • 總結(jié) 其中綠色的部分與藍(lán)色可能在一個(gè)線程,也可能不在一個(gè)線程 初始化handler時(shí),指定了對(duì)應(yīng)的Looper以及...
    Rancune閱讀 171評(píng)論 0 0