当Alamofire下载时应用程序冻结

时间:2016-05-11 07:41:12

标签: swift alamofire

我希望在下载数据时使用我的应用。不想被装载机困扰。我正在执行几个alamofire GET调用。在做事时我需要有什么平滑的应用程序。

    let headers = [ "header" : "pass"
    ]

    var nextCheck = next

    if(next > count){
        let tempN = next - 1000
        nextCheck = count - tempN
    }

    Alamofire.request(.GET, urlDomain + "_table1?offset=\(nextCheck)", headers: headers, encoding: .URL)
        .responseJSON() { response in

            if response.result.isSuccess {

                let json = JSON(response.result.value!)
                //print(json)
                let done = true
                var doneDownloading = false

                for i in 0..<json["resource"].count {

                    let id_pobor = json["resource"][i]["id_bor"].stringValue
                    let misto = json["resource"][i]["mio"].stringValue
                    let nazev_oc = json["resource"][i]["naze"].stringValue
                    let tel = json["resource"][i]["tel"].stringValue
                    let ulice = json["resource"][i]["uli"].stringValue
                    let exp_logo = json["resource"][i]["logo"].stringValue


                    let count = json["meta"]["count"].intValue
                    let next = json["meta"]["next"].intValue

                    if(i == json["resource"].count - 1){
                        doneDownloading = true
                    }

                    completionHandler(done, id_pobor, misto, nazev_oc, gpsn, tel, ulice, exp_logo, gpse, id_obor, www, Id_prov, cinnost, psc, id_region, id_oblast, logo, provoz, eshop, count, next, doneDownloading)
                }

                if(json["resource"].count == 0){
                    completionHandler(done, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, 0, true)
                }
            } else {
                completionHandler(false, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, 0, true)
            }

这种方法使用多个偏移分页多次完成。

这就是我称之为这种方法的方法。我正在使用REALM来存储它。我正在加载4万多行

 private func getDataForE21Table(){
    self.getReq.getE21(nextOffsetE21, count: countOffsetE21) { (done, id_pobor, misto, nazev_oc, gpsn, tel, ulice, exp_logo, gpse, id_obor, www, Id_prov, cinnost, psc, id_region, id_oblast, logo, provoz, eshop, count, next, doneDownloading) in
        if(done){
            self.saveToRealm.saveE21(id_pobor, misto: misto, nazev_oc: nazev_oc, gpsn: gpsn, tel: tel, ulice: ulice, exp_logo: exp_logo, gpse: gpse, id_obor: id_obor, www: www, Id_prov: Id_prov, cinnost: cinnost, psc: psc, id_oblast: id_oblast, logo: logo, provoz: provoz)
            if(doneDownloading){
                self.s.saveTableDates(self.s.e21Time, forKey: "e21Time")
                self.nextOffsetE21 = self.nextOffsetE21 + 1000
                self.countOffsetE21 = count
                NSNotificationCenter.defaultCenter().postNotificationName("loadMoreDataE21", object: nil)
            }
        } else {
            SwiftLoader.hide()
        }
    }
}

我的课程需要在后台运行

    import Foundation
import SwiftLoader
import RealmSwift

class Synchronize {

    private let getReq = GetReq()
    private let postReq = PostReq()
private let saveToRealm = SavaDataToRealmDatabase()
private let arrOfTables = ["e21", "e21sle", "evi22", "evi23oc", "regiony"]
private let s = Session.sharedInstance
private var nextOffsetE21Sle = 0
private var countOffsetE21Sle = 1000
private var nextOffsetE21 = 0
private var countOffsetE21 = 1000

func syncDb(){
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        self.getSessionToken()
    })
}

private func getSessionToken(){
    postReq.sessionTokenRefresh { (done) in
        if(done){
            self.getReq.getTimeStampOfUpdatedTables({ (done) in
                if(done){
                    if(self.s.e21TimeNeedUpdate){
                        self.deleteObject(1)
                        self.getDataForE21Table()
                    } else {
                        Session.sharedInstance.progress += 0.2
                        NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
                    }
                    if(self.s.e21sleTimeNeedUpdate){
                        self.deleteObject(2)
                        self.getDataForE21sleTable()
                    } else {
                        Session.sharedInstance.progress += 0.2
                        NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
                    }
                    if(self.s.evi22TimeNeedUpdate){
                        self.deleteObject(3)
                        self.getDataForE22()
                    } else {
                        Session.sharedInstance.progress += 0.2
                        NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
                    }
                    if(self.s.evi23ocTimeNeedUpdate){
                        self.deleteObject(4)
                        self.getDataForE23()
                    } else {
                        Session.sharedInstance.progress += 0.2
                        NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
                    }
                    if(self.s.regionTimeNeedUpdate){
                        self.deleteObject(5)
                        self.getDataForRegion()
                    } else {
                        Session.sharedInstance.progress += 0.2
                        NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
                    }
                }
            })
        } else {
            SwiftLoader.hide()
        }
    }
}

private func loadMoreDataE21Sle(){
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        if(self.nextOffsetE21Sle <= self.countOffsetE21Sle) {
            self.getDataForE21sleTable()
        } else {
            Session.sharedInstance.progress += 0.2
            NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
        }
    })
}

private func loadMoreDataE21(){
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        print("backgroundThread")
        if(self.nextOffsetE21 <= self.countOffsetE21) {
            self.getDataForE21Table()
        } else {
            Session.sharedInstance.progress += 0.2
            NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
        }
    })
}

private func getDataForE21Table(){
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

        self.getReq.getE21(self.nextOffsetE21, count: self.countOffsetE21) { (done, id_pobor, misto, nazev_oc, gpsn, tel, ulice, exp_logo, gpse, id_obor, www, Id_prov, cinnost, psc, id_region, id_oblast, logo, provoz, eshop, count, next, doneDownloading) in
            if(done){
                self.saveToRealm.saveE21(id_pobor, misto: misto, nazev_oc: nazev_oc, gpsn: gpsn, tel: tel, ulice: ulice, exp_logo: exp_logo, gpse: gpse, id_obor: id_obor, www: www, Id_prov: Id_prov, cinnost: cinnost, psc: psc, id_oblast: id_oblast, logo: logo, provoz: provoz)
                if(doneDownloading){
                    self.s.saveTableDates(self.s.e21Time, forKey: "e21Time")
                    self.nextOffsetE21 = self.nextOffsetE21 + 1000
                    self.countOffsetE21 = count
                    self.loadMoreDataE21()
                }
            } else {
                SwiftLoader.hide()
            }
        }
    })
}

private func getDataForE21sleTable(){
    self.getReq.getE21sle(nextOffsetE21Sle, count: countOffsetE21Sle) { (done, vyse_sle, druh_sle, popis_sle, id_pobor, id_sle, id_prov, count, next, carte, doneDownloading) in
        if(done){
            self.saveToRealm.saveE21sle(vyse_sle, druh_sle: druh_sle, popis_sle: popis_sle, id_pobor: id_pobor, id_sle: id_sle, id_prov: id_prov, carte: carte)
            if(doneDownloading){
                self.s.saveTableDates(self.s.e21sleTime, forKey: "e21sleTime")
                self.nextOffsetE21Sle = self.nextOffsetE21Sle + 1000
                self.countOffsetE21Sle = count
                self.loadMoreDataE21Sle()
            }
        } else {
            SwiftLoader.hide()
        }
    }
}

private func getDataForE22(){
    self.getReq.getE22 { (done, id_skup, skuptxt_sk, id_obor, skuptxt_cz, obortxt_sk, obortxt_cz, doneDownloading) in
        if(done){
            self.saveToRealm.saveE22(id_skup, skuptxt_sk: skuptxt_sk, id_obor: id_obor, skuptxt_cz: skuptxt_cz, obortxt_sk: obortxt_sk, obortxt_cz: obortxt_cz)
            if(doneDownloading){
                Session.sharedInstance.progress += 0.2
                self.s.saveTableDates(self.s.evi22Time, forKey: "evi22Time")
                NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
            }
        } else {
            SwiftLoader.hide()
        }
    }
}

private func getDataForE23(){
    self.getReq.getE23oc { (done, nazev, psc, id_oc, oblast, sphere, misto, region, stat, statut, adresa, public_, doneDownloading) in
        if(done){
            self.saveToRealm.saveE23(nazev, psc: psc, id_oc: id_oc, oblast: oblast, sphere: sphere, misto: misto, region: region, stat: stat, statut: statut, adresa: adresa, public_: public_)
            if(doneDownloading){
                Session.sharedInstance.progress += 0.2
                self.s.saveTableDates(self.s.evi23ocTime, forKey: "evi23ocTime")
                NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
            }
        } else {
            SwiftLoader.hide()
        }
    }
}

private func getDataForRegion(){
    self.getReq.getRegiony { (done, oblast, lokalita, okres, poradi, uroven, doneDownloading) in
        if(done){
            self.saveToRealm.saveRegion(oblast, lokalita: lokalita, okres: okres, poradi: poradi, uroven: uroven)
            if(doneDownloading){
                Session.sharedInstance.progress += 0.2
                self.s.saveTableDates(self.s.regionTime, forKey: "regionTime")
                NSNotificationCenter.defaultCenter().postNotificationName("checkForLoadedData", object: nil)
            }
        } else {
            SwiftLoader.hide()
        }
    }
}

private func deleteObject(id:Int){
    let realm = try! Realm()
    try! realm.write {
        switch id {
        case 1: realm.delete(realm.objects(E21))
        case 2: realm.delete(realm.objects(E21sle))
        case 3: realm.delete(realm.objects(E22))
        case 4: realm.delete(realm.objects(E23oc))
        case 5: realm.delete(realm.objects(Regiony))
        default:break
        }
    }
}

}

1 个答案:

答案 0 :(得分:6)

默认情况下,Alamofire会在主队列(source)上调度响应处理程序。但是,您可以使用response()方法的queue:参数指定另一个参数,以保持UI响应:

    Alamofire.request(.GET, urlDomain + "_table/e21?offset=\(nextCheck)", headers: headers, encoding: .JSON)
        .responseJSON(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { response in

请记住,如果您在响应处理程序中执行UI更新,则需要在主队列中执行此操作:

dispatch_async(dispatch_get_main_queue()) {
    // update some UI
}