Swift - Checking unmanaged address book single value property for nil
If I want the values associated with various properties, I use the following syntax:
let first = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String
let last = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String
Or you can use optional binding:
if let first = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String {
// use `first` here
}
if let last = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String {
// use `last` here
}
If you really want to return a non-optional, where missing value is a zero length string, you can use the ??
operator:
let first = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String ?? ""
let last = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String ?? ""
Get value as swift type from UnmanagedAnyObject . For example: ABRecordRef
Since NoOne answered before I solved it, I'll add the answer here:
firstName.takeRetainedValue() as? String
If you look at the header of the Unmanaged
struct type, you'll find this:
/// Get the value of this unmanaged reference as a managed
/// reference and consume an unbalanced retain of it.
///
/// This is useful when a function returns an unmanaged reference
/// and you know that you're responsible for releasing the result.
func takeRetainedValue() -> T
So, because the CFTypeRef
is converted to Unmanaged<AnyObject>
in Swift.
Unmanaged
uses generics to define a return type, and it is declared like so:
Unmanaged<T>
Our object is of type Unmanaged<AnyObject>
which means that takeRetainedValue()
will return type T
, or in our case, type AnyObject
. I use optional downcasting since my property firstName
is of type String?
.
You can use the takeRetainedValue
method to get your value out of your Unmanaged
object. In Foundation API's, I'm guessing that they will mostly be of type Unmanaged<AnyObject>!
and a downcast will be required. The generic formula appears to be:
var unmanagedObject: Unmanaged<AnyObject> = someFunctionThatReturnsAnUnmanagedObject()
var newValue: Type = unmanagedObject.takeRetainedValue as Type
Error with fetching value from CFArray
You cannot force cast an UnsafePointer<Void>
to a type. You must first convert that void pointer to UnsafePointer<Type>
then take its memory:
let aPerson = UnsafePointer<ABRecordRef>(CFArrayGetValueAtIndex(allPeople, i)).memory
FYI... ABAddressBook
has been deprecated on iOS 9. For new code targeting that OS, use CNContactStore
instead.
iOS AddressBook - get contact image crash
check all for nil. if ABPersonCopyImageDataWithFormat returns nil, you call takeRetainedValue on nil. and then use it nil to create image too
guard let CFData = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail) else {
print("no cfdata")
return
}
if let data = CFData.takeRetainedValue {
if let img = UIImage(data: data) {
image = img
}
}
How to add address properties in Address Book?
i don't know about ABaddressBook but if you want it in ios 9+ then you can set as follow demo with CNContact
import Contacts
func createContcat()
{
if #available(iOS 9.0, *) {
let contact = CNMutableContact()
contact.imageData = NSData() // The profile picture as a NSData object
contact.givenName = "Jack"
contact.familyName = "test"
let homeEmail = CNLabeledValue(label:CNLabelHome, value:"jaydeep@example.com")
let workEmail = CNLabeledValue(label:CNLabelWork, value:"j.appleseed@icloud.com")
contact.emailAddresses = [homeEmail, workEmail]
contact.phoneNumbers = [CNLabeledValue(
label:CNLabelPhoneNumberiPhone,
value:CNPhoneNumber(stringValue:"12346579"))]
let homeAddress = CNMutablePostalAddress()
homeAddress.street = "1 Infinite Loop"
homeAddress.city = "Test"
homeAddress.state = "Guj"
homeAddress.postalCode = "12345"
homeAddress.country = "Country"
contact.postalAddresses = [CNLabeledValue(label:CNLabelHome, value:homeAddress)]
let birthday = NSDateComponents()
birthday.day = 14
birthday.month = 2
birthday.year = 1991 // You can omit the year value for a yearless birthday
contact.birthday = birthday
// Saving the newly created contact
let store = CNContactStore()
let saveRequest = CNSaveRequest()
saveRequest.addContact(contact, toContainerWithIdentifier:nil)
do {
try store.executeSaveRequest(saveRequest)
} catch {
print("Something went wrong!")
}
}
}
Related Topics
Custom Repeat Interval for Uilocalnotification
An Elegant Way to Ignore Any Errors Thrown by a Method
Press-And-Hold Button for "Repeat Fire"
Ios13 Share Sheet: How to Set Preview Thumbnail When Sharing Uiimage
Enable/Disable Apple Push Notification from iPhone App
Leak from Nsurl and Avaudioplayer Using Arc
How to Position Views on Top of Each Other
Abpeoplepickernavigationcontroller Changes with iOS8
When Does Awakefromnib Get Called
Accessing Variables from Another Viewcontroller in Swift
Codesign Returned Unknown Error -1=Ffffffffffffffff
How to Create a Uiimage from the Current Graphics Context
Get Pixel Value from Cvpixelbufferref in Swift
Setting Up Uiscrollview to Swipe Between 3 View Controllers