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
Scaling Current Dot of Uipagecontrol and Keeping It Centered
Horizontal Paging Uicollectionview with Automatic Item Size in a Vertical Stack View
Pausing Timer When App Is in Background State Swift
Navigationlink Inside Lazyvgrid Cycles All Entries on Back, Swiftui
Module Compiled with Swift 5.1.2 Cannot Be Imported by the Swift 5.2.4 Compiler
How to Fix Uilabel Text Spacing
Swift Conform to Protocol Subclass
Why Do I Get an Mkerrordomain Error When Doing a Local Search
How to Update a Sent Message in Quickblox iOS
Target Is Not Found, Please Reconnect the Device, Xcode:Device Support File
Programmatically Obtaining the Imei or Udid of an iOS Device
iOS Mkmapview Custom Images Display on Top Left Corner
Scrolling in Uicollectionview Selects Wrongs Cells - Swift
Swift Function That Takes in Array Giving Error: '@Lvalue $T24' Is Not Identical to 'Cgfloat'
Why Swift Use a Struct as Dictionary Key Instead of a String Here