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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

3回答

557閲覧

SwiftyJSONで値を取り出す方法について

kazzzstudio

総合スコア94

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2018/02/02 06:13

編集2018/02/02 08:43

サーバーにAPIを投げて結果をJSONで受け取って処理するプログラムを作っています。

以下がその該当コードになります。

Swift

1 let response = runQuery(_login_url) 2 let responseJson = JSON(response) 3 print (responseJson) 4 if (responseJson["status"].string == "success") { 5 loginStatus = 1 6 } 7 else { 8 loginStatus = 0 9 } 10 print(loginStatus) 11

上記プログラムを走らせると、loginStatusが0になります。

print(responseJson)の結果は、以下のように表示されています。

{"status": "success", "userid": "12345678", "username": "aaaaaaaa", "email": "bbbbbb@cccccccc.com", "session_string": "xxxxxxxxxxxxxxxx"}

しかし、responseJson["status"]の値が取れず、
print (responseJson["status"].string)とすると、nilが返ってきてしまいます。

取得したJSONデータを正しく取り出す方法につきましてアドバイスをいただけないでしょうか?
よろしくお願いいたします。

追記)
runQuery()は、以下のように書いています。

Swift

1 private func runQuery(_ _url: String) -> JSON { 2 var responseData: JSON = JSON.null 3 let urlString = _url 4 var keepAlive = true 5 6 Alamofire.request(urlString, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON(completionHandler: { response in 7 8 responseData = JSON(response.result.value) 9 keepAlive = false 10 }) 11 12 let runLoop = RunLoop.current 13 while keepAlive && 14 runLoop.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 0.1)) { 15 } 16 17 return responseData 18 } 19

追記2)

print(responseJson)の結果
{"status": "success", "userid": "12345678", "username": "aaaaaaaa", "email": "bbbb@cccccccc.com", "session_string": "dddddddddddddddd"}

print(responseJson.rawValue)の結果
{"status": "success", "userid": "12345678", "username": "aaaaaaaa", "email": "bbbb@cccccccc.com", "session_string": "dddddddddddddddd"}

全く一緒でした。

また、response["status"].stringValue == "success" とstringの代わりにstringValueを試してみましたがダメでした。

どこが悪いのかさっぱりわかりません。引き続きよろしくお願いいたします。

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

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

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

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

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

fromageblanc

2018/02/02 06:38

let responseJson = JSON(response) を、let responseJson = JSON(response.result.value)に変えることは可能ですか?
kazzzstudio

2018/02/02 06:43 編集

ご回答ありがとうございます。やってみたのですが、Value of type 'JSON' has no member 'result'となりの、ビルドできなくなってしまいました。
fromageblanc

2018/02/02 07:24 編集

runQueryの中でJSONにパースしてるので、その後の、let responseJson = JSON(response)はいらないんじゃない?
kazzzstudio

2018/02/02 07:42

ご回答ありがとうございます。おっしゃる通りでその方法で当初試したのですが、うまくいかないので今のコードになってしまいました。どううまくいかないのかというと、今の現象と全く同じなのです。
fuzzball

2018/02/02 07:49

print(responseJson) と print(responseJson.rawValue) の出力を教えて下さい。
fromageblanc

2018/02/02 08:09

あと、.stringってプロパティ持ってましたっけ?.stringValueを試してみてください
kazzzstudio

2018/02/02 08:44

ご回答、ありがとうございます。試してみましたが、やっぱりダメなようです。ちなみにXcodeとSwiftは最新のバージョンを使っています。
fuzzball

2018/02/02 09:07 編集

print(type(of: responseJson.rawValue)) の出力を教えて下さい。バージョンを書くときは具体的に書いて下さい。「最新」などというバージョンはありません。あと念のため確認しますが、出力結果はコピペしてますよね?(改行も含めて)
kazzzstudio

2018/02/02 09:30 編集

ご回答ありがとうございます。print(type(of: responseJson.rawValue))の出力はStringでした。出力結果はコピペした後に、実データが公開できないため単純な文字列に変更しています。改行などはいじっていません。バージョンも誤解を招く表現でした。Xcode9.2、Swift4.0.3です。
fuzzball

2018/02/02 10:20

確認出来ないのでこっちに書きます。runQuery()の方、JSON(parseJSON: response.result.value) でどうでしょうか?
kazzzstudio

2018/02/02 10:31

これで良いのか疑問は残りますが、ひとまず動作するようになりました。アドバイス、ありがとうございました。
guest

回答3

0

(deleted)

投稿2018/02/05 01:09

編集2018/02/05 05:00
fuzzball

総合スコア16731

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

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

0

runQuery(_:)が返すのはJSONなので

swift

1// let response = runQuery(_login_url) 2 let responseJson = runQuery(_login_url)

でいいんじゃないの?

投稿2018/02/02 14:06

MasakiHori

総合スコア3384

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

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

kazzzstudio

2018/02/02 14:27

アドバイス、ありがとうございます。 おっしゃる通り、それでいいはずなのですが、うまくいかず、結局、以下のようにしたらできました。まだ原因は不明で、何が悪いのかわかっていません。
MasakiHori

2018/02/02 14:46

print(runQuery(_login_url).type) と print(runQuery(_login_url).error) はどうなるの?
kazzzstudio

2018/02/05 03:40

print(runQuery(_login_url).type)の結果は、stringになりました。
MasakiHori

2018/02/05 04:37

想定しているtypeはdictionayなのでrunQuery関数内で生成しているJSONが壊れてますね... 可能性としては...サーバから返ってきてるデータから生成される文字列が " で括られてしまっている?とかでしょうか? 正しいJSONは {"status": "success" } こう。 サーバからのデータは "{"status": "success" }" となっている可能性。...それでもおかしいですね...これだとパースに失敗... "{\"status\": \"success\" }" こうなってるのかな?
MasakiHori

2018/02/05 04:48

サーバからのデータは変更できないというのであれば、(サーバは第三者が提供している場合) if let jsonString= JSON(response.result.value).string { responseData = JSON(parseJSON: jsonString) } ぐらいでしょうか?
guest

0

自己解決

print(type(of: responseJson.rawValue))から型がわかったので、強引に以下のようにしてみたら正常に動作しました。

Swift

1 let response = runQuery(_login_url) 2 let data: Data? = String(describing: response.rawValue).data(using: .utf8) 3 let responseJson = JSON(data!) as JSON 4 print(responseJson) 5 if (responseJson["status"].stringValue == "success") { 6 loginStatus = 1 7 } 8 else { 9 loginStatus = 0 10 } 11 print(loginStatus) 12

JSONで返って来たはずの値をもう一度Data型にして再度JSONm文字列を作り直すのはスマートではないと思いますが、ひとまず動作するようになりました。

投稿2018/02/02 10:30

kazzzstudio

総合スコア94

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

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

fuzzball

2018/02/05 00:33

init(parseJSON:)の中で同じことをしているので、わざわざ自分でやる必要ないんですよ。 //SwiftyJSON.swiftより抜粋 if let data = jsonString.data(using: .utf8) { self.init(data) }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問