質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

560閲覧

Swift Alamofireを使った関数の戻り値を取得したい。

ataru2222

総合スコア272

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2023/01/14 06:52

編集2023/01/14 06:57

実現したいこと

Swift Alamofireを使った関数の戻り値を取得したい。

発生している問題・エラーメッセージ

現在Alamofireを使ってデータが取れたら別画面のTableViewに遷移して表示するようなプログラムを作っています。

しかし、Alamofireの挙動がおかしいので、思ったようにコードが動かず、困惑しております。

以下のようなコードが2つあるとき、デバッグで確認してみると

①Util.dbShow()をみに行く(View Controller .swift)
AF.request()の中には入らない(Util.swift)
②Util.dbShow()のreturn行に到達 0件のdataArraysを返す(Util.swift)
③0件のdataArrayを表示する(View Controller .swift)

なぜかViewController内の処理が終わった後に、最後に突然ここが動き出す
④Util.dbShow()のAF.request()の処理が始まる(Util.swift)

※④の後はreturnの行には到達せず、
.responseData { }の }が終わったところで処理が終わる。
このタイミングではdataArraysにはちゃんと値が格納されます。
returnの行に到達しないので、データが呼び出し元に持ち込めないで状況です。

該当のソースコード

Swift

1//ViewController.swift 2@IBAction func show(_ sender: Any) { 3 ①dataArrays = Util.dbShow() 4print(dataArrays.count) 5 }

Swift

1//Util.swift 2class func dbShow() -> Array<Array<String>>{ 3 4 // 送信先URL 5 let requestUrl = "http://localhost:8888/testPHP/testPOST.php" 6 // リクエストパラメータ 7 let param: Parameters = [ 8 "inputKBN": "show", 9 "name": "", 10 "id": 1 11 ] 12 // リクエストヘッダ 13 let headers: HTTPHeaders = [ 14 "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8" 15 ] 16 17 var dataArrays: Array<Array<String>> = [] 18 let storyBoard = UIStoryboard(name: "Main", bundle: nil) 19 let viewController = storyBoard.instantiateViewController(withIdentifier: "view") as! ViewController 20 21 // AlamofireでPOST送信 22 AF.request( 23 requestUrl, 24 method: .post, 25 parameters: param, 26 encoding: URLEncoding.httpBody, 27 headers: headers 28 ) 29 .responseData { response in 30 switch response.result { 31 case .success: 32 33 //④■■■■■ 34 let json = JSON(response.data as Any)  35 36 if json[0]["id"].int != nil { 37 for count in 0 ... json.count - 1 { 38 dataArrays.append([]) 39 dataArrays[count].append(String(json[count]["id"].int!)) 40 dataArrays[count].append(String(json[count]["name"].string!)) 41 dataArrays[count].append(String(json[count]["address"].string!)) 42 43 } 44 45 } else { 46 print("error") 47 } 48 49 case .failure: 50 print("error") 51 print(".failureブロックに入りました") 52 53 } 54 55 } 56 //②■■■■■ 57 return dataArrays 58 }

試したこと

同期通信、非同期通信とかの問題なのかな?と推測しつつも、詳しい原因やAlamofireの仕様なのかよく分からず、どう調べて良いか分からない状況です。

処理的に③の部分にdataArraysに値が入っていたら一覧表示する画面に遷移するコードを書きたいのですが、現在はdayaArray.countに0が入ってしまい画面遷移できません。

このような場合どのようにしたら、dataArraysの値を取得して、画面遷移できるのでしょうか?
詳しい方いらっしゃいましたらご教授ください。

よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

こちらの記事を参考に自己解決できました。
https://qiita.com/kazuhirox/items/9ecb25bc238ad2d47ff0

Alamofireは.responseJSONのブロック内と、その外側が同じスレッドで処理されるらしいです。
少し前の記事でなので一部コードが変更になっていましたがSwift5ならこちらで動きます。

Swift

1 //ロックが解除されるまで待つ 2 let runLoop = RunLoop.current 3 while keepAlive && 4 runLoop.run(mode: RunLoop.Mode.default, before: Date(timeIntervalSinceNow: 0.1)) { 5 // 0.1秒毎の処理なので、処理が止まらない 6 }

投稿2023/01/15 01:13

ataru2222

総合スコア272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問