我想以某種方式異步驗證ABPadLockScreen中的引腳,因爲引腳未保存在設備上。我使用Alamofire作爲http請求,並與PromiseKit一起承諾。我試圖使用AwaitKit
但問題是我陷入僵局。等待異步請求結果
我也嘗試過使用semaphore
,但結果是一樣的。由於我無法更改ABPadLock方法來容納像完成處理程序之類的東西,所以我需要一些解決方案,它是否阻塞主線程並不重要,只是它可以工作。
Alamofire請求方法:
public func loginAsync(pinCode: String?, apiPath: String?) -> Promise<LoginResult>{
return Promise { fullfil, reject in
let params = [
"Pin": pinCode!
]
Alamofire.request(.POST, "\(baseUrl!)/\(apiPath!)", parameters: params).responseObject{(response: Response<LoginResult, NSError>) in
let serverResponse = response.response
if serverResponse!.statusCode != 200 {
reject(NSError(domain: "http", code: serverResponse!.statusCode, userInfo: nil))
}
if let loginResult = response.result.value {
fullfil(loginResult)
}
}
}
}
ABPadLockScreen銷驗證方法:
public func padLockScreenViewController(padLockScreenViewController: ABPadLockScreenViewController!, validatePin pin: String!) -> Bool {
let pinCode = pin!
let defaults = NSUserDefaults.standardUserDefaults()
let serverUrl = defaults.stringForKey(Util.serverUrlKey)
let service = AirpharmService(baseUrl: serverUrl)
service.loginAsync(pinCode, apiPath: "sw/airpharm/login").then { loginResult -> Void in
if loginResult.code == HTTPStatusCode.OK {
AirpharmService.id = loginResult.result!.id
}
}
return false // how do i get the result of above async method here?
}
隨着旗語:
public func padLockScreenViewController(padLockScreenViewController: ABPadLockScreenViewController!, validatePin pin: String!) -> Bool {
var loginResult: LoginResult?
let defaults = NSUserDefaults.standardUserDefaults()
let baseUrl = defaults.stringForKey(Util.serverUrlKey)
let service = AirpharmService(baseUrl: baseUrl)
let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
service.loginAsync(pin, apiPath: "sw/airpharm/login").then { loginResultRaw -> Void in
loginResult = loginResultRaw
dispatch_semaphore_signal(semaphore)//after a suggestion from Josip B.
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
return loginResult != nil // rudimentary check for now
}
編輯:
從約瑟普B.我在加入旗語信號建議後,但它仍然無法正常工作
AirpharmService
是包含靜態類屬性稱爲id,以及Alamofire
請求方法。爲是與我和我的,不是那麼好,雨燕和iOS知識,使患者
感謝大家:
ABPadLockScreen
引腳驗證在主線程中ViewController
解決的編輯完成。在這裏有很多很好的答案,最後,我只是在我看來是最簡單的解決方案。我聽了Losiowaty-s的建議;實現了一個微調器,並在我得到服務器響應時手動解鎖了鎖屏。我使用了SwiftSpinner。最終的解決方案看起來像這樣:
public func padLockScreenViewController(padLockScreenViewController: ABPadLockScreenViewController!, validatePin pin: String!) -> Bool {
let defaults = NSUserDefaults.standardUserDefaults()
let baseUrl = defaults.stringForKey(Util.serverUrlKey)
let service = AirpharmService(baseUrl: baseUrl)
SwiftSpinner.show("Logging in. Please wait...")
service.loginAsync(pin, apiPath: "sw/airpharm/login").then { loginResult -> Void in
if loginResult.code == HTTPStatusCode.OK {
SwiftSpinner.hide()
AirpharmService.id = loginResult.result!.id
self.unlockWasSuccessfulForPadLockScreenViewController(padLockScreenViewController)
} else if loginResult.code == HTTPStatusCode.Unauthorized {
let toast = JLToast.makeText("Invalid pin, please try again", duration: 5)
toast.show()
SwiftSpinner.hide()
} else {
let toast = JLToast.makeText("\(loginResult.code) sent from server. Please try again.", duration: 5)
toast.show()
SwiftSpinner.hide()
}
}.error { error in
let toast = JLToast.makeText("\((error as NSError).code) sent from server. Please try again.", duration: 5)
toast.show()
SwiftSpinner.hide()
}
return false
}
您說「ABPadLockScreen引腳驗證在主線程上完成」,那麼您不應該在那裏等待。重新構建適合異步調用的驗證功能。 – OOPer
這個函數'padLockScreenViewController'是abpadlockscreen協議的一部分,該函數由abpadlockscreen自動調用。你打算怎麼做?如果我問了一個愚蠢的問題,我真的很抱歉,但我一直在使用Swift幾天,所以我仍然不知道它是如何工作的。 –
帶信號量的代碼不完整,添加dispatch_semaphore_signal(信號量);在loginResult = loginResultRaw之後發出信號量以繼續。 –