如何在后台加载联系人图像?

Posted

技术标签:

【中文标题】如何在后台加载联系人图像?【英文标题】:How to load contact image in background? 【发布时间】:2017-12-22 06:56:03 【问题描述】:

我正在使用通讯录开发应用程序。我正在显示来自 API 的通话记录,当我显示历史数据时,我会检查联系人是否在通讯录中可用。如果可用,则显示联系人姓名和图像。 我在后台执行此过程,但有时,tableview 卡住并且没有给出任何响应。 我正在使用以下代码来执行上述过程:

for i in (0..<arrdata.count-1)

    self.count = self.count + 1
    let dict_data = arrdata.value(forKey: String(format: "%d", arguments: [i])) as! NSDictionary

    let dict = NSMutableDictionary()
    dict.setValue(dict_data["callstart"], forKey: "callstart")
    dict.setValue(dict_data["notes"], forKey: "notes")
    dict.setValue(dict_data["debit"], forKey: "debit")
    dict.setValue(dict_data["pattern"], forKey: "pattern")
    dict.setValue(dict_data["calltype"], forKey: "calltype")
    dict.setValue(dict_data["billseconds"], forKey: "billseconds")
    dict.setValue(dict_data["disposition"], forKey: "disposition")
    dict.setValue(dict_data["callednum"], forKey: "callnumber")

    DispatchQueue.global(qos: .background).async(execute:
     () -> Void in
        let searchContact = Constants.appDelegate.searchForContactUsingPhoneNumber(phoneNumber: dict_data["callednum"] as? String) as [ContactEntry]
        if searchContact.count == 1
        
            for contact in searchContact
            
                dict.setValue(contact.name, forKey: "callednum")
                dict.setValue(contact, forKey: "historycontact")
                if contact.image == nil
                
                    dict.setValue(nil, forKey: "contactimage")
                
                else
                
                    let new_image = contact.image?.scaleUIImageToSize( image: contact.image!, size: CGSize(width:250,height:250))
                    let imgdata = new_image?.jpeg(.lowest)
                    dict.setValue(imgdata, forKey: "contactimage")


                
            
        
        else
        
            dict.setValue(nil, forKey: "historycontact")
            dict.setValue(dict_data["callednum"], forKey: "callednum")
            dict.setValue(nil, forKey: "contactimage")

        
    )
    dict.setValue(nil, forKey: "historycontact")
    dict.setValue(dict_data["callednum"], forKey: "callednum")
    dict.setValue(nil, forKey: "contactimage")
    dict.setValue(dict_data["callerid"], forKey: "callerid")
    self.arrHistory.append(dict)


DispatchQueue.main.async

    self.tblview.reloadData()

在后台队列中我检查了联系人是否可用。

我需要在后台搜索联系人,并在后台设置数据并在主线程上调用 API。

如果有人对上述问题有解决方案,请帮助我。

谢谢。

【问题讨论】:

【参考方案1】:

我可以在这里看到一些潜在的问题。您在 for 循环中抓取一个后台线程(取决于数据)可能会占用很多线程!这可能是导致您的应用程序无响应的原因。我不完全确定您要实现什么,因为当您的后台线程完成时,您不会重新加载表格视图。

据我所知,您想在一开始就分派到后台队列中,执行所有处理,然后在最后分派回主线程以更新 tableview。比如:

DispatchQueue.global(qos: .background).async(execute:  () -> Void in
    for i in (0..<arrdata.count-1)
    
        self.count = self.count + 1
        let dict_data = arrdata.value(forKey: String(format: "%d", arguments: [i])) as! NSDictionary

        let dict = NSMutableDictionary()
        dict.setValue(dict_data["callstart"], forKey: "callstart")
        dict.setValue(dict_data["notes"], forKey: "notes")
        dict.setValue(dict_data["debit"], forKey: "debit")
        dict.setValue(dict_data["pattern"], forKey: "pattern")
        dict.setValue(dict_data["calltype"], forKey: "calltype")
        dict.setValue(dict_data["billseconds"], forKey: "billseconds")
        dict.setValue(dict_data["disposition"], forKey: "disposition")
        dict.setValue(dict_data["callednum"], forKey: "callnumber")


        let searchContact = Constants.appDelegate.searchForContactUsingPhoneNumber(phoneNumber: dict_data["callednum"] as? String) as [ContactEntry]
        if searchContact.count == 1
        
            for contact in searchContact
            
                dict.setValue(contact.name, forKey: "callednum")
                dict.setValue(contact, forKey: "historycontact")
                if contact.image == nil
                
                    dict.setValue(nil, forKey: "contactimage")
                
                else
                
                    let new_image = contact.image?.scaleUIImageToSize( image: contact.image!, size: CGSize(width:250,height:250))
                    let imgdata = new_image?.jpeg(.lowest)
                    dict.setValue(imgdata, forKey: "contactimage")


                
            
        
        else
        
            dict.setValue(nil, forKey: "historycontact")
            dict.setValue(dict_data["callednum"], forKey: "callednum")
            dict.setValue(nil, forKey: "contactimage")

        
        dict.setValue(nil, forKey: "historycontact")
        dict.setValue(dict_data["callednum"], forKey: "callednum")
        dict.setValue(nil, forKey: "contactimage")
        dict.setValue(dict_data["callerid"], forKey: "callerid")
        self.arrHistory.append(dict)
    

    DispatchQueue.main.async 
        self.tblview.reloadData()
    
)

【讨论】:

感谢您的回答。我会试试你的解决方案。

以上是关于如何在后台加载联系人图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何显示尚未完全加载的图像的缩略图

Launch Image 在后台加载模糊的游戏图像

如何从用户手机获取联系人 URI 并在 android 中使用 glide 加载

如何在后台工作人员运行时在 uwp 中加载图像

使用 webview 启动图像

阻止视频在移动设备的后台加载