Swift - Checking Unmanaged Address Book Single Value Property for Nil

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



Leave a reply



Submit