Coder Social home page Coder Social logo

apaddressbook's Introduction

Build Status

APAddressBook is a wrapper on AddressBook.framework that gives easy access to native address book without pain in a head.

Features

  • Load contacts from iOS address book asynchronously
  • Decide what contact data fields you need to load (for example, only name and phone number)
  • Filter contacts to get only necessary records (for example, you need only contacts with email)
  • Sort contacts with array of any NSSortDescriptor
  • Get photo of contact

Objective-c

Installation via Cocoapods

Add APAddressBook pod to Podfile

pod 'APAddressBook'

Installation via Carthage

Add to your Cartfile

github 'Alterplay/APAddressBook'

Run carthage update to fetch and build the framework. Add APAddressBook.framework to your project's 'Linked Frameworks and Libraries'. Ensure that $(SRCROOT)/Carthage/Build/iOS/APAddressBook.framework is part of the carthage copy-framework build phase.

Warning for iOS 10.0 and after

To protect user privacy, an iOS app linked on or after iOS 10.0, and which accesses the user’s contacts, must statically declare the intent to do so. Include the NSContactsUsageDescription key in your app’s Info.plist file and provide a purpose string for this key. If your app attempts to access the user’s contacts without a corresponding purpose string, your app exits.

From here.

Load contacts

APAddressBook *addressBook = [[APAddressBook alloc] init];
// don't forget to show some activity
[addressBook loadContacts:^(NSArray <APContact *> *contacts, NSError *error)
{
    // hide activity
    if (!error)
    {
        // do something with contacts array
    }
    else
    {
        // show error
    }
}];

Callback block will be run on main queue! If you need to run callback block on custom queue use loadContactsOnQueue:completion: method

Select contact fields bit-mask

Available fields:

  • APContactFieldName - first name, last name, middle name, composite name
  • APContactFieldJob - company (organization), job title
  • APContactFieldThumbnail - thumbnail image
  • APContactFieldPhonesOnly - array of phone numbers disregarding phone labels
  • APContactFieldPhonesWithLabels - array phones with original and localized labels
  • APContactFieldEmailsOnly - array of email addresses disregarding email labels
  • APContactFieldEmailsWithLabels - array of email addresses with original and localized labels
  • APContactFieldAddressesWithLabels - array of contact addresses with original and localized labels
  • APContactFieldAddressesOnly - array of contact addresses disregarding addresses labels
  • APContactFieldSocialProfiles - array of contact profiles in social networks
  • APContactFieldBirthday - date of birthday
  • APContactFieldWebsites - array of strings with website URLs
  • APContactFieldNote - string with notes
  • APContactFieldRelatedPersons - array of related persons
  • APContactFieldLinkedRecordIDs - array of contact linked records IDs
  • APContactFieldSource - contact source ID and source name
  • APContactFieldDates - contact dates with localized and original labels
  • APContactFieldRecordDate - contact record creation date and modification date
  • APContactFieldDefault - contact name and phones without labels
  • APContactFieldAll - all contact fields described above

Contact recordID property is always available

Example of field mask with name and thumbnail:

APAddressBook *addressBook = [[APAddressBook alloc] init];
addressBook.fieldsMask = APContactFieldFirstName | APContactFieldThumbnail;

Filter contacts

The most common use of this option is to filter contacts without phone number. Example:

addressBook.filterBlock = ^BOOL(APContact *contact)
{
    return contact.phones.count > 0;
};

Sort contacts

APAddressBook returns unsorted contacts. So, most of users would like to sort contacts by first name and last name.

addressBook.sortDescriptors = @[
    [NSSortDescriptor sortDescriptorWithKey:@"name.firstName" ascending:YES],
    [NSSortDescriptor sortDescriptorWithKey:@"name.lastName" ascending:YES]
];

Load contact by address book record ID

[addressBook loadContactByRecordID:recordID completion:^(APContact *contact)
{
    self.contact = contact;
}];

APContact instance will contain fields that set in addressBook.fieldsMask

Callback block will be run on main queue! If you need to run callback block on custom queue use loadContactByRecordID:onQueue:completion: method

Load contact photo by address book record ID

[addressBook loadPhotoByRecordID:recordID completion:^(UIImage *image)
{
    self.imageView.image = image;
}];

Callback block will be run on main queue! If you need to run callback block on custom queue use loadPhotoByRecordID:onQueue:completion: method

Observe address book external changes

// start observing
[addressBook startObserveChangesWithCallback:^
{
    // reload contacts
}];
// stop observing
[addressBook stopObserveChanges];

Request address book access

[addressBook requestAccess:^(BOOL granted, NSError *error)
{
    // check `granted`
}];

Check address book access

switch([APAddressBook access])
{
    case APAddressBookAccessUnknown:
        // Application didn't request address book access yet
        break;

    case APAddressBookAccessGranted:
        // Access granted
        break;

    case APAddressBookAccessDenied:
        // Access denied or restricted by privacy settings
        break;
}

Swift

Installation via Cocoapods

pod 'APAddressBook/Swift'

Import APAddressBook-Bridging.h to application's objective-c bridging file.

#import <APAddressBook/APAddressBook-Bridging.h>

Installation via Carthage

Add to your Cartfile

github 'Alterplay/APAddressBook'

Run carthage update to fetch and build the framework. Add APAddressBook.framework to your project's 'Linked Frameworks and Libraries'. Ensure that $(SRCROOT)/Carthage/Build/iOS/APAddressBook.framework is part of the carthage copy-framework build phase.

Example

See example application in Example/Swift directory.

self.addressBook.loadContacts(
    { (contacts: [APContact]?, error: Error?) in
        if let uwrappedContacts = contacts {
            // do something with contacts
        }
        else if let unwrappedError = error {
            // show error
        }
    })

APContact serialization

Use APContact-EasyMapping by Jean Lebrument

0.1.x to 0.2.x Migration guide

Migration Guide

History

Releases

Contributor guide

Contributor Guide

githalytics.com alpha

Contacts

If you have improvements or concerns, feel free to post an issue and write details.

Check out all Alterplay's GitHub projects. Email us with other ideas and projects.

apaddressbook's People

Contributors

0xthk avatar belkevich avatar carlosefonseca avatar coryalder avatar dduan avatar dobiedad avatar evgenbakumenko avatar ggurantz avatar grachyov avatar irshadpc avatar jmhobbs avatar kainsu avatar kimmobrunfeldt avatar krivoblotsky avatar krzyzanowskim avatar laptobbe avatar legranddamien avatar mikumi avatar monowerker avatar natashatherobot avatar ndmeiri avatar nicopuri avatar pr1001 avatar rahuljiresal avatar rbngzlv avatar rizal72 avatar shams-ahmed avatar slangley avatar slavabushtruk avatar tonymillion avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apaddressbook's Issues

Doesn't with Swift and Cocoapods use_frameworks

If I use cocoapods 'use_frameworks' feature, the bridging header isn't included in the package, so it doesn't work. On the surface this is not a big problem, since I can just remove the use_frameworks string from my podfile. However, my other pods are depended on that thing, so it would be nice if there was a way to fix this.

Sorting contacts does not work

I'm trying to sort the contacts at the same time as i'm reading the contacts, but it always returns an unsorted tableview. Is there maybe something that changed with the keys to sort for?

Duplicate contacts

this is the code:

@IBOutlet weak var activity: UIActivityIndicatorView!

let addressBook = APAddressBook()

override func viewDidLoad() {
    super.viewDidLoad()
    self.registerCellClass(TableViewCell.self, forModelClass: APContact.self)
    self.addressBook.fieldsMask = APContactField.FirstName | APContactField.LastName | APContactField.Emails
    self.addressBook.sortDescriptors = [NSSortDescriptor(key: "firstName", ascending: true),
        NSSortDescriptor(key: "lastName", ascending: true)]
    self.addressBook.filterBlock = {(contact: APContact!) -> Bool in
        println("\(contact.firstName), \(contact.lastName)")
        return contact.emails != nil && contact.emails.count > 0
    }
    self.addressBook.loadContacts(
        { (contacts: [AnyObject]!, error: NSError!) in
            self.activity.stopAnimating()
            if (contacts != nil) {
                self.memoryStorage().addItems(contacts)
            }
            else if (error != nil) {
                let alert = UIAlertView(title: "Error", message: error.localizedDescription,
                    delegate: nil, cancelButtonTitle: "OK")
                alert.show()
            }
        })
}

the result is a list with all contacts duplicated, why? do I need something more?

Sorting for untitled contacts?

Just a quick question. I've been wondering if it's possible to specify sort descriptors such that contacts that have the composite name, first name, and last name missing would be at the end of the array returned by loadContacts with the sort descriptor "firstName" ascending?

retrieving phone number returns nil

when i loop through the contacts array and try to print the phone number its always nil. I have numbers stored in the simulator.

        var book = APAddressBook()
        book.fieldsMask = APContactField.All

        book.loadContacts(
          {(contacts:[AnyObject]!, error:NSError!) -> Void in
                for c in contacts {
                    print (c.phoneNumber)
                }
         })

Cocoapods + Swift

I want to use the library in a Swift project with Xcode6Beta6+Cocoapods 0.33.1 and after executed pod update and added the bridge of apaddressbook on my bridge file it said that APAddressBook is not found.

screen shot 2014-09-04 at 5 50 58 pm

Contacts Birthday

Hi, thanks for the great tool. I needed to know if I can get birthday of contacts? My native contacts list do show birthday's of different contacts fetched from Facebook. But I don't see any property in APContact class regarding it.

Add toString method to APAddress class

Feature request:

A method to generate a string from an instance of APAddress would be great. Ideally it would avoid null properties (such as missing Country Code).

Get contact by RecordID from APAddressBook object

APAddressBook should have a method to get a contact given a RecordID, it should return a APContact object.

(Currently the only way to do this is to iterate all contacts - the AddressBook API gives the ABAddressBookGetPersonWithRecordID function to return a ABRecordRef which can be passed into the APContact initialiser.

use APContactFieldThumbnail cause crash

NSData *data = (__bridge_transfer NSData *)ABPersonCopyImageDataWithFormat(recordRef, format);

is that ABPersonCopyImageDataWithFormat(recordRef, format) = nil. cause this

reloading contacts

I'm using this in Swift project, basic functionality works pretty good, however when running self.addressBook.loadContacts(...) for second or latter time(app was dismissed and after it's become active again, I want to reload contacts), changes in actual address book are not reflected...

The example Swift project will not build.

Downloads/APAddressBook-master/Example/Swift/AddressBook/TableViewCell.swift:23:14: 'UIImageView?' does not have a member named 'image'

Downloads/APAddressBook-master/Example/Swift/AddressBook/TableViewCell.swift:24:14: 'UILabel?' does not have a member named 'text'

Downloads/APAddressBook-master/Example/Swift/AddressBook/TableViewCell.swift:25:14: 'UILabel?' does not have a member named 'text'

APAddressBook module is missing

As far as I can tell, the pod is installed correctly, however, when I try and use "import APAddressBook", it says no such module.

Crash in APAddressBook.m on iPhone 6

  • APAddressBook/Core (0.1.11)
  • APAddressBook/Swift (0.1.11)

My app crashes running on my iPhone 6 with a large AddressBook but does not crash in the iOS 6 simulator with only a few entries in APAddressBook.m:117

peopleArrayRef = ABAddressBookCopyArrayOfAllPeople(self.addressBook);

Because:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000003
Triggered by Thread:  6
Thread 6 name:  Dispatch queue: com.apple.root.default-qos
Thread 6 Crashed:
0   libsqlite3.dylib                0x000000019749006c 0x197444000 + 311404
1   libsqlite3.dylib                0x00000001974900cc 0x197444000 + 311500
2   libsqlite3.dylib                0x000000019748110c 0x197444000 + 250124
3   libsqlite3.dylib                0x000000019747fdf4 sqlite3_step + 524
4   AppSupport                      0x000000018b5e7728 CPSqliteStatementSendResults + 72
5   AppSupport                      0x000000018b5ecd08 CPRecordStoreProcessRecordStatementWithPropertyIndices + 188
6   AppSupport                      0x000000018b5ed084 CPRecordStoreProcessQueryWithBindBlock + 128
7   AppSupport                      0x000000018b5ed150 CPRecordStoreCopyAllInstancesOfClassWhereWithBindBlock + 136
8   AddressBook                     0x000000018454ea28 ABCCopyArrayOfAllPeopleInSourceWithSortOrdering + 156
9   APAddressBook                   0x00000001002b77b8 __48-[APAddressBook loadContactsOnQueue:completion:]_block_invoke (APAddressBook.m:117)
10  AddressBook                     0x00000001845a3194 __37-[ABTCC accessRequestWithCompletion:]_block_invoke + 44
11  libdispatch.dylib               0x000000019776d990 _dispatch_call_block_and_release + 20
12  libdispatch.dylib               0x000000019776d950 _dispatch_client_callout + 12
13  libdispatch.dylib               0x000000019777a77c _dispatch_root_queue_drain + 1844
14  libdispatch.dylib               0x000000019777bc48 _dispatch_worker_thread3 + 104
15  libsystem_pthread.dylib         0x000000019794d228 _pthread_wqthread + 812
16  libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

When the debugger breaks on frame 9 above:

(lldb) po self.addressBook
<ABCAddressBook 0x144d0b970 [0x197dc0f50]>

(lldb) po self
<APAddressBook: 0x1700533e0>

I enabled NSZombies objects in my scheme and it did nothing, but i noticed another thread with exeactly the same stack frames, see threads 2 and 6 below:

Hardware Model:      iPhone7,2
Process:             ABC [2876]
Path:                /private/var/mobile/Containers/Bundle/Application/8E7B40EE-A4C2-4E09-8303-501BA3CF2FCC/ABC.app/ABC
Identifier:          com.king7532.abc.ABC
Version:             99 (0.65)
Code Type:           ARM-64 (Native)
Parent Process:      launchd [1]

Date/Time:           2015-07-14 11:13:33.753 -0400
Launch Time:         2015-07-14 11:13:30.530 -0400
OS Version:          iOS 8.4 (12H143)
Report Version:      105

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000003
Triggered by Thread:  6

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0:
0   UIKit                           0x000000018a006ba8 -[UIViewController _isDeallocating] + 0
1   libobjc.A.dylib                 0x000000019710a4b8 -[NSObject allowsWeakReference] + 20
2   libobjc.A.dylib                 0x00000001971037e4 weak_register_no_lock + 140
3   libobjc.A.dylib                 0x00000001971082cc objc_storeWeak + 212
4   ABC                             0x00000001000eb5bc -[ZLPeoplePickerViewController setDelegate:] (ZLPeoplePickerViewController.h:48)
5   ABC                             0x00000001001445a0 ABC.ABCContactsViewController.showPeoplePickerController (ABC.ABCContactsViewController)() -> () (ABCContactsViewController.swift:53)
6   ABC                             0x0000000100146004 ABC.ABCContactsViewController.accessGrantedForAddressBook (ABC.ABCContactsViewController)() -> () (ABCContactsViewController.swift:185)
7   ABC                             0x00000001001457e0 ABC.ABCContactsViewController.checkAddressBookAccess (ABC.ABCContactsViewController)() -> () (ABCContactsViewController.swift:153)
8   ABC                             0x000000010014441c ABC.ABCContactsViewController.viewDidAppear (ABC.ABCContactsViewController)(Swift.Bool) -> () (ABCContactsViewController.swift:45)
9   ABC                             0x000000010014446c @objc ABC.ABCContactsViewController.viewDidAppear (ABC.ABCContactsViewController)(Swift.Bool) -> () (ABCContactsViewController.swift:0)
10  UIKit                           0x0000000189eb3f50 -[UIViewController _setViewAppearState:isAnimating:] + 588
11  UIKit                           0x0000000189eb44bc -[UIViewController _endAppearanceTransition:] + 340
12  UIKit                           0x000000018a1def1c __97-[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]_block_invoke749 + 32
13  UIKit                           0x0000000189f20268 -[UIViewController _executeAfterAppearanceBlock] + 60
14  UIKit                           0x0000000189f201d0 _applyBlockToCFArrayCopiedToStack + 352
15  UIKit                           0x0000000189e906a4 _afterCACommitHandler + 572
16  CoreFoundation                  0x00000001853dc2a0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 28
17  CoreFoundation                  0x00000001853d922c __CFRunLoopDoObservers + 356
18  CoreFoundation                  0x00000001853d960c __CFRunLoopRun + 832
19  CoreFoundation                  0x00000001853052d0 CFRunLoopRunSpecific + 392
20  GraphicsServices                0x000000018ed5b6f8 GSEventRunModal + 164
21  UIKit                           0x0000000189f02f3c UIApplicationMain + 1484
22  ABC                             0x000000010012d97c main (AppDelegate.swift:15)
23  libdyld.dylib                   0x000000019779aa04 start + 0

Thread 1 name:  Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0   libsystem_kernel.dylib          0x0000000197898c24 kevent64 + 8
1   libdispatch.dylib               0x000000019777de6c _dispatch_mgr_invoke + 272
2   libdispatch.dylib               0x000000019776f998 _dispatch_mgr_thread + 48

Thread 2 name:  Dispatch queue: com.apple.root.default-qos
Thread 2:
0   libsqlite3.dylib                0x000000019748ffa4 0x197444000 + 311204
1   libsqlite3.dylib                0x000000019748110c 0x197444000 + 250124
2   libsqlite3.dylib                0x000000019748110c 0x197444000 + 250124
3   libsqlite3.dylib                0x000000019747fdf4 sqlite3_step + 524
4   AppSupport                      0x000000018b5e7728 CPSqliteStatementSendResults + 72
5   AppSupport                      0x000000018b5ecd08 CPRecordStoreProcessRecordStatementWithPropertyIndices + 188
6   AppSupport                      0x000000018b5ed084 CPRecordStoreProcessQueryWithBindBlock + 128
7   AppSupport                      0x000000018b5ed150 CPRecordStoreCopyAllInstancesOfClassWhereWithBindBlock + 136
8   AddressBook                     0x000000018454ea28 ABCCopyArrayOfAllPeopleInSourceWithSortOrdering + 156
9   APAddressBook                   0x00000001002b77b8 __48-[APAddressBook loadContactsOnQueue:completion:]_block_invoke (APAddressBook.m:117)
10  AddressBook                     0x00000001845a3194 __37-[ABTCC accessRequestWithCompletion:]_block_invoke + 44
11  libdispatch.dylib               0x000000019776d990 _dispatch_call_block_and_release + 20
12  libdispatch.dylib               0x000000019776d950 _dispatch_client_callout + 12
13  libdispatch.dylib               0x000000019777a77c _dispatch_root_queue_drain + 1844
14  libdispatch.dylib               0x000000019777bc48 _dispatch_worker_thread3 + 104
15  libsystem_pthread.dylib         0x000000019794d228 _pthread_wqthread + 812
16  libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

Thread 3:
0   libsystem_kernel.dylib          0x00000001978b3c78 __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x000000019794d2d8 _pthread_wqthread + 988
2   libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

Thread 4:
0   libsystem_kernel.dylib          0x00000001978b3c78 __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x000000019794d2d8 _pthread_wqthread + 988
2   libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

Thread 5:
0   libsystem_kernel.dylib          0x00000001978b3c78 __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x000000019794d2d8 _pthread_wqthread + 988
2   libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

Thread 6 name:  Dispatch queue: com.apple.root.default-qos
Thread 6 Crashed:
0   libsqlite3.dylib                0x000000019749006c 0x197444000 + 311404
1   libsqlite3.dylib                0x00000001974900cc 0x197444000 + 311500
2   libsqlite3.dylib                0x000000019748110c 0x197444000 + 250124
3   libsqlite3.dylib                0x000000019747fdf4 sqlite3_step + 524
4   AppSupport                      0x000000018b5e7728 CPSqliteStatementSendResults + 72
5   AppSupport                      0x000000018b5ecd08 CPRecordStoreProcessRecordStatementWithPropertyIndices + 188
6   AppSupport                      0x000000018b5ed084 CPRecordStoreProcessQueryWithBindBlock + 128
7   AppSupport                      0x000000018b5ed150 CPRecordStoreCopyAllInstancesOfClassWhereWithBindBlock + 136
8   AddressBook                     0x000000018454ea28 ABCCopyArrayOfAllPeopleInSourceWithSortOrdering + 156
9   APAddressBook                   0x00000001002b77b8 __48-[APAddressBook loadContactsOnQueue:completion:]_block_invoke (APAddressBook.m:117)
10  AddressBook                     0x00000001845a3194 __37-[ABTCC accessRequestWithCompletion:]_block_invoke + 44
11  libdispatch.dylib               0x000000019776d990 _dispatch_call_block_and_release + 20
12  libdispatch.dylib               0x000000019776d950 _dispatch_client_callout + 12
13  libdispatch.dylib               0x000000019777a77c _dispatch_root_queue_drain + 1844
14  libdispatch.dylib               0x000000019777bc48 _dispatch_worker_thread3 + 104
15  libsystem_pthread.dylib         0x000000019794d228 _pthread_wqthread + 812
16  libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

Thread 7:
0   libsystem_kernel.dylib          0x00000001978b3c78 __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x000000019794d2d8 _pthread_wqthread + 988
2   libsystem_pthread.dylib         0x000000019794ceec start_wqthread + 0

Any help will be greatly appreciated. Thanks

APAddressBook not updated after changes in AddressBook

I've tried adding and deleting the phone of a contact to see if the changes where refreshed (I'm retrieving contacts whith phone number as in the example given).
The callback was fired when a change like that was produced, but when I called listOfContacts I was receiving the same list of contacts as I had before the change... So I've ended up with this solution:

modifying APAddressBookExternalChangeCallback in APAddressBook.m by adding this line as first line:

ABAddressBookRevert(addressBookRef);

and now I obtain the refreshed list of contacts.
Greetings, and congratulations for your job!
Lucía.

Make ABAddressBookRef public?

You keep the wrapped ABAddressBookRef private, but in order to call ABAddressBookRequestAccessWithCompletion, we need to access it.

If you agree, I'm happy to submit a pull request. Thanks!

Contact emails are always (null)

Hello,

Thanks for your work, I love APAddressBook and I'm using it in my almost-finished app!
I noticed a problem today while testing, the NSArray property of an APContact is always (null) also when in the contact library there is at least an email in it. Check out this screenshot with a contact example.
ios simulator screen shot 21 jun 2014 10 26 26

Here is my very simple code.

- (void)startLoading {
    __block NSArray *arrayOfContacts = [NSArray new];
    APAddressBook *addressBook = [[APAddressBook alloc] init];

    addressBook.fieldsMask = APContactFieldFirstName | APContactFieldLastName | APContactFieldPhones | APContactFieldRecordID;
    addressBook.sortDescriptors = @[
                                    [NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES],
                                    [NSSortDescriptor sortDescriptorWithKey:@"firstName" ascending:YES]];

    [addressBook loadContacts:^(NSArray *contacts, NSError *error) {
        if (!error) {
            arrayOfContacts = contacts;
            [contacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                APContact *current = (APContact *)obj;
                NSLog(@"current email %@", current.emails);
            }];
           // Already here, contacts.emails is (null)
        } else {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
                                                                message:error.localizedDescription
                                                               delegate:nil
                                                      cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
            [alertView show];
        }
    }];
}

Am I doing something wrong or is this a problem in the APAddressBook library?

Thanks a lot.

Requesting for Addressbook access

Currently, if the app does not have access to the Address Book, it never asks for it. It only returns APAddressBookAccessUnknown on [APAddressBook access].

You should add an API for requesting the access to the address book. Something like

+ (void)requestAccessWithCompletionBlock:(void(^)(void)block;

Best and efficient way to get one contact

What is the best way to get one contact based on RecordID? Is there a method for this? Or do I have to load the entire addressbook and filter based on the RecordID?

thank you!

observer doens't work

I've got the observer initialized in the ViewWillAppear method but it never finds any new changes to the addressbook. Removing or adding contacts.

Reason for missing fields

What is the reason why a lot of available fields are missing in your framework? Would you be interested in a pull request that adds the missing fields?

Crash [APContact enumerateMultiValueOfProperty:fromRecord:withBlock:]

Hello Alexey.

I found a bug.

Contact has no emails/phones (any arrays) but we try to retrieve it.

swift code to create contact: APContact(recordRef: person, fieldMask: .FirstName | .LastName | .Phones | .Emails) ->

[APContact enumerateMultiValueOfProperty:fromRecord:withBlock:] method ->

ABMultiValueRef multiValue = ABRecordCopyValue(recordRef, property);

multiValue is 0x0 in this case but we try to release it at CFRelease(multiValue);

So the the app crashes.

We need something like this:

if (multiValue != nil) { {
    CFRelease(multiValue);
}

Thank you for your work!

Calling APAddressBook.access() after permissions are updated in Settings does not reflect changes.

I am trying to alert users when they need to enable permissions for my app to access their Contacts. I call 'loadAddressBookContacts()' in both 'viewDidLoad' and from an observer that listens for UIApplicationDidBecomeActiveNotification (for when a user leaves the app to update the permissions then comes back).
However, calling 'APAddressBook.access()' after the user has left the app and updated the permissions in settings does not seem to recognize the change and still returns the 'denied' status. Only after re-launching the app does the change get observed. Is this being cached somehow?

func loadAddressBookContacts()
{
    // Check if access is denied
    if APAddressBook.access() == APAddressBookAccess.Denied
    {
        self.displayAddressBookPermissionsAlert()
        return
    }
    ...load contacts...
}

Address Book crash

When following these step

  1. run app
  2. go to setting-> privacy->contact-> AddressBook->
    Turn off the contact access service it crash.

Please solve this ASAP

Get Email type in Contact

I want to know if the library has a way to get the "Email Type" (home,work,iCloud,etc). If now i think is a good feature to develop..

Thx
Abel Osorio

Thumbnails not loading for contacts

I am trying to display the thumbnail images for address book contacts, and for some reason it recently stopped working.
When I use this code with a breakpoint inside the block, it never gets hit:

if let thumbnail = cell.apContact?.thumbnail
{
     cell.leftIconImageView.image = thumbnail
}

I have verified that the contacts do in fact have thumbnails in my native Contacts app. I have also tried to use '.photo' instead of '.thumbnail' and still no luck.
It was working before just fine so not sure why the thumbnails are being ignored now. Everything else (i.e. names, emails, phone numbers) all load up just fine.
I think I updated the pod installation a week or so ago, so not sure if something changed since my initial use a couple months ago.

Any ideas?

Filtering other fields besides phones (Swift)

I'm trying to filter my contacts to remove those without an email address
where the example below works as expected for phone entries:

    self.addressBook.filterBlock = {(contact: APContact!) -> Bool in
          return contact.phones.count > 0
        }

The following code returns "fatal error: unexpectedly found nil while unwrapping an Optional value"

    self.addressBook.filterBlock = {(contact: APContact!) -> Bool in
          return contact.emails.count > 0
        }

How should the emails filter be implemented to avoid this error? I assume the [AnyObject]! emails and phones arrays contain different types so they should be treated differently, however the solution is not readily apparent to my noob eyes!

[APContact initWithRecordRef:fieldMask:] fails when asked to retrieve non-existent fields

If

  1. you have an initiated ABRecordRef (such as that returned by ABPeoplePickerNavigationController),
  2. and you try to generate an APContact instance from the ABRecordRef by using [[APContact alloc] initWithRecordRef:recordRef fieldMask:fieldMask],
  3. and the fieldMask requests an array-type field (such as APContactFieldPhones) that is null / does not exist in the ABRecordRef,

then the program fails.

I believe the APContact should simply set the non-existent fields to a type of null value, if the field does not exist in the ABRecordRef.

Contact's company always returns nil

Hi, I'm having trouble extracting the company info from my contacts. At the moment I iterate thought the Contacts list and pass a contact to a method to extract the first and last name and concatenate these into a string that is returned. However for entries that have no first and last name I'm trying to return the company instead.
However, contacts[i].company always returns nil

ABAddressBookRegisterExternalChangeCallback doesn't called.

when I changed

dispatch_async(self.localQueue, ^
            {
                ABAddressBookRegisterExternalChangeCallback(self.addressBook,
                                                            APAddressBookExternalChangeCallback,
                                                            (__bridge void *)(self));
            });

to

dispatch_async(dispatch_get_main_queue(), ^
            {
                ABAddressBookRegisterExternalChangeCallback(self.addressBook,
                                                            APAddressBookExternalChangeCallback,
                                                            (__bridge void *)(self));
            });

then it does call to the callback function but then the other errors will occur.

It looks like that APAddressBookExternalChangeCallback will be called on the thread that registered it then if we call register function with GCD then it can be a problem because we have no idea about how the system create, using and destroy threads for using with queue.

do you have any idea how to fix it.

cheers

JSON encoding

Maybe it's just lack of knowledge but how can I encode a APContact to JSON in a easy way?

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:contacts options:0 error:nil];
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (APContact)'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.