Alterplay / APAddressBook

Easy access to iOS address book
MIT License
1.38k stars 193 forks source link

startObserveChangesWithCallback bug #125

Open gbmiranda opened 8 years ago

gbmiranda commented 8 years ago

I'm having problems with the "startObserveChangesWithCallback" on devices that have many contacts. The function is called many times in a row without the contacts has actually been changed.

For my code, something is wrong in the flow?

Att, Gabriel

Code:

class AddressBook: NSObject {

    static let addressBook = APAddressBook()

    static var timer = NSTimer()

    static var phones: [SendContatoDTO] = []

    static var listaTodosContatos: [Contato] = []

    class func carregaListaContatos(){

        listaTodosContatos = []

        if accessGaranted() == false{
            return
        }

        addressBook.fieldsMask = [APContactField.PhonesOnly, APContactField.Name, APContactField.LinkedRecordIDs]

        addressBook.filterBlock = {
            (contact: APContact) -> Bool in
            if let phones = contact.phones {
                return phones.count > 0
            }
            return false
        }

        addressBook.startObserveChangesWithCallback {

            print("addressBook.startObserveChangesWithCallback")
            loadContacts()

        }

        loadContacts()

    }

    class func loadContacts(){

        addressBook.loadContacts({(contacts: [APContact]?, error: NSError?) in

            if error != nil || contacts == nil{

                print("ERRO AO PEGAR CONTATOS")
                return

            }

            let numPhones = self.phones.count

            self.listaTodosContatos = []
            self.phones = []

            for contact in contacts!{

                let telefones = contact.phones

                if telefones != nil{

                    for telefone in telefones! {

                        let number = Functions.formatAndValidatePhoneNumber(telefone.number!)

                        if number.isEmpty == false{

                            let send = SendContatoDTO()
                            send.id = Int(contact.recordID)
                            send.cellphone = number
                            phones.append(send)

                        }

                        let contato = Contato()
                        contato.cellphone = number

                        var nome = ""

                        if contact.name?.firstName != nil{
                            nome += (contact.name?.firstName)!
                        }

                        if contact.name?.middleName != nil{
                            nome += " \((contact.name?.middleName)!)"
                        }

                        if contact.name?.lastName != nil{
                            nome += " \((contact.name?.lastName)!)"
                        }

                        if nome.isEmpty == false{

                            contato.name = nome
                            contato.isPayMeApp = false
                            contato.id = Int(contact.recordID)
                            listaTodosContatos.append(contato)

                        }

                    }

                }

            }

            if numPhones != self.phones.count{

                self.sendContactsWS()

            }

        })

    }

    static func sendContactsWS(){

        timer.invalidate()

        if Global.usuario == nil{
            return
        }

        if self.phones.count == 0{
            return
        }

        let enviarContatosWS = EnviarContatosWS(success: sucessoGetFriends, failure: erroGetFriends)

        let enviarContatosRequisicao = EnviarContatosRequisicao()
        enviarContatosRequisicao.contacts = self.phones

        enviarContatosWS.enviarContatos(enviarContatosRequisicao)

    }

    static func sucessoGetFriends(dataResponse: AnyObject?){

        let retorno = dataResponse as! EnviarContatosResposta

        if retorno.friends == nil || retorno.friends?.count == 0{
            return
        }

        for contato in retorno.friends!{

            var filtered = self.listaTodosContatos.filter { $0.id == contato.id }

            if filtered.count > 0 {

                filtered[0].isPayMeApp = true
                filtered[0].name = contato.name
                filtered[0].api_key = contato.api_key
                filtered[0].avatar = contato.avatar
                filtered[0].cellphone = contato.cellphone

            }

        }

    }

    static func erroGetFriends(error: RespostaBase){

        print("erro get contatos")
        timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "sendContactsWS", userInfo: nil, repeats: false)

    }

    class func accessGaranted() -> Bool{

        var retorno = false

        let access = APAddressBook.access()

        if access == APAddressBookAccess.Unknown{

            addressBook.requestAccess({ (granted: Bool?, error: NSError?) -> Void in

                if error != nil{
                    print(error?.description)
                }

                if granted == true{

                    retorno = true

                }

            })

        }else if access == APAddressBookAccess.Denied{

            print("Não possuí permissão para acessar os contatos")

        }else if access == APAddressBookAccess.Granted{

            retorno = true

        }

        return retorno

    }   
}
belkevich commented 8 years ago

Sorry for delay. I don't see any problems in your code. But you can try this: 1) Comment startObserveChangesWithCallback. Maybe loadContacts called from another method? 2) Run Example.app from this repo on device with many contacts. Does startObserveChangesWithCallback still called without any changes?