某些设备中的联系人加载速度太慢

时间:2017-10-04 04:55:04

标签: ios swift xcode

我正在使用以下代码从电话簿加载联系人,但在某些iPhone设备中加载非常慢。甚至联系人都在后台线程中加载。在某些设备中,它可以快速加载触点,但在某些设备中它的速度太慢。

我该如何解决这个问题?

//调用返回联系人的方法

DispatchQueue.global(qos: .background).async {
            self.contacts = self.returnContacts(searchBy: nil)
            DispatchQueue.main.async {
                self.tblView.reloadData()
            }
        } 

//返回联系人的方法

func returnContacts(searchBy:String?) -> NSArray {


            let status = CNContactStore.authorizationStatus(for: .contacts)


            if (status == .denied || status == .restricted) {

                DispatchQueue.main.async {
                    let alertController = UIAlertController(title: "", message: "This app previously was refused permissions to contacts. Please go to settings and grant permission to this app so it can use contacts", preferredStyle: .alert)
                    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))

                    self.present(alertController, animated: true, completion: nil)
                }

                return NSArray()

            }

            let contactStore = CNContactStore()
            let keysToFetch = [
                CNContactFormatter.descriptorForRequiredKeys(for: .fullName),

                CNContactPhoneNumbersKey] as [Any]
            // Get all the containers

            var results: [CNContact] = []

            do {

                    var allContainers: [CNContainer] = []
                     allContainers = try contactStore.containers(matching: nil)

                     // Iterate all containers and append their contacts to our results array
                    for container in allContainers {
                        let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)
                        do {
                            let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keysToFetch as! [CNKeyDescriptor])

                            results.append(contentsOf: containerResults)
                        } catch {
                            //print("Error fetching results for container")
                        }
                    }
              //  }

            } catch {
               // print("Error fetching containers")
            }
        //    print(results)

            results.sort{$0.givenName < $1.givenName} // sorting array by name

    // Converting Array of CNContatcts into array of Dictionaries

            var conatctsArr = Array<Any>()

            for contactDetail in results  {
                var contactDic = Dictionary<String, String>()
                contactDic["givenName"] = contactDetail.givenName + " " +
                contactDetail.familyName
                let phoneNumbers : [CNLabeledValue<CNPhoneNumber>] = contactDetail.phoneNumbers

                for number in phoneNumbers {
                    contactDic["phoneNumber"] = number.value.stringValue
                    conatctsArr.append(contactDic)

                }
            }

            // filter array

            if searchBy != nil {
                let predicate=NSPredicate(format: "SELF.givenName CONTAINS[cd] %@", searchBy!)
                let mobileNumberpredicate = NSPredicate(format: "phoneNumber CONTAINS[cd] %@", searchBy!)
                let compoundPredicate = NSCompoundPredicate.init(type: .or, subpredicates: [predicate,mobileNumberpredicate])
                let arr = (conatctsArr as NSArray).filtered(using: compoundPredicate) as NSArray

                conatctsArr = arr as! Array<Any>
            }

            ///////////////////////////


     //Arranging array of contatcts in sections

            let finalArr = NSMutableArray()

            for contactDetail in conatctsArr {

                var contactDic = Dictionary<String, String>()
                contactDic = contactDetail as! Dictionary
                let name = contactDic["givenName"] ?? ""// Getting First character of name
                var key = String()
                if name.characters.count > 0 {
                    let index1 = name.index((name.startIndex), offsetBy: 1)
                    key = name.substring(to: index1)
                }
                else {
                    key = ""
                }
                // getting all contatcts starting with particular character
                let predicate=NSPredicate(format: "SELF.givenName beginswith[c] %@",key )
                let filteredArr = (conatctsArr as NSArray).filtered(using: predicate)

                var dic = Dictionary<String, Any>()
                dic["key"] = key
                dic["values"] = filteredArr

                if filteredArr.count > 0  && !(finalArr.contains(dic)) {
                    finalArr.add(dic)
                }
            }
            return finalArr
        }

1 个答案:

答案 0 :(得分:0)

我会尝试更高优先级的QoS级别,如User-initiated。来自docs

  

后台:在后台运行并且对用户不可见的工作,例如索引,同步和备份。重点关注能源效率。

     

用户启动:用户已启动的工作,需要立即生成结果,例如在用户点击用户界面中的内容时打开已保存的文档或执行操作。需要这项工作才能继续用户互动。重点关注响应能力和绩效。

我怀疑在您的情况下,在旧设备上,background任务正在以先进先出的方式完成,并且优先级非常低,导致数据返回缓慢。