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

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

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

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

1回答

709閲覧

SwiftでのAPIでの取得後に結果を別ViewControllerのTextFieldに表示させたい

syoco0330

総合スコア30

Swift

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2019/10/19 00:25

編集2019/10/19 00:26

APIを使って漢字からひらがなに変換するアプリを作成しています。

APIで取得した文字をViewController.swift内にあるLabelに表示させることはできたのですが、ModalViewController.swiftという別のControllerに値を受け渡したいのですが、表示されません。

ご教授いただけませんでしょうか。

試したこと

ViewController.swiftの中にあるLabelには表示することができました。

表示できない原因の考察

なぜ表示されないのかを自分なりに考えてみました。

  • API取得後、デバックエリアには結果がすぐに返ってくるがLabelに反映されるには30秒ほど時間がかかるため

実装できていること

  • APIの取得はできている。
  • 画面遷移する。
  • 値の受け渡しもできる状態である。

下記がViewController.swiftです。

swift

1import UIKit 2 3class ViewController: UIViewController, UITextFieldDelegate { 4 5 @IBOutlet weak var testLabel: UILabel! 6 @IBOutlet weak var textField: UITextField! 7 8 9 var imageView: UIImageView! 10 var backImageView: UIImageView! 11 var hiraganaSentence: String = "" 12 13 14 // レスポンスデータの構造 15 struct PostData: Codable { 16 var app_id : String 17 var request_id : String 18 var sentence : String 19 var output_type : String 20 } 21 22 struct Rubi: Codable { 23 var request_id : String 24 var output_type : String 25 var converted : String 26 } 27 28 override func viewDidLoad() { 29 super.viewDidLoad() 30 31 textField.delegate = self 32 33 } 34 35 override func viewDidAppear(_ animated: Bool) { 36 super.viewDidAppear(animated) 37 38 } 39 40 41 42 @IBAction func hiraganaConvertButton(_ sender: UIButton) { 43 guard let text = textField.text,!text.isEmpty else { 44 print("文章を入力してね") 45 return 46 } 47 48 sentenceChange(text: text) 49 performSegue(withIdentifier: "modal", sender: nil) 50 51 } 52 53 54 // ModalViewに値を渡す 55 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 56 57 let modalVC = segue.destination as! ModalViewController 58 modalVC.result = hiraganaSentence 59 60 } 61 62 // キーボードを閉じる 63 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 64 65 textField.resignFirstResponder() 66 return true 67 68 } 69 70 71 func sentenceChange(text: String) { 72 73 let postData = PostData(app_id: "APIキー",request_id: "record003", sentence: textField.text!, output_type: "hiragana") 74 guard let uploadData = try? JSONEncoder().encode(postData) else { 75 print("失敗しました") 76 return 77 78 } 79 // データの確認 80 print(postData) 81 82 var request = URLRequest(url: URL(string: "https://labs.goo.ne.jp/api/hiragana")!) 83 request.httpMethod = "POST" 84 request.addValue("application/json", forHTTPHeaderField: "Content-Type") 85 let task = URLSession.shared.uploadTask(with: request, from: uploadData, completionHandler: { (data, response, error) in 86 87 // クライアント側エラー 88 if let error = error { 89 print("error:(error)") 90 return 91 } 92 93 guard let data = data, let response = response as? HTTPURLResponse else { 94 print("no data or no response") 95 return 96 } 97 98 if response.statusCode == 200 { 99 guard let jsonData = try? JSONDecoder().decode(Rubi.self, from: data) else { 100 print("json変換に失敗しました") 101 return 102 } 103 print("ここから") 104 print(jsonData.converted) 105 self.testLabel.text = jsonData.converted 106 self.hiraganaSentence = jsonData.converted 107 } else { 108 // レスポンスのステータスコードが200でない場合などはサーバサイドエラー 109 print("サーバエラー ステータスコード: (response.statusCode)\n") 110 } 111 }) 112 task.resume() 113 } 114 115}

Swift

1import UIKit 2 3class ModalViewController: UIViewController { 4 5 @IBOutlet weak var convertText: UITextView! 6 7 var result = "" 8 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 13 view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5) 14 convertText.text = result 15 print(result) 16 } 17 18 @IBAction func backButton(_ sender: Any) { 19 20 dismiss(animated: true, completion: nil) 21 22 } 23} 24

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

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

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

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

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

guest

回答1

0

Swift

1override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 2 let modalVC = segue.destination as! ModalViewController 3 modalVC.result = hiraganaSentence 4}

上記の先頭行にprint("prepareForSegue:", hiraganaSentence)を記入してみてください

そしてコンソールを見るとわかると思いますが、
非同期通信なので、URLSessionの結果が帰ってくる前に、
preformSegue()が先に実行されてしまうので、
hiraganaSentenceに結果が入る前(空のまま)
Segueが開始されてしまうんです。

文字の表示の時と同じです。
perforSegueを書く位置が大事です。

理想的にはcomletionなどを用いるときれいに分離できますけどね。

投稿2019/10/19 02:22

hameji

総合スコア1380

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

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

syoco0330

2019/10/19 10:41

すいません。 書く位置というのは単純に @IBAction func hiraganaConvertButton のコード全体を違うところに書くということでしょうか?
hameji

2019/10/19 11:17

あのー、UIlabelの表示の時と同じ位置にperformSegueを書けば良いって意味です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問