2016-08-19 17 views
5

मैं सिर्फ फोन नंबर से नाम और परिवार का नाम संपर्क प्राप्त करना चाहता हूं। मैंने कोशिश की लेकिन यह बहुत धीमी है और सीपीयू 120% से अधिक है।आईओएस संपर्क फ़ोन नंबर से संपर्क कैसे प्राप्त करें

let contactStore = CNContactStore() 
      let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] 
      var contacts = [CNContact]() 
      do { 
       try contactStore.enumerateContactsWithFetchRequest(CNContactFetchRequest.init(keysToFetch: keys), usingBlock: { (contact, cursor) in 
        if (!contact.phoneNumbers.isEmpty) { 
         for phoneNumber in contact.phoneNumbers { 
          if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { 
           do { 
            let libPhone = try util.parseWithPhoneCarrierRegion(phoneNumberStruct.stringValue) 
            let phoneToCompare = try util.getNationalSignificantNumber(libPhone) 
            if formattedPhone == phoneToCompare { 
             contacts.append(contact) 
            } 
           }catch { 
            print(error) 
           } 
          } 

         } 
        } 
       }) 
       if contacts.count > 0 { 
        contactName = (contacts.first?.givenName)! + " " + (contacts.first?.familyName)! 
        print(contactName) 
        completionHandler(contactName) 
       } 
      }catch { 
       print(error) 
      } 

इसके अलावा जब मैं खोजने के संपर्कों के लिए फ़ोन नंबर की किट अपनी बढ़ती सीपीयू और देर से प्रतिक्रिया देने का प्रयोग करें।

var result: [CNContact] = [] 
     let nationalNumber = PhoneNumberKit().parseMultiple([phoneNumber]) 
     let number = nationalNumber.first?.toNational() 
     print(number) 

     for contact in self.addressContacts { 
      if (!contact.phoneNumbers.isEmpty) { 

       let phoneNumberToCompareAgainst = number!.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") 
       for phoneNumber in contact.phoneNumbers { 
        if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { 
         let phoneNumberString = phoneNumberStruct.stringValue 
         let nationalContactNumber = PhoneNumberKit().parseMultiple([phoneNumberString]) 
         let nationalContactNumberString = nationalContactNumber.first?.toNational() 
         if nationalContactNumberString == number { 
          result.append(contact) 
         } 
        } 
       } 
      } 
     } 

     return result 
+0

कोई सुझाव या सहायता? –

+0

ऐसा नहीं लगता कि यह संभव है – user3237732

+0

मैं सिर्फ फोन नंबर से नाम और उपनाम प्राप्त करने की कोशिश कर रहा हूं और इसे प्राप्त नहीं कर सकता? यह दिलचस्प है तो व्हाट्सएप यह कैसे कर सकता है? –

उत्तर

13

आपके कार्यान्वयन के साथ समस्या यह है कि आप जो भी खोज कर रहे हैं उसमें आप एड्रेस बुक तक पहुंच सकते हैं।

यदि आप पहले पहुंच के बाद एड्रेस बुक सामग्री को याद करते हैं तो आप इस उच्च CPU उपयोग तक नहीं पहुंचेंगे।

  1. सबसे पहले अपने नियंत्रक में एक आलसी वर कि पता पुस्तिका सामग्री का आयोजन करेगा पकड़:

    lazy var contacts: [CNContact] = { 
        let contactStore = CNContactStore() 
        let keysToFetch = [ 
         CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), 
         CNContactEmailAddressesKey, 
         CNContactPhoneNumbersKey, 
         CNContactImageDataAvailableKey, 
         CNContactThumbnailImageDataKey] 
    
        // Get all the containers 
        var allContainers: [CNContainer] = [] 
        do { 
         allContainers = try contactStore.containersMatchingPredicate(nil) 
        } catch { 
         print("Error fetching containers") 
        } 
    
        var results: [CNContact] = [] 
    
        // Iterate all containers and append their contacts to our results array 
        for container in allContainers { 
         let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier) 
    
         do { 
          let containerResults = try  contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch) 
          results.appendContentsOf(containerResults) 
         } catch { 
          print("Error fetching results for container") 
         } 
        } 
    
        return results 
    }() 
    
      इन-स्मृति सरणी के माध्यम से
    1. दोहराएं जब आप देख रहे हैं एक विशिष्ट फोन नंबर के साथ संपर्क के लिए:

    func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] { 
        var result: [CNContact] = [] 
    
        for contact in self.contacts { 
         if (!contact.phoneNumbers.isEmpty) { 
          let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") 
          for phoneNumber in contact.phoneNumbers { 
           if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { 
            let phoneNumberString = phoneNumberStruct.stringValue 
            let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") 
            if phoneNumberToCompare == phoneNumberToCompareAgainst { 
             result.append(contact) 
            } 
           } 
          } 
         } 
        } 
    
        return result 
    } 
    

मैं एक बहुत बड़ी पता पुस्तिका के साथ यह परीक्षण किया है, इसे सुचारू रूप से काम करता है।

यहां संपूर्ण दृश्य नियंत्रक संदर्भ के लिए एक साथ पैच किया गया है।

import UIKit 
import Contacts 

class ViewController: UIViewController { 

    lazy var contacts: [CNContact] = { 
     let contactStore = CNContactStore() 
     let keysToFetch = [ 
       CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), 
       CNContactEmailAddressesKey, 
       CNContactPhoneNumbersKey, 
       CNContactImageDataAvailableKey, 
       CNContactThumbnailImageDataKey] 

     // Get all the containers 
     var allContainers: [CNContainer] = [] 
     do { 
      allContainers = try contactStore.containersMatchingPredicate(nil) 
     } catch { 
      print("Error fetching containers") 
     } 

     var results: [CNContact] = [] 

     // Iterate all containers and append their contacts to our results array 
     for container in allContainers { 
      let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier) 

      do { 
       let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch) 
       results.appendContentsOf(containerResults) 
      } catch { 
       print("Error fetching results for container") 
      } 
     } 

     return results 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     let contact = searchForContactUsingPhoneNumber("(555)564-8583") 
     print(contact) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] { 

     var result: [CNContact] = [] 

     for contact in self.contacts { 
      if (!contact.phoneNumbers.isEmpty) { 
       let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") 
       for phoneNumber in contact.phoneNumbers { 
        if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { 
         let phoneNumberString = phoneNumberStruct.stringValue 
         let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") 
         if phoneNumberToCompare == phoneNumberToCompareAgainst { 
          result.append(contact) 
         } 
        } 
       } 
      } 
     } 

     return result 
    } 
} 

मैं आलसी वर भाग के लिए flohei's answer इस्तेमाल किया।

+1

हाँ यह तेज़ है लेकिन मुझे मेरी सूची में सभी नंबर नहीं मिल रहे हैं। उदाहरण के लिए मुझे एक संपर्क लाने की आवश्यकता है लेकिन मेरे पास देश कोड के साथ नंबर है। तो अगर देश कोड द्वारा संपर्क सहेजा नहीं जाता है तो मैं इसे नहीं ला सकता हूं। इस –

+1

के लिए मुझे क्या करना चाहिए असल में यह आपके द्वारा मूल रूप से पूछे जाने वाले एक अलग प्रश्न है। आप केवल उपयोगकर्ता इनपुट संख्याओं और पता पुस्तिका से संख्याओं को उसी प्रारूप पर प्रारूपित करने के लिए प्रारूपित कर सकते हैं, आप इसके लिए बाहरी लाइब्रेरी का उपयोग कर सकते हैं (जैसे https://github.com/marmelroy/PhoneNumberKit)। –

+0

एक और विकल्प देश कोड को हटाना है - यदि यह अस्तित्व में है। फिर बस विमान संख्या की तुलना करें। –

संबंधित मुद्दे