2017-10-25 19 views
5

मुझे नहीं पता कि यह प्रश्न यहां होने के योग्य है या नहीं, लेकिन बहुत सारे शोध के बाद भी, मुझे उपयुक्त मार्गदर्शिका नहीं मिली इस सवाल के लिए। मुझे आशा है कि मुझे यहां एक जवाब मिलेगा।आईओएस मैसेजिंग ऐप जैसे Viber, टेलीग्राम, व्हाट्सएप संपर्क इतने तेज़ और कुशलता से प्राप्त करते हैं

मुझे लगता है कि Viber, व्हाट्सएप, टेलीग्राम जैसे सभी मैसेजिंग ऐप्स उपयोगकर्ता संपर्क लाते हैं और उन्हें इतनी तेजी से और कुशलतापूर्वक पार्स करते हैं कि लगभग शून्य देरी होती है। मैं इसे दोहराने की कोशिश कर रहा था लेकिन कभी सफल नहीं था। पृष्ठभूमि थ्रेड पर पूरे ऑपरेशन को चलाकर 3000 संपर्कों को पार्स करने में हमेशा 40-60 सेकंड का समय लगता है। यहां तक ​​कि 5 और 5 एस जैसे धीमे उपकरणों पर UI को ठंडा कर रहा है। संपर्क लाने के बाद मुझे उन्हें बैकएंड पर भेजना होगा ताकि यह पता चल सके कि कौन सा उपयोगकर्ता मंच पर पंजीकृत है जो कुल समय तक भी जोड़ता है। उपर्युक्त ऐप्स यह किसी भी समय में नहीं करता है!

मुझे खुशी होगी अगर कोई मुख्य धागे को अवरुद्ध किए बिना संपर्कों को सबसे कुशल और तेज़ तरीके से पार्स करने का तरीका सुझा सकता है।

यहां कोड है, मैं इस समय उपयोग करता हूं।

final class CNContactsService: ContactsService { 

private let phoneNumberKit = PhoneNumberKit() 
private var allContacts:[Contact] = [] 

private let contactsStore: CNContactStore 


init(network:Network) { 
    contactsStore = CNContactStore() 
    self.network = network 
} 

func fetchContacts() { 
    fetchLocalContacts { (error) in 
     if let uError = error { 

     } else { 
      let contactsArray = self.allContacts 
      self.checkContacts(contacts: contactsArray, checkCompletion: { (Users) in 
       let nonUsers = contactsArray.filter { contact in 
        return !Users.contains(contact) 
       } 
       self.Users.value = Users 
       self.nonUsers.value = nonUsers 
      }) 
     } 
    } 

} 

func fetchLocalContacts(_ completion: @escaping (NSError?) -> Void) { 
    switch CNContactStore.authorizationStatus(for: CNEntityType.contacts) { 
    case CNAuthorizationStatus.denied, CNAuthorizationStatus.restricted: 
     //User has denied the current app to access the contacts. 
     self.displayNoAccessMsg() 
    case CNAuthorizationStatus.notDetermined: 
     //This case means the user is prompted for the first time for allowing contacts 
     contactsStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (granted, error) -> Void in 
      //At this point an alert is provided to the user to provide access to contacts. This will get invoked if a user responds to the alert 
      if (!granted){ 
       DispatchQueue.main.async(execute: {() -> Void in 
        completion(error as! NSError) 
       }) 
      } else{ 
       self.fetchLocalContacts(completion) 
      } 
     }) 

    case CNAuthorizationStatus.authorized: 
     //Authorization granted by user for this app. 
     var contactsArray = [EPContact]() 
     let contactFetchRequest = CNContactFetchRequest(keysToFetch: allowedContactKeys) 
     do { 
      //    let phoneNumberKit = PhoneNumberKit() 
      try self.contactsStore.enumerateContacts(with: contactFetchRequest, usingBlock: { (contact, stop) -> Void in 
       //Ordering contacts based on alphabets in firstname 
       if let contactItem = self.contactFrom(contact: contact) { 
       contactsArray.append(contactItem) 
       } 
      }) 
      self.allContacts = contactsArray 
      completion(nil) 
     } catch let error as NSError { 
      print(error.localizedDescription) 
      completion(error) 
     } 
    } 
} 

private var allowedContactKeys: [CNKeyDescriptor]{ 
    //We have to provide only the keys which we have to access. We should avoid unnecessary keys when fetching the contact. Reducing the keys means faster the access. 
    return [ 
     CNContactGivenNameKey as CNKeyDescriptor, 
     CNContactFamilyNameKey as CNKeyDescriptor, 
     CNContactOrganizationNameKey as CNKeyDescriptor, 
     CNContactThumbnailImageDataKey as CNKeyDescriptor, 
     CNContactPhoneNumbersKey as CNKeyDescriptor, 
    ] 
} 

private func checkUsers(contacts:[Contact],checkCompletion:@escaping ([Contact])->Void) { 
    let phoneNumbers = contacts.flatMap{$0.phoneNumbers} 
    if phoneNumbers.isEmpty { 
     checkCompletion([]) 
     return 
    } 
    network.request(.registeredContacts(numbers: phoneNumbersList), completion: { (result) in 
     switch result { 
     case .success(let response): 
      do { 
       let profiles = try response.map([Profile].self) 
       let contacts = profiles.map{ CNContactsService.contactFrom(profile: $0) } 
       checkCompletion(contacts) 
      } catch { 
       checkCompletion([]) 
      } 
     case .failure: 
      checkCompletion([]) 
     } 
    }) 
} 

static func contactFrom(profile:Profile) -> Contact { 
    let firstName = "" 
    let lastName = "" 
    let company = "" 
    var displayName = "" 
    if let fullName = profile.fullName { 
     displayName = fullName 
    } else { 
     displayName = profile.nickName ?? "" 
    } 
    let numbers = [profile.phone!] 
    if displayName.isEmpty { 
     displayName = profile.phone! 
    } 
    let contactId = String(profile.id) 

    return Contact(firstName: firstName, 
        lastName: lastName, 
        company: company, 
        displayName: displayName, 
        thumbnailProfileImage: nil, 
        contactId: contactId, 
        phoneNumbers: numbers, 
        profile: profile) 
} 

private func parsePhoneNumber(_ number: String) -> String? { 
    do { 
     let phoneNumber = try phoneNumberKit.parse(number) 
     return phoneNumberKit.format(phoneNumber, toType: .e164) 
    } catch { 
     return nil 
    } 
} 


}` 

और संपर्क यहाँ लाई जाती हैं एप्लिकेशन शुरू की है

private func ApplicationLaunched() { 
    DispatchQueue.global(qos: .background).async { 
     let contactsService:ContactsService = self.serviceHolder.get() 
     contactsService.fetchContacts() 
    } 
+0

बस एक सवाल है, क्या आपने 'अनुमति कॉन्टैक्टकेस' के साथ खेलने की कोशिश की है? हो सकता है कि 'सीएनकॉन्टैक्ट थंबनेल इमेजडेटाकी' 3000 संपर्कों के लिए बहुत भारी है? मैंने कभी भी उन कई संपर्कों के लिए कोशिश नहीं की, लेकिन मैं अपने ऐप में लगभग तुरंत 200 संपर्क ला रहा हूं, लेकिन मैं थंबनेल छवि का अनुरोध नहीं कर रहा हूं। – TawaNicolas

+0

क्या आपने उन्हें बैच में लाने की कोशिश की है? – swift2geek

+0

निश्चित नहीं है लेकिन मुझे लगता है कि व्हाट्सएप पहली बार खुली ऐप के रूप में संपर्कों को समन्वयित करना प्रारंभ कर रहा है। इसे पढ़ें https://www.quora.com/How-does-the-contacts-sync-work-in-WhatsApp/answer/Jinesh-Soni?srid=RhqE –

उत्तर

1

मेरा अनुमान है कि आप बैकएंड के लिए भेज रहे हैं संपर्कों की संख्या बहुत बड़ा है। 3000 संपर्क बहुत अधिक हैं और मुझे लगता है कि निम्न में से एक हो रहा है:

  1. या तो अनुरोध बहुत बड़ा है और बैकएंड के लिए समय देने में समय लगता है।
  2. बैकएंड के लिए यह बहुत भारी है और इसमें ग्राहक को प्रक्रिया करने और वापस आने में समय लगता है, और यही कारण है कि आपके लिए देरी हो रही है।

कम से कम होने की संभावना समस्या है:

  1. आपका पार्स विधि CPU पर बहुत भारी है। लेकिन यह बहुत ही असंभव है।

क्या आपने पार्सिंग शुरू होने और समाप्त होने के बीच की अवधि को माप लिया था?

मुझे लगता है कि आप उन सभी कार्यों आप कर रहे हैं, उदाहरण के लिए के बीच की अवधि को मापने चाहिए:

  1. उपाय कब तक यह डिवाइस से संपर्कों को लाने के लिए ले जाता है।
  2. मापें कि संपर्कों को पार्स करने में कितना समय लगता है।
  3. मापें बैकएंड से प्रतिक्रिया प्राप्त करने में कितना समय लगता है।

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

मुझे आशा है कि इससे आपकी समस्या को हल करने में मदद मिलेगी।

+0

धन्यवाद @ टावानिकोलस। आपके समाधान ने वास्तव में मुझे समस्या का पता लगाने में मदद की। यह 3 है, आपने उल्लेख किया है कि समस्या पैदा कर रही है। हम संख्याओं को पार्स करने के लिए फोन नम्बरकिट का उपयोग कर रहे हैं और देश कोड जोड़ सकते हैं, जो बहुत धीमी है और हर समय ले रहा है। मैं libPhoneNumber-iOS में स्थानांतरित हो गया जो पूरी तरह से काम कर रहा है। 2 9 00 संपर्कों को लाने और पार्स करने के लिए समय 65 सेकंड से 3 सेकंड तक आ गया है, जिसमें नेटवर्क कॉल –

+0

भी शामिल है, यूआई फ्रीजिंग एरे फ़िल्टर करने के कारण होती है। एक बार जब हम सर्वर से प्रतिक्रिया प्राप्त कर लेते हैं, तो मैं सभी फोन नंबरों को एक सरणी में संग्रहीत करता हूं और इसे सभी संपर्कों की सरणी से तुलना करता हूं और हमारे प्लेटफ़ॉर्म पर मौजूद सभी संपर्कों के साथ एक नई सरणी बना देता हूं। चूंकि यह मुख्य थ्रेड पर हो रहा है, यूआई को अवरुद्ध कर दिया गया है कि वैश्विक उपयोगिता धागे ने यूआई अवरोध को रोका है। साथ ही, संपर्क लाने के लिए इसे उपयोगिता धागे में स्थानांतरित कर दिया गया है ताकि इसे तेज़ी से लाया जा सके। –

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