Swift - 检查nil的非托管地址簿单值属性

Rob*_*Rob 12 unmanaged abaddressbook ios abrecordcopyvalue swift

我对iOS-Development和swift相对较新.但到目前为止,我总是能够通过对stackoverflow和一些文档和教程的一些研究来帮助自己.但是,有一个问题我找不到任何解决方案.

我想从用户地址簿中获取一些数据(例如单值属性kABPersonFirstNameProperty).因为.takeRetainedValue()如果此联系人在地址簿中没有firstName值,该函数会抛出错误,我需要确保该ABRecordCopyValue()函数确实返回一个值.我试图在一个闭包中检查这个:

let contactFirstName: String = {
   if (ABRecordCopyValue(self.contactReference, kABPersonFirstNameProperty) != nil) {
      return ABRecordCopyValue(self.contactReference, kABPersonFirstNameProperty).takeRetainedValue() as String
   } else {
      return ""
   }
}()
Run Code Online (Sandbox Code Playgroud)

contactReference 是一个类型的变量 ABRecordRef!

当地址簿联系人提供firstName值时,一切正常.但是如果没有firstName,则应用程序会崩溃.takeRetainedValue().似乎if语句没有帮助,因为ABRecordCopyValue()虽然没有firstName,但函数的非托管返回值不是nil.

我希望我能够清楚地解决问题.如果有人能帮我解决一些脑波,那将是很棒的.

Rob*_*Rob 32

如果我想要与各种属性关联的值,我使用以下语法:

let first = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String
let last  = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String
Run Code Online (Sandbox Code Playgroud)

或者您可以使用可选绑定:

if let first = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String {
    // use `first` here
}
if let last  = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String {
    // use `last` here
}
Run Code Online (Sandbox Code Playgroud)

如果你真的想要返回一个非可选的,其中缺失的值是零长度字符串,你可以使用??运算符:

let first = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String ?? ""
let last  = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String ?? ""
Run Code Online (Sandbox Code Playgroud)

  • 几天后,这就是我想要的答案!! 非常感谢你的分享! (2认同)

Log*_*gan 5

我在这里通过这个函数得到它:

func rawValueFromABRecordRef<T>(recordRef: ABRecordRef, forProperty property: ABPropertyID) -> T? {
    var returnObject: T? = nil
    if let rawValue: Unmanaged<AnyObject>? = ABRecordCopyValue(recordRef, property) {
        if let unwrappedValue: AnyObject = rawValue?.takeRetainedValue() {
            println("Passed: \(property)")
            returnObject = unwrappedValue as? T
        }
        else {
            println("Failed: \(property)")
        }
    }
    return returnObject
}
Run Code Online (Sandbox Code Playgroud)

您可以在您的财产中使用它,如下所示:

let contactFirstName: String = {
    if let firstName: String = rawValueFromABRecordRef(recordRef, forProperty: kABPersonFirstNameProperty) {
        return firstName
    }
    else {
        return ""
    }
}()
Run Code Online (Sandbox Code Playgroud)