확인의 모든 단계에서 progressHUD를 업데이트, 나는방법 Alamofire으로 순차적 요청을 수행하고 스위프트 3
내가 Alamofire 4.x의 (스위프트 3, 엑스 코드 8.1을 사용하고 있습니다 ...이 일을 통해 너트려고하고있다). 가져 와서 인증을 필요로하는 사이트에서 여러 HTML 요청을 구문 분석해야합니다 (불행히도 json API 없음). 그러면 HTML이 Fuzi와 구문 분석되며이 진행 과정에는 다소 시간이 걸릴 수 있으므로 ProgressHUD (정확한 PKHUD)를 사용하여 사용자에게 무슨 일이 일어나는지 알릴 수 있습니다. 나는 또한 인증 뒤에 있지 않은 html을 잡을 필요가있다.
전체 네트워크 프로세스를 처리하고 데이터를 구문 분석하기 위해 구조체와 함수를 만들었습니다.
요청을 수행하고 필요한 데이터를 가져올 수 있었지만 적시에 HUD 업데이트를 만드는 방법을 알 수 없었습니다. 이 설정으로
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)
: 나는 TableViewController에서 MscRequest 설정을하고자하고 일련 그래서 같은 요청을 시작,이 설정에서
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
}
:
여기에 지금까지 내 코드입니다 모든 HUD 업데이트는 (메인 스레드에서) 동시에 수행되고 백그라운드 페칭 및 파싱이 진행되는 동안 해지됩니다. 정확히 내가 무엇을하려고하는지 ...
Alamofire 매뉴얼 (completionHandler 부분을 생략 함)에서 HTML 요청 코드를 직접 시도했지만 여전히 얻을 수 있습니다. 동일한 결과 ...
는 또한 (예 :이 하나 : http://www.appcoda.com/grand-central-dispatch/를) 그랜드 센트럴 디스패치 튜토리얼을 살펴했지만, 나는 Alamofire를 사용할 때 참고로
... 정보를 적용하는 방법을 생각하지 않은 당시에 NSURLRequests 매뉴얼로 Objective-C에서이 작업을 할 수있었습니다. 나는이 오래된 응용 프로그램을 Swift 3으로 현대화하고 있으며 Alamofire를 시험해보아야한다고 생각했습니다.
나는 명백한 뭔가를 놓치고있는 것처럼 느껴지지 않을 수 있습니다 ... 어떤 팁?
좋아,이 (http://stackoverflow.com/questions/36911192/how-to-load-view-after-alamofire-finished-its-job) 내가 필요하다고 생각하는 것에 훨씬 더 가깝지만 나는 ' 그것은 아직 작동하도록하는 방법을 찾지 못했습니다 ... –
이 모양 (http://stackoverflow.com/questions/28634995/cha) in-multiple-alamofire-requests)도 도움이 될 수 있습니다 - PromiseKit이 아닌 경우 ... –