在Swift 3的每一步中,如何使用Alamofire执行顺序请求并更新progressHUD

艾蒂安·博尔(Etienne Beaule)

好吧,我要疯了...

我正在使用Alamofire 4.x(Swift 3和XCode 8.1)。我需要从需要身份验证的站点获取并解析几个html请求(不幸的是,没有json API)。然后,用Fuzi解析HTML,此过程可能需要一些时间,因此我计划使用ProgressHUD(准确地说是PKHUD)让用户知道发生了什么。我还需要获取一些不在身份验证后面的html。

我创建了一个结构和函数来处理整个网络过程并解析数据。

我设法执行了请求并获取了我需要的数据,但似乎无法弄清楚如何在正确的时间进行HUD更新。

到目前为止,这是我的代码:

import Alamofire
import Fuzi
import PKHUD

struct MyMSCProvider {

static let baseUrl = "http://mastersswimming.ca"

//I tried with or without a custom queue - same result
static let processingQueue = DispatchQueue(label: "com.colddiver.processing-queue", qos: .utility)

static func fetchData(data: MscRequest) {

    if data.profile || data.log {

        //Authenticate first!
        HUD.show(.labeledProgress(title: "Authenticating", subtitle: ""))

        let requestUrl = "\(baseUrl)/MyMscPage.jsp"
        let parameters = ["locale": "en", "username": data.user.username, "password": data.user.password]

        Alamofire.request(requestUrl, method: .post, parameters: parameters).responseData(
            queue: processingQueue,
            completionHandler:
            { response in


                // Now on the processingQueue you created earlier.
                print("THREAD: \(Thread.current) is main thread: \(Thread.isMainThread)")

                switch response.result {
                case .success:

                    if data.profile {
                        DispatchQueue.main.async {
                            HUD.show(.labeledProgress(title: "Getting Profile", subtitle: ""))
                        }
                        let userProfile = parseProfile(data: response.data!, user: data.user)
                        print(userProfile)
                    }

                    if data.log {
                        DispatchQueue.main.async {
                            HUD.show(.labeledProgress(title: "Getting Log", subtitle: ""))
                        }
                        fetchLog()
                    }

                    if data.records {
                        DispatchQueue.main.async {
                            HUD.show(.labeledProgress(title: "Getting Records", subtitle: ""))
                        }
                        fetchRecords(recordsToFetch: data.recordsToFetch)
                    }

                    if data.times {
                        DispatchQueue.main.async {
                            HUD.show(.labeledProgress(title: "Getting Times", subtitle: ""))
                        }
                        print("Fetching times is not implemented yet")
                    }

                    DispatchQueue.main.async {
                        HUD.flash(.success)
                    }


                case .failure(let error):
                    HUD.flash(.error)
                    print("Alamofire request failed")
                    print(error)
                }
        }
        )


    } else {
        //Just fetch - no need to authenticate first
        if data.records {
            DispatchQueue.main.async {
                HUD.show(.labeledProgress(title: "Getting Records", subtitle: ""))
            }
            fetchRecords(recordsToFetch: data.recordsToFetch)
        }

        if data.times {
            print("Fetching times is not implemented yet")
        }

        DispatchQueue.main.async {
            HUD.flash(.success)
        }
    }

}

static func fetchRecords(recordsToFetch: RecordsToFetch) {

    for province in recordsToFetch.provinces {
        for ageGroup in recordsToFetch.ageGroups {
            for gender in recordsToFetch.genders {

                DispatchQueue.main.async {
                    HUD.show(.labeledProgress(title: "Getting Records", subtitle: "\(province) - \(gender+Helpers.getAgeGroupFromAge(age: Int(ageGroup)!))"))
                }

                let requestUrl = "\(baseUrl)/Records.jsp"
                let parameters = ["locale": "en", "province": province, "age": ageGroup, "gender": gender, "course": "*"]

                Alamofire.request(requestUrl, method: .post, parameters: parameters).responseData(
                    queue: processingQueue,
                    completionHandler: { response in

                        switch response.result {
                        case .success:

                            let recordArray = parseRecords(data: response.data!, province: province, ageGroup: ageGroup, gender: gender)

                        case .failure(let error):
                            DispatchQueue.main.async {
                                HUD.flash(.failure)
                            }
                            print("Alamofire request failed")
                            print(error)
                        }
                }
                )
            }
        }
    }
}

static func fetchLog() {

    let requestUrl = "\(baseUrl)/ViewLog.jsp"

    Alamofire.request(requestUrl).responseData(
        queue: processingQueue,
        completionHandler: { response in

            switch response.result {
            case .success:
                let log = parseLog(data: response.data!)

            case .failure(let error):
                DispatchQueue.main.async {
                    HUD.flash(.failure)
                }
                print("Alamofire request failed")
            }
        }
    )
}

// MARK: - Convenience structs
struct MscRequest {
    let profile: Bool
    let log: Bool
    let times: Bool
    let records: Bool
    let recordsToFetch: RecordsToFetch
    let user: MscUser

    let parentView: UITableViewController
}

在这种设置下,我将在TableViewController中设置一个MscRequest并启动一系列的请求,如下所示:

let myData = MscRequest.init(
  profile: true,
  log: true,
  times: false,
  records: true,
  recordsToFetch: RecordsToFetch.init(
    provinces: ["NB", "CA"],
    ageGroups: ["20", "25", "30", "35", "40"],
    genders: ["M", "F"]),
  user: MscUser.init(
    username: "SomeUserName",
    password: "SomePassword"),
  parentView: self
)

MyMSCProvider.fetchData(data: myData)

使用此设置,所有HUD更新将同时(在主线程上)完成,并在后台获取和解析仍在进行时最终被关闭。不完全是我想要的...

我尝试了各种迭代(有或没有自定义队列),也尝试了直接来自Alamofire手册的HTML请求代码(省略了completionHandler部分),但仍然得到了相同的结果...

我也看过了Grand Central Dispatch教程(例如本教程:http : //www.appcoda.com/grand-central-dispatch/),但我还没有弄清楚在使用Alamofire时如何应用信息。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

值得注意的是,我当时通过手动NSURLRequests在Objective-C中完成了这项工作。我正在将该旧应用程序更新为Swift 3,并认为我应该尝试一下Alamofire。

不禁会觉得我缺少明显的东西...有什么提示吗?

艾蒂安·博尔(Etienne Beaule)

好的,我找到了一种使用DispatchGroup进行操作的方法(Swift 3,Alamofire 4.x)

func fetchData() {
    let requestGroup =  DispatchGroup()

    //Need as many of these statements as you have Alamofire.requests
    requestGroup.enter()
    requestGroup.enter()
    requestGroup.enter()

    Alamofire.request("http://httpbin.org/get").responseData { response in
        print("DEBUG: FIRST Request")
        requestGroup.leave()
    }

    Alamofire.request("http://httpbin.org/get").responseData { response in
         print("DEBUG: SECOND Request")
         requestGroup.leave()
    }

    Alamofire.request("http://httpbin.org/get").responseData { response in
         print("DEBUG: THIRD Request")
         requestGroup.leave()
    }

    //This only gets executed once all the above are done
    requestGroup.notify(queue: DispatchQueue.main, execute: {
        // Hide HUD, refresh data, etc.
         print("DEBUG: all Done")
    })

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在 Alamofire 请求 swift 3 中传递 JSON 对象

来自分类Dev

Alamofire JSON请求Swift 3

来自分类Dev

Swift:如何RM Alamofire逐一循环获取请求

来自分类Dev

Swift中的一步式对象创建和属性初始化?

来自分类Dev

使用Swift和textFieldShouldReturn的“下一步” /“完成”按钮

来自分类Dev

Linux上的Swift:使第一步工作

来自分类Dev

在Swift中执行POST请求

来自分类Dev

在Swift中执行POST请求

来自分类Dev

如何在没有AlamoFire的情况下在Swift 3中同时发出异步HTTP请求

来自分类Dev

Swift:每10秒重新载入一次alamofire请求

来自分类Dev

执行期间在 DAG 中的每一步缓存

来自分类Dev

Swift中的Alamofire HTTP发布请求

来自分类Dev

Swift 使用 Alamofire 发出 http 请求

来自分类Dev

如何从 HealthKit Swift 3 显示步数

来自分类Dev

如何在 Swift 4 中按顺序执行操作

来自分类Dev

从Swift 3迁移Alamofire swift2

来自分类Dev

Swift 3中的HTTP请求

来自分类Dev

POST请求Swift 3.0 Alamofire

来自分类Dev

swift alamofire 请求 json 异步

来自分类Dev

我怎样才能一步步完成Swift for-in循环?

来自分类Dev

使用Alamofire在Swift 3中进行Json解析

来自分类Dev

尝试使用 Alamofire 在 Swift 3 中解析 JSON

来自分类Dev

使用 Swift 3 和 Alamofire 上传文件

来自分类Dev

Swift IOS:如何执行REST POST请求

来自分类Dev

在iOS Swift中执行POST请求

来自分类Dev

在Swift 3中更新范围

来自分类Dev

Swift:如何使用库:Alamofire-SwiftyJSON

来自分类Dev

Swift:如何从Swift调用CCKeyDerivationPBKDF

来自分类Dev

Swift 3:如何在 ALamofire 4 的请求正文中添加或删除参数?