【问题标题】:ABRecordSetValue change isn't shown in people picker view after the change in Swift (perhaps change isn't committed?)在 Swift 中更改后,ABRecordSetValue 更改未显示在人员选择器视图中(也许更改未提交?)
【发布时间】:2014-08-25 01:01:29
【问题描述】:

我正在尝试使用 ABRecordSetValue() 更新 Swift 中的各种联系人属性,但是下次我打开模拟器时,它不会显示 ABPeoplePickerNavigation.presentViewController() 中的更改:

  1. 点击按钮打开联系人选择器
  2. 选择联系人
  3. 点击按钮再次打开联系人选择器

预期: 模拟器中的联系人具有我分配的新名字

实际: Println 显示该值似乎已被分配,但在视图中,名称并没有改变

我假设 ABAddressBookSave() 会提交更改,所以我想知道是否需要提交其他内容,或者我可能需要以某种方式更新用于人员选取器视图控制器的 addressBook 引用以反映更改?

首先视图会提示请求访问联系人,然后为 var adbk 赋值:

var adbk : ABAddressBook!
var authDone = false

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    if !self.authDone {
        self.authDone = true
        let stat = ABAddressBookGetAuthorizationStatus()
        switch stat {
        case .Denied, .Restricted:
            println("no access")
        case .Authorized, .NotDetermined:
            var err : Unmanaged<CFError>? = nil
            var adbk : ABAddressBook? = ABAddressBookCreateWithOptions(nil, &err).takeRetainedValue()
            if adbk == nil {
                println(err)
                return
            }
            ABAddressBookRequestAccessWithCompletion(adbk) {
                (granted:Bool, err:CFError!) in
                if granted {
                    self.adbk = adbk
                } else {
                    println(err)
                }//if
            }//ABAddressBookReqeustAccessWithCompletion
        }//case
    }//if
}//viewDidAppear

然后绑定到 showPicker 的按钮显示人员选择器 UI:

var person: ABRecord!

@IBAction func showPicker(sender: AnyObject) {
    var picker: ABPeoplePickerNavigationController =  ABPeoplePickerNavigationController()

    picker.peoplePickerDelegate = self
    self.presentViewController(picker, animated: true, completion:nil)
}//showPicker

选择联系人后,我会尝试更新该 ABRecordRef! "person" 使用 ABRecordSetValue,它返回 true,并且 firstName 道具的值显示新值,所以我不确定出了什么问题:

func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, didSelectPerson person: ABRecordRef!) -> Bool {
    self.person = person
    println(ABRecordCopyValue(person, kABPersonFirstNameProperty).takeUnretainedValue())
    var updateSucceeded = ABRecordSetValue(person,  kABPersonFirstNameProperty, "New First Name", nil)
    println("Did the update succeed? \(updateSucceeded)")
    println(ABRecordCopyValue(person, kABPersonFirstNameProperty).takeUnretainedValue())
    ABAddressBookSave(adbk, nil)
    println(ABRecordCopyValue(person, kABPersonFirstNameProperty).takeUnretainedValue())
}//navController

(缺乏)进度更新: 在 Apple 发誓后,我终于在我的 iPhone 5 上构建了工作(必须将 didSelectPerson 更改为 shouldContinueAfterSelectingProgram,因为前者仅适用于 iOS8,后者是 iOS 7,在 iOS8 中已弃用)

结果与 sim 稍有不同 - 虽然 ABRecordSetValue 和 ABAddressBookSave 都表示成功,但在手机中,保存后的 ABRecordCopyValue 返回旧的、未更改的名称。在 sim 中,它返回更改后的名称,但 UI 不反映该更改。

【问题讨论】:

    标签: swift


    【解决方案1】:

    终于弄明白了,虽然我不得不承认我不明白为什么修复有效。

    问题 - 我正在针对 adbk 运行 ABAddressBookSave,但它不起作用

    解决方案 - 针对 self.adbk 运行 ABAddressBookSave

    我稍微更新了 peoplePicker 方法,所以这是我最新的:

    //This method shouldContinueAfterSelectingPerson only works in iOS 7.0 and is deprecated in 8.0, but the 8.0 method doesn't exist in 7.0 so using this to test on my 7.1 phone
    func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, shouldContinueAfterSelectingPerson person: ABRecordRef!) -> Bool {
        self.adbk = peoplePicker.addressBook
        self.person = person
        println(ABRecordCopyValue(person, kABPersonFirstNameProperty).takeUnretainedValue())
    
        //Gets the recordId of a person such as 1,2,3,4,5.  Note this number may change if somone backs up their contacts from iCloud or something like that
        var pId = ABRecordGetRecordID(person)
        println(pId)
    
        updateFirstAndLastName()
        return false
    }//navController
    
    func updateFirstAndLastName(){
    //Note this next line no longer works in Xcode 6.1 so I'm commenting it out and replacing error with nil
        //var error:UnsafeMutablePointer<Unmanaged<CFError>?>=nil
    
        var updateSucceeded = ABRecordSetValue(self.person,  kABPersonFirstNameProperty, "aa", nil)
        println("Did the update succeed? \(updateSucceeded)")
        //println("Error: \(error)")
    
        println(ABRecordCopyValue(self.person, kABPersonFirstNameProperty).takeUnretainedValue())
    
        var addressBookSave = ABAddressBookSave(self.adbk, nil)
        println("Did the addressbook save succeed? \(addressBookSave)")
        //println("Error: \(error)")
    
        println(ABRecordCopyValue(self.person, kABPersonFirstNameProperty).takeUnretainedValue())
    }//udpateFirstAndLastName
    

    如果我了解 self 如何工作的详细信息以及为什么这个范围界定在我的其他类级别 var 没有工作的情况下工作,我会更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-10
      • 2015-11-09
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 2014-07-13
      相关资源
      最近更新 更多