具有网络呼叫和完成的Swift Dispatch组

时间:2016-11-07 16:46:44

标签: ios swift xcode swift3 grand-central-dispatch

我有一个函数,我需要获取2个数组的差异并使用完成来返回字典形式的差异。它需要网络调用才能从TVDB api创建一个对象。我尝试使用.enter()和.leave()实现dispatchGroups,一切似乎都以正确的顺序工作(使用断点检查),直到最后一次迭代它在“groupDispatch.leave()”的行上崩溃,没有错误消息在控制台中。

这是有问题的功能:

    func showsToWatch(idArray: [Int], completion:@escaping(_ dict: [Int:[Int]])->Void){
    var toWatch:[Int:[Int]] = [:]

    let groupDispatch = DispatchGroup()


    for id in idArray {
        groupDispatch.enter()

        guard let watchedId = SeriesController.sharedController.watchedDict[id] else {return}

        NetworkController.getEpisodes(id) { (episodes, error) in
            if let episodes = episodes {
                let episodesId = episodes.map({$0.id})

                let difference = episodesId.filter { !watchedId.contains($0) }
                toWatch[id] = difference
            }
        groupDispatch.leave()
        }
    }


    groupDispatch.notify(queue: DispatchQueue.main, execute: { () -> Void in
        completion(toWatch)
    })
}

这是NetworkController.getEpisodes函数:

static func getEpisodes(_ id: Int, completion:@escaping (_ episode: [Episode]?, _ error: NSError?)->Void) {

    NetworkController.getPageCount(id) { (pageCount) in
        var allEpisodes = [Episode]()
        for i in 1...pageCount {
            let idString = String(id)
            let searchUrl = baseUrl + "series/\(idString)/episodes?page=\(i)"
            let searchParam = searchUrl
            let myUrl = URL(string: searchParam)

            var request = URLRequest(url:myUrl!)

            request.httpMethod = "GET"
            request.addValue("application/json", forHTTPHeaderField: "Accept")
            let headerString = "Bearer " + myToken
            request.addValue(headerString, forHTTPHeaderField: "Authorization")

            let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in

                if error != nil {
                    print("error=\(error)")
                    completion(nil, error as NSError?)
                    return
                }

                do {
                    if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {

                        if let dataDict = convertedJsonIntoDict as? [String:AnyObject] {
                            if let dataArray = dataDict["data"] as? [[String:AnyObject]]{
                                for episodeDict in dataArray {

                                    let episode = Episode(dict: episodeDict)
                                    //print("S\(episode.airedSeason)E\(episode.airedEpisodeNumber)")
                                    if episode.absoluteNumber < 0 {
                                        if episode.airedSeason > 0 && episode.airedEpisodeNumber > 0 {
                                            allEpisodes.append(episode)
                                        }
                                    } else {
                                        allEpisodes.append(episode)
                                    }
                                }
                            }
                        }
                    }
                    completion(allEpisodes, nil)
                } catch let error as NSError {
                    print(error.localizedDescription)
                    completion(nil, error as NSError?)
                }
            }); task.resume()
        }
    }
}

我尝试将groupDispatch.leave()放在函数/ for循环中的不同位置但是它没有以正确的顺序完成(编辑:它在将变量“difference”数组设置为之前完成完成“toWatch”字典变量中的正确键)。我对.leave()的工作方式感到有点困惑。

谢谢!

0 个答案:

没有答案