How to Get Account Name from Contact Framework

How to get My Number from AddressBook framework ?

This is not allowed. There is no public API to get user's phone number.
There are few open question on SO that cover this theme. For example this.

Swift Using Contacts Framework, search using phone number to get Name and User Image

In order to get this example up-and-running quickly I used the following sources of info:

Filter non-digits from string

https://stackoverflow.com/a/32700339/558933

http://www.appcoda.com/ios-contacts-framework/

The code block below includes the authorisation check because I had to get it working in order to test in the simulator. The code is just the Single-View Apps view controller and you can connect up a UIButton in the Storyboard to the findContactInfoForPhoneNumber: method to get if to run. Output is to the console - you will need to replace these print statements with something else.

If you are not interested in the full view controller code then just look at the searchForContactUsingPhoneNumber(phoneNumber: String) method. I've followed Apple's advice in the docs to run the CNContact framework asynchronously.

The code strips all the +, - and ( symbols that could be in a phone number and just matches the digits so the phone number you pass in to match MUST be exactly the same.

//
// ViewController.swift
// ContactsTest
//
// Created by Robotic Cat on 13/04/2016.
//

import UIKit
import Contacts

class ViewController: UIViewController {

// MARK: - App Logic
func showMessage(message: String) {
// Create an Alert
let alertController = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.Alert)

// Add an OK button to dismiss
let dismissAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (action) -> Void in
}
alertController.addAction(dismissAction)

// Show the Alert
self.presentViewController(alertController, animated: true, completion: nil)
}

func requestForAccess(completionHandler: (accessGranted: Bool) -> Void) {
// Get authorization
let authorizationStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts)

// Find out what access level we have currently
switch authorizationStatus {
case .Authorized:
completionHandler(accessGranted: true)

case .Denied, .NotDetermined:
CNContactStore().requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (access, accessError) -> Void in
if access {
completionHandler(accessGranted: access)
}
else {
if authorizationStatus == CNAuthorizationStatus.Denied {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let message = "\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings."
self.showMessage(message)
})
}
}
})

default:
completionHandler(accessGranted: false)
}
}

@IBAction func findContactInfoForPhoneNumber(sender: UIButton) {

self.searchForContactUsingPhoneNumber("(888)555-1212)")
}

func searchForContactUsingPhoneNumber(phoneNumber: String) {

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), { () -> Void in
self.requestForAccess { (accessGranted) -> Void in
if accessGranted {
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactImageDataKey, CNContactPhoneNumbersKey]
var contacts = [CNContact]()
var message: String!

let contactsStore = CNContactStore()
do {
try contactsStore.enumerateContactsWithFetchRequest(CNContactFetchRequest(keysToFetch: keys)) {
(contact, cursor) -> Void in
if (!contact.phoneNumbers.isEmpty) {
let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
for phoneNumber in contact.phoneNumbers {
if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
let phoneNumberString = phoneNumberStruct.stringValue
let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
if phoneNumberToCompare == phoneNumberToCompareAgainst {
contacts.append(contact)
}
}
}
}
}

if contacts.count == 0 {
message = "No contacts were found matching the given phone number."
}
}
catch {
message = "Unable to fetch contacts."
}

if message != nil {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.showMessage(message)
})
}
else {
// Success
dispatch_async(dispatch_get_main_queue(), { () -> Void in
// Do someting with the contacts in the main queue, for example
/*
self.delegate.didFetchContacts(contacts) <= which extracts the required info and puts it in a tableview
*/
print(contacts) // Will print all contact info for each contact (multiple line is, for example, there are multiple phone numbers or email addresses)
let contact = contacts[0] // For just the first contact (if two contacts had the same phone number)
print(contact.givenName) // Print the "first" name
print(contact.familyName) // Print the "last" name
if contact.isKeyAvailable(CNContactImageDataKey) {
if let contactImageData = contact.imageData {
print(UIImage(data: contactImageData)) // Print the image set on the contact
}
} else {
// No Image available

}
})
}
}
}
})
}

}

Contacts Framework. Access to phones ' values

The digits are a private variable.
For getting a phone number:

CNLabeledValue<CNPhoneNumber*>* labeledValue = contact.phoneNumbers[0];
NSString *phone = labeledValue.value.stringValue;

E.g. to get a mobile number:

// get mobile
NSString *phone = nil;
for (CNLabeledValue<CNPhoneNumber*>* labeledValue in contact.phoneNumbers)
{
if ([labeledValue.label isEqualToString:CNLabelPhoneNumberMobile])
{
phoneNumber = labeledValue.value.stringValue;
break;
}
}


Related Topics



Leave a reply



Submit