使用環境
Xcode8.2.1
swift3.0
Alamofire4
swift
1 //APIからデータを取得 2 func getData() -> Bool { 3 var isComplete = false 4 var isError = true 5 //APIからデータ取得 6 Alamofire.request(ApiConst.Url, 7 parameters: [ ApiConst.Key: ApiConst.Val] 8 ).responseJSON {response in 9 print("データ取得") 10 if response.result.isSuccess { 11 isError = false 12 } else { 13 isError = true 14 } 15 isComplete = true 16 } 17 18 let calendar = Calendar(identifier: .gregorian) 19 let startTime = Date() 20 var isTimeout = false 21 let runLoop = RunLoop.current 22 //レスポンスがあるか、タイムリミットが尽きるまで待機する(0.1秒刻み) 23 while !isComplete && !isTimeout && 24 runLoop.run(mode: RunLoopMode.defaultRunLoopMode, before: NSDate(timeIntervalSinceNow: 0.1) as Date) { 25 //開始時間から現在までの時間のスパンがタイムリミットに達したらタイムアウトフラグを立てる 26 let nowTime = Date() 27 let span = calendar.dateComponents([.second], from: startTime, to: nowTime).second 28 if span! > ApiConst.LimitTime { 29 isTimeout = true 30 print("タイムアウト") 31 } 32 } 33 print("データ返却") 34 if isComplete && !isError { 35 print("成功") 36 return true 37 } else { 38 print("失敗") 39 return false 40 } 41 }
上記はプロトコル・デリゲートを使用せず、ちと強引に取得をreturn前に終わらせている例です。
--
swift
1 @IBAction func getAPIAction(_ sender: Any) { 2 _ = self.getData() 3 }
上記の使用方法では、予定通りの動作をしてくれます。
-- Print Log --
データ取得
データ返却
成功
--
swift
1 @IBAction func getAPIAction(_ sender: Any) { 2 let alert = UIAlertController(title: "", message: "取得する", 3 preferredStyle: UIAlertControllerStyle.alert) 4 let yesAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, 5 handler: {(_) -> Void in 6 _ = self.getData() 7 }) 8 alert.addAction(yesAction) 9 self.present(alert, animated: true, completion: nil) 10 }
しかし、上記の使用方法では、レスポンスの取得が全ての動作後になってしまいます。
-- Print Log --
タイムアウト
データ返却
失敗
データ取得
Dispatch等も調べて試してみたでのすが、どうにもうまくいかず・・・。
どなた様か、コレの解消方法にお気づきになられました方、ご教授お願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/03 08:56
2017/04/03 09:27
2017/04/03 10:03 編集
2017/04/03 10:16
2017/04/03 10:23
2017/04/03 10:30
2017/04/03 10:49