ios - delegado - Obtenga valor como tipo swift desde Unmanaged<AnyObject>. Por ejemplo: ABRecordRef
uisearchbar swift 4 (2)
¿Cómo obtengo un valor como tipo Swift de un objeto de tipo Unmanaged<AnyObject>
? Mi ejemplo es usar un ABRecordRef
Estoy creando un objeto de contacto para administrar una vez que obtenga ABRecordRef
, pero tengo problemas para traducir desde ObjC. Esto es lo que tengo:
init(recordRef: ABRecordRef) {
if let firstName = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty) {
self.firstName = firstName
}
}
Si fuera ObjC, haría:
CFTypeRef firstNameRef = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);
if (firstNameRef) {
self.firstName = (__bridge NSString *)firstNameRef;
}
Parece que no puedo encontrar la combinación correcta de reducción / conversión, por lo que se agradece cualquier ayuda.
Como NoOne respondió antes de que lo resolviera, agregaré la respuesta aquí:
firstName.takeRetainedValue() as? String
Si observa el encabezado del tipo de estructura no Unmanaged
, encontrará esto:
/// 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
Entonces, porque CFTypeRef
se convierte a Unmanaged<AnyObject>
en Swift.
Unmanaged
usa genéricos para definir un tipo de retorno, y se declara así:
Unmanaged<T>
Nuestro objeto es de tipo Unmanaged<AnyObject>
que significa que takeRetainedValue()
devolverá el tipo T
, o en nuestro caso, escriba AnyObject
. ¿Uso el downcasting opcional ya que mi propiedad firstName
es de tipo String?
.
Puede usar el método takeRetainedValue
para obtener su valor de su objeto no Unmanaged
. En las API de Foundation, supongo que en su mayoría serán de tipo Unmanaged<AnyObject>!
y se requerirá un abatimiento. La fórmula genérica parece ser:
var unmanagedObject: Unmanaged<AnyObject> = someFunctionThatReturnsAnUnmanagedObject()
var newValue: Type = unmanagedObject.takeRetainedValue as Type
import UIKit
import AddressBook
class ViewController: UIViewController {
lazy var addressBook: ABAddressBookRef = {
var error: Unmanaged<CFError>?
return ABAddressBookCreateWithOptions(nil, &error).takeRetainedValue() as ABAddressBookRef
}()
@IBAction func GetPeople(sender: UIButton) {
var ab: ABAddressBookRef = addressBook
switch ABAddressBookGetAuthorizationStatus(){
case .Authorized:
println("Authorized")
readFromAddressBook(addressBook)
case .Denied:
println("Denied")
case .Restricted:
println("Restricted")
case .NotDetermined:
println("Not determined")
ABAddressBookRequestAccessWithCompletion(addressBook,
{[weak self] (granted: Bool, error: CFError!) in
if granted {
let strongSelf = self!
println("Access is granted")
strongSelf.readFromAddressBook(strongSelf.addressBook)
}
else{
println("Access is not granted")
}
})
default:
break
}
}
func readFromAddressBook(addressBook: ABAddressBookRef){
let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as NSArray
for person:ABRecordRef in allPeople{
if let firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty) {
if let lastName = ABRecordCopyValue(person, kABPersonLastNameProperty) {
let ln:String = (lastName.takeRetainedValue() as? String) ?? ""
let fn:String = (firstName.takeRetainedValue() as? String) ?? ""
println("/(ln) - /(fn)")
}
}
}
}
}