如何知道何时使用闭包完成异步请求?

时间:2017-03-16 19:08:54

标签: ios swift closures alamofire completionhandler

我正在使用Alamofire下载数据并使用JSON解析它。我知道为了宣布数据可用,我们应该使用闭包而不使用NotificationCenter。我不明白闭包。请求完成后,如何使用闭包重新加载表视图? 这是代码。

    func downloadEvents() {
    let coreDataObject = CoreDataMethods()
    Alamofire.request(URL(string:URL)!)
        .responseJSON { response in
            switch response.result {
            case .success:
                // we create the model object
                let downloadedEvent = EventModel()
                /* we have new data remove old data from core data*/
                coreDataObject.deleteData(entityArgument: "Event")
                events.removeAll() // remove the data from array this is no longer needed FIX
                for JSONData in response.result.value as! [Dictionary<String, Any>] {
                    /* get the data from JSON and store in the event model*/
                    downloadedEvent.eTitle = JSONData[downloadedEvent.titleString] as? String
                    downloadedEvent.eDate = JSONData[downloadedEvent.dateString] as? String
                    downloadedEvent.eDescription = JSONData[downloadedEvent.descriptionString] as? String
                    downloadedEvent.eLocation = JSONData[downloadedEvent.locationline1String] as? String
                    downloadedEvent.eLocation2 = JSONData[downloadedEvent.locationline2String] as? String
                    /* if the event has an image save the url*/
                    if let image = JSONData[downloadedEvent.imageString] as? String {
                        downloadedEvent.eImageURL = image
                    } else {
                        /* else we save the default image url */
                        downloadedEvent.eImageURL = downloadedEvent.defaultImageURL
                    }
                    coreDataObject.save(eventParam: downloadedEvent)
                }
                /* post notification to reload table view FIX */
                NotificationCenter.default.post(name: RELOAD_NOTIFICATION, object: nil)
            case .failure(let error):
                print("ALAMO REQUEST FIALED: \(error)")
            }
    }
}

1 个答案:

答案 0 :(得分:1)

这是downloadEvents函数,能够通知调用者它是否成功:

func downloadEvents(completion: @escaping (Bool, String?)-> Void) {
    let coreDataObject = CoreDataMethods()
    Alamofire.request(URL(string:URL)!)
        .responseJSON { response in

            switch response.result {
            case .success:
                // we create the model object
                let downloadedEvent = EventModel()
                /* we have new data remove old data from core data*/
                coreDataObject.deleteData(entityArgument: "Event")
                events.removeAll() // remove the data from array this is no longer needed FIX
                for JSONData in response.result.value as! [Dictionary<String, Any>] {
                    /* get the data from JSON and store in the event model*/
                    downloadedEvent.eTitle = JSONData[downloadedEvent.titleString] as? String
                    downloadedEvent.eDate = JSONData[downloadedEvent.dateString] as? String
                    downloadedEvent.eDescription = JSONData[downloadedEvent.descriptionString] as? String
                    downloadedEvent.eLocation = JSONData[downloadedEvent.locationline1String] as? String
                    downloadedEvent.eLocation2 = JSONData[downloadedEvent.locationline2String] as? String
                    /* if the event has an image save the url*/
                    if let image = JSONData[downloadedEvent.imageString] as? String {
                        downloadedEvent.eImageURL = image
                    } else {
                        /* else we save the default image url */
                        downloadedEvent.eImageURL = downloadedEvent.defaultImageURL
                    }
                    coreDataObject.save(eventParam: downloadedEvent)
                }

                completion(true, nil)

                /* post notification to reload table view FIX */
                //NotificationCenter.default.post(name: RELOAD_NOTIFICATION, object: nil)
            case .failure(let error):
                print("ALAMO REQUEST FIALED: \(error)")
                completion(false, "ALAMO REQUEST FIALED: \(error)")
            }
    }
}

然后您将调用此函数:

func reloadTable(){

    downloadEvents { (success, errMsg) in
        if success{
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
        else{
            let alertMessage: String
            if let err = errMsg{
                alertMessage = err
            }
            else{
                alertMessage = "An unknown error occurred."
            }
            let alert = UIAlertController.init(title: "Request Failed", message: alertMessage, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil))
            DispatchQueue.main.async {
                self.present(alert, animated: true, completion: nil)
            }
        }
    }
}