🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

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

Q&A

1回答

2330閲覧

【Swift】APIデータで変換した値をラベルに表示したい

syoco0330

総合スコア30

Swift

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

0グッド

0クリップ

投稿2019/10/17 13:09

編集2019/10/17 15:04

APIを使ってひらがなに変換するアプリを作成しています。
textFieldに入力した漢字が、hiraganaConvertButtonを押すことでひらがなに変換された値がtestLabelに表示されるようにしたいのですが、表示されません。

どのようにしたらよろしいでしょうか?
ご教授いただければ幸いです。

Swift

1 2import UIKit 3 4class ViewController: UIViewController, UITextFieldDelegate { 5 6 @IBOutlet weak var testLabel: UILabel! 7 @IBOutlet weak var textField: UITextField! 8 9 // レスポンスデータの構造 10 struct PostData: Codable { 11 var app_id : String 12 var request_id : String 13 var sentence : String 14 var output_type : String 15 } 16 17 struct Rubi: Codable { 18 var request_id : String 19 var output_type : String 20 var converted : String 21 } 22 23 var sentence: String = "" 24 25 26 override func viewDidLoad() { 27 super.viewDidLoad() 28 29 30 31 textField.delegate = self 32 33 } 34 35 @IBAction func hiraganaConvertButton(_ sender: Any) { 36 37 print(sentence) 38 sentenceChange() 39 testLabel.text = sentence 40 41 } 42 // ModalViewに値を渡す 43 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 44 45 let modalVC = segue.destination as! ModalViewController 46 modalVC.result = sentence 47 } 48 49 // ひらがなに変換 50 func sentenceChange() { 51 if textField.text != nil { 52 var request = URLRequest(url: URL(string: "https://labs.goo.ne.jp/api/hiragana")!) 53 request.httpMethod = "POST" 54 request.addValue("application/json", forHTTPHeaderField: "Content-Type") 55 56 let postData = PostData(app_id: "APIキー",request_id: "record003", sentence: textField.text!, output_type: "hiragana") 57 58 guard let uploadData = try? JSONEncoder().encode(postData) else { 59 print("失敗しました") 60 return 61 } 62 let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in 63 if let error = error { 64 print("error:(error)") 65 return 66 } 67 68 guard let data = data, let jsonData = try? JSONDecoder().decode(Rubi.self, from: data) else { 69 print("json変換に失敗しました") 70 return 71 } 72 print(jsonData.converted) 73 } 74 task.resume() 75 }else{ 76 print("文章を入力してね") 77 } 78 79 } 80 81 // キーボードを閉じる 82 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 83 textField.resignFirstResponder() 84 return true 85 } 86 87} 88 89 90 91 92

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

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

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

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

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

guest

回答1

0

まず、前提となる、APIからの取得はきちんとできているでしょうか?
それができていれば、あとは難しくないですよ。

APIから返ってくるタイミングで、textField.text = 返ってきたもの
とすれば良いです。

なので、、、

Swift

1@IBAction func hiraganaConvertButton(_ sender: UITextField) { 2 guard let text = sender.text, text.isEmpty else { 3 print("文章を入力してね") // 実機ではUIAlertController表示などが良いのでは? 4 return 5 } 6 sentenceChange(text: text) 7} 8 9// ~~~ 間省略 10 11// ひらがなに変換 12func sentenceChange(text: String) { 13 let postData = PostData(app_id: "APIキー",request_id: "record003", sentence: text, output_type: "hiragana") 14 guard let uploadData = try? JSONEncoder().encode(postData) else { 15 print("失敗しました") 16 return 17 } 18 19 var request = URLRequest(url: URL(string: "https://labs.goo.ne.jp/api/hiragana")!) 20 request.httpMethod = "POST" 21 request.addValue("application/json", forHTTPHeaderField: "Content-Type") 22 let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in 23 24 // クライアント側エラー 25 if let error = error { 26 print("error:(error)") 27 return 28 } 29 30 guard let data = data, let response = response as? HTTPURLResponse else { 31 print("no data or no response") 32 return 33 } 34 35 if response.statusCode == 200 { 36 guard let jsonData = try? JSONDecoder().decode(Rubi.self, from: data) else { 37 print("json変換に失敗しました") 38 return 39 } 40 print(jsonData.converted) // <- ここでデータ取得後なので、このタイミングで設定すればOKです。 41 self.textField.text = jsonData.converted // これを追加してください。 42 } else { 43 // レスポンスのステータスコードが200でない場合などはサーバサイドエラー 44 print("サーバエラー ステータスコード: (response.statusCode)\n") 45 } 46 } 47 task.resume() 48} 49

少し下記を参考にしました。
https://qiita.com/shiz/items/09523baf7d1cd37f6dee#基本的な使い方

nil checkはボタンを押した段階でして、
無駄にsentenceChangeを呼ばなくしたのと、nilではないけど、空白 ""のcheckも追加。
nil check済を引数で渡して、sentenceChangeではnil check不要にしました。
また、Encodeに失敗すれば、通信準備不要なので、
データ加工を先頭にし、その後にrequestを作成にしました。
dataが存在することと、decodeできるかは別の事項なので、
同じguardに併記するのは良くないかなと思います。

投稿2019/10/17 18:03

hameji

総合スコア1380

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

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

syoco0330

2019/10/18 12:22

ご丁寧に教えていただきありがとうございます。 試してみたところ”hiraganaConvertButton”の部分でエラーが出てしまい修正してますが、非常に参考になりました。
hameji

2019/10/18 13:11

どんなエラーなんですか?
syoco0330

2019/10/18 13:24

Value of type 'UIButton' has no member 'text'; did you mean 'next'? 上記のエラーになりました。
syoco0330

2019/10/18 13:30 編集

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButton text]: unrecognized selector sent to instance 0x104610f70' 最初にThread 1: signal SIGABRTで、上記のエラーになり、修正をしているうちにハマってしまっている状態です。
hameji

2019/10/18 13:40 編集

あ、ごめんなさい。こっちのミスです。 UIButtonの@IBActionなので、 @IBAction func hiraganaConvertButton(_ sender: UITextField) {の senderはUIButtonになるでしたね。 そこを(_ sender: Any)に戻す、もしくは(_ sender: UIButton)にして、 guard let text = sender.text, text.isEmpty else { を guard let text = textField.text, text.isEmpty else { とすれば動くはずです。
hameji

2019/10/18 13:39

わからなければ、上記の大元の答えを編集し直しますが、、、
syoco0330

2019/10/18 13:45

@IBAction func hiraganaConvertButton(_ sender: Any) { guard let text = textField.text, text.isEmpty else { print("文章を入力してね") return } sentenceChange(text: text) }
syoco0330

2019/10/18 13:50

上記のようにしたのですが、デバックエリアに表示される結果が「文章を入力してね」になってしまっている状態です。 APIからの取得は質問の時点では取得できてはいました
hameji

2019/10/18 13:58 編集

ごめんなさい、また凡ミスで、、、 @IBAction func hiraganaConvertButton(_ sender: Any) { guard let text = textField.text, !text.isEmpty else { print("文章を入力してね") return } text.isEmptyの前に「!」が抜けてました。 <- 「」はずして!だけ書いてくださいね。
hameji

2019/10/18 13:57

自分まだまだですね。 精進します。
syoco0330

2019/10/18 14:02

ありがとうございます! デバックエリアに漢字を変換した文字が表示されました! hiraganaConvertButtonを押したらラベルに表示される仕様なのですが苦戦しております。 ちなみに @IBOutlet weak var testLabel: UILabel! に反映した文字を表示させたいのですが、ご存知でしょうか? おんぶに抱っこですいません。
hameji

2019/10/18 14:04 編集

print(jsonData.converted)の次の行の 代入するself.textField.textのとこを、 self.testLabel.textに書き換えるだけですよ。
syoco0330

2019/10/18 14:18

self.testLabel.text = jsonData.converted このように書き換えたのですが、表示がされないようです。
syoco0330

2019/10/18 15:00

ラベルへの表示についてですが、ボタンを押しておよそ30秒後くらいにラベルに表示されました。
hameji

2019/10/18 15:23

よかったです、動いて。 コードをどこか間違えたのかと心配になりました。 URLSessionを用いた処理は非同期通信なので、 押してからのタイムラグ(サーバーの応答時間)はしょうがない面があります。 違和感が生じると思うので、 通常はHUD (head up display)などを表示することが多いです。 SVProgressiveHUDやPKHUDを用いてみるのはどうですか? (花びらみたいなクルクル回る処理中の画像を出す奴です)
syoco0330

2019/10/18 22:53

APIから取得してデバックエリアにはすぐに表示されるのですが、ラベル表示は30秒ほどかかるのですが、そういうものなのでしょうか? HUDの実装やってみます。
syoco0330

2019/10/18 23:30

Main Thread Checker: UI API called on a background thread: -[UILabel setText:] PID: 6114, TID: 5733639, Thread name: (none), Queue name: NSOperationQueue 0x28226f680 (QOS: UNSPECIFIED), QoS: 0 Backtrace: 4 RubiApp 0x000000010266f924 $s7RubiApp14ViewControllerC14sentenceChange4textySS_tFy10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 1888 5 RubiApp 0x000000010266fe64 $s10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 284 6 CFNetwork 0x00000001e5493688 <redacted> + 32 7 CFNetwork 0x00000001e54a7220 <redacted> + 176 8 Foundation 0x00000001e5923cf4 <redacted> + 16 9 Foundation 0x00000001e582fdc0 <redacted> + 72 10 Foundation 0x00000001e582f2a8 <redacted> + 740 11 Foundation 0x00000001e5925a78 <redacted> + 272 12 libdispatch.dylib 0x0000000102a3f6f4 _dispatch_call_block_and_release + 24 13 libdispatch.dylib 0x0000000102a40c78 _dispatch_client_callout + 16 14 libdispatch.dylib 0x0000000102a43ffc _dispatch_continuation_pop + 524 15 libdispatch.dylib 0x0000000102a43458 _dispatch_async_redirect_invoke + 628 16 libdispatch.dylib 0x0000000102a51dc8 _dispatch_root_queue_drain + 372 17 libdispatch.dylib 0x0000000102a527ac _dispatch_worker_thread2 + 156 18 libsystem_pthread.dylib 0x00000001e4ade1b4 _pthread_wqthread + 464 19 libsystem_pthread.dylib 0x00000001e4ae0cd4 start_wqthread + 4 2019-10-19 08:25:35.433805+0900 RubiApp[6114:5733639] [reports] Main Thread Checker: UI API called on a background thread: -[UILabel setText:] PID: 6114, TID: 5733639, Thread name: (none), Queue name: NSOperationQueue 0x28226f680 (QOS: UNSPECIFIED), QoS: 0 Backtrace: 4 RubiApp 0x000000010266f924 $s7RubiApp14ViewControllerC14sentenceChange4textySS_tFy10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 1888 5 RubiApp 0x000000010266fe64 $s10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 284 6 CFNetwork 0x00000001e5493688 <redacted> + 32 7 CFNetwork 0x00000001e54a7220 <redacted> + 176 8 Foundation 0x00000001e5923cf4 <redacted> + 16 9 Foundation 0x00000001e582fdc0 <redacted> + 72 10 Foundation 0x00000001e582f2a8 <redacted> + 740 11 Foundation 0x00000001e5925a78 <redacted> + 272 12 libdispatch.dylib 0x0000000102a3f6f4 _dispatch_call_block_and_release + 24 13 libdispatch.dylib 0x0000000102a40c78 _dispatch_client_callout + 16 14 libdispatch.dylib 0x0000000102a43ffc _dispatch_continuation_pop + 524 15 libdispatch.dylib 0x0000000102a43458 _dispatch_async_redirect_invoke + 628 16 libdispatch.dylib 0x0000000102a51dc8 _dispatch_root_queue_drain + 372 17 libdispatch.dylib 0x0000000102a527ac _dispatch_worker_thread2 + 156 18 libsystem_pthread.dylib 0x00000001e4ade1b4 _pthread_wqthread + 464 19 libsystem_pthread.dylib 0x00000001e4ae0cd4 start_wqthread + 4 2019-10-19 08:25:49.063233+0900 RubiApp[6114:5733639] [Animation] +[UIView setAnimationsEnabled:] being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior. trace=( 0 UIKitCore 0x0000000211da57f0 <redacted> + 116 1 libdispatch.dylib 0x0000000102a40c78 _dispatch_client_callout + 16 2 libdispatch.dylib 0x0000000102a42c84 _dispatch_once_callout + 84 3 UIKitCore 0x0000000211da5778 <redacted> + 100 4 UIKitCore 0x0000000211da58e4 <redacted> + 92 5 UIKitCore 0x0000000211d28fb4 <redacted> + 368 6 UIKitCore 0x0000000211d29098 <redacted> + 32 7 QuartzCore 0x00000001e9400c08 <redacted> + 332 8 QuartzCore 0x00000001e93633e4 <redacted> + 348 9 QuartzCore 0x00000001e9391620 <redacted> + 640 10 QuartzCore 0x00000001e93926ec <redacted> + 228 11 libsystem_pthread.dylib 0x00000001e4ae04b4 <redacted> + 580 12 libsystem_pthread.dylib 0x00000001e4add904 <redacted> + 80 13 libsystem_pthread.dylib 0x00000001e4ade508 pthread_workqueue_setdispatchoffset_np + 0 14 libsystem_pthread.dylib 0x00000001e4ade14c _pthread_wqthread + 360 15 libsystem_pthread.dylib 0x00000001e4ae0cd4 start_wqthread + 4 )
syoco0330

2019/10/18 23:31

API取得後にデバックエリアに表示されるのもですがこれが原因でしょうか?
syoco0330

2019/10/19 10:27

原因がわかりました。 落ち着きましたら解決方法を入力したいと思います。 ご丁寧に教えていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問