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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Swift

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

API

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

Q&A

1回答

708閲覧

クライアントがサーバーからJSON形式のレスポンスを受け取るにはどのような処理が何ですか?

退会済みユーザー

退会済みユーザー

総合スコア0

JSON

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Swift

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

API

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

0グッド

1クリップ

投稿2019/03/09 05:03

編集2019/03/09 07:02

サーバーに置いたphp7からswift4にjsonを返そうとしています。
##print(req_url)で正しいリクエストURLが作成できている
作成したURLをブラウザに入力すると正しいjsonが帰ってきます。
##受け取ったJSONデータをパース(解析)して格納した後のprint(json)でnilが帰ってくる
###➡︎サーバーからのレスポンスを正しく受け取れていないのでは?
####入門書、参考書、WEBサイトを漁ったのですが、参考にできそうなコードが見つかりません。助けてください。

wakaran.swift

1import UIKit 2 3class ViewController: UIViewController, UITextFieldDelegate { 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 // Do any additional setup after loading the view, typically from a nib. 8 textBar.delegate = self 9 textBar.placeholder = "next" 10 } 11 12 override func didReceiveMemoryWarning() { 13 super.didReceiveMemoryWarning() 14 // Dispose of any resources that can be recreated. 15 } 16 17 @IBOutlet weak var textBar: UITextField! 18 19 @IBOutlet weak var nowText: UILabel! 20 21 // データリスト 22 var dataList : [(date:String , time:String)] = [] 23 24 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 25 textField.resignFirstResponder() 26 if let queryKey = textField.text { 27 print(queryKey) 28 nowmesod(keyword: queryKey) 29 } 30 return true 31 } 32 33 struct ItemJson: Codable { 34 let date: String? 35 let time: String? 36 } 37 38 struct ResultJson: Codable { 39 let item:[ItemJson]? 40 } 41 42 // now メソッド 43 func nowmesod (keyword: String) { 44 // URLをエンコードする 45 guard let keyword_encode = keyword.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { 46 return 47 } 48 49 // リクエストURLの組み立て 50 guard let req_url = URL(string: "http://localhost/v1.php/now?query=(keyword_encode)") else { 51 return 52 } 53 print(req_url) 54 55 // リクエストに必要な情報を生成 56 let req = URLRequest(url: req_url) 57 // データ転送を管理するためにセッションを生成 58 let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main) 59 // リクエストをタスクとして登録 60 let task = session.dataTask(with: req, completionHandler: { 61 (data , response , error) in 62 // セッション終了 63 session.finishTasksAndInvalidate() 64 65 // do try catch エラーハンドリング 66 do { 67 // JSONDecoder のインスタンス取得 68 let decoder = JSONDecoder() 69 // 受け取ったJSONデータをパース(解析)して格納 70 let json = try decoder.decode(ResultJson.self, from: data!) 71 print(json) 72 // ResultJsonが取得てきているか確認 73 if let items = json.item { 74 self.dataList.removeAll() 75 for item in items { 76 if let date = item.date , let time = item.time { 77 let now = (date,time) 78 self.dataList.append(now) 79 // 表示 80 self.nowText.text = "(now)" 81 82 } 83 } 84 } 85 } catch { 86 print("エラーが出ました") 87 } 88 }) 89 task.resume() 90 } 91}

now.php

php

1<?php 2 3 class Now { 4 // 現在の日時をjsonにして返却する関数 (引数:なし, 戻り値: json(string)) 5 public function getAll() { 6 // データを作成 7 $jsonData = [ 8 "date" => (string) date("Y/m/d"), 9 "time" => (string) date("H:i:s") 10 ]; 11 // jsonに変換にしてreturn 12 return json_encode($jsonData); 13 } 14 15 // 現在の日付をjsonにして返却する関数 (引数:なし, 戻り値: json(string)) 16 public function getDate() { 17 $jsonData = [ 18 "date" => (string) date("Y/m/d") 19 ]; 20 return json_encode($jsonData); 21 } 22 23 // 現在の時間をjsonにして返却する関数 (引数:なし, 戻り値: json(string)) 24 public function getTime() { 25 $jsonData = [ 26 "time" => (string) date("H:i:s") 27 ]; 28 return json_encode($jsonData); 29 } 30 } 31 32?> 33

v1.php

php

1<?php 2 3 // エラーを表示 4 ini_set('display_errors', 1); 5 6 // now.phpをインポート 7 require_once(dirname(__FILE__)."/service_v1/now.php"); 8 9 if (empty($_SERVER['PATH_INFO'])) { 10 exit; 11 } 12 13 // URL内で呼ばれたAPIを$callに格納(今回はのnow) 14 $parse = explode('/', $_SERVER['PATH_INFO']); 15 $call = ""; 16 foreach ($parse as $value) { 17 if ($value !== "") { 18 $call = $value; 19 break; 20 } 21 } 22 23 // 呼ばれたAPIのクラスが存在するか確認 24 if (file_exists('./service_v1/'.$call.'.php')) { 25 26 // レスポンスのヘッダにjson,UTF-8,クロスオリジン対策を指定 27 header("Content-Type: application/json; charset=UTF-8"); 28 header("X-Content-Type-Options: nosniff"); 29 header("Access-Control-Allow-Origin: *"); 30 header("Access-Control-Allow-Headers: Content-Type"); 31 32 // 呼ばれたAPIごとに処理を分ける 33 switch ($call) { 34 case "now": 35 // クエリの種類を取得 36 $query = $_GET["query"]; 37 if (!(empty($query))) { 38 // レスポンス用の変数を定義 39 $response = ''; 40 // nowクラス(サービス)のインスタンスを作成 41 $nowApi = new Now(); 42 switch ($query) { 43 case "all": 44 $response = $nowApi->getAll(); 45 break; 46 case "date": 47 $response = $nowApi->getDate(); 48 break; 49 case "time": 50 $response = $nowApi->getTime(); 51 break; 52 default: 53 $response = "{\"error\":\"The query is incorrect\"}"; 54 break; 55 } 56 echo $response; 57 }else{ 58 echo "{\"error\":\"The query is not specified\"}"; 59 } 60 break; 61 default: 62 break; 63 } 64 } 65 66?> 67

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/03/09 05:26

PHPにアクセスして値が返って来ているなら、PHPは正常だと思われますが
退会済みユーザー

退会済みユーザー

2019/03/09 05:35

let req = URLRequest(url: req_url) // データ転送を管理するためにセッションを生成 let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main) // リクエストをタスクとして登録 let task = session.dataTask(with: req, completionHandler: { (data , response , error) in // セッション終了 session.finishTasksAndInvalidate() // do try catch エラーハンドリング do { // JSONDecoder のインスタンス取得 let decoder = JSONDecoder() // 受け取ったJSONデータをパース(解析)して格納 let json = try decoder.decode(ResultJson.self, from: data!) print(json) // ResultJsonが取得てきているか確認 if let items = json.item { self.dataList.removeAll() for item in items { if let date = item.date , let time = item.time { let now = (date,time) self.dataList.append(now) // 表示 self.nowText.text = "\(now)" } } } } catch { print("エラーが出ました") } この辺りで値がnilになっているのでしょうか? それとも、戻ってきたときにはもうnilになっているのでしょうか?
garchomp

2019/03/09 05:40 編集

おそらくですが、swiftの受け取り処理の部分が問題だと思います。 response.bodyにkeyとvelのセットがブラウザで帰ってきていること確認したら、swiftでレスポンスを受け取った時の処理を記述すればいいはずです。
退会済みユーザー

退会済みユーザー

2019/03/09 05:51

echo $response;でブラウザにkeyとvalが帰っていることを確認しているのですが、 swiftでechoに相当する書き方が間違っている、もしくは足りないということでしょうか?
garchomp

2019/03/09 06:16

echoではなくreturnですね。 jsonをリターンさせ、ヘッダーの設定が適切であれば、あとはswift側で受け取れるはずです。
退会済みユーザー

退会済みユーザー

2019/03/09 06:30

echo $response; return; としましたが、print(json)はnilのままでした。 ヘッダーの設定が不適切ということでしょうか? ブラウザでは依然正常に表示されています
退会済みユーザー

退会済みユーザー

2019/03/09 06:36

このような設定をしています header("Content-Type: application/json; charset=UTF-8"); header("X-Content-Type-Options: nosniff"); header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: Content-Type");
退会済みユーザー

退会済みユーザー

2019/03/09 06:50

// echo $response; return; と、echoをコメントアウトしたところ、次のようなエラーが出ました dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.})))
guest

回答1

0

  1. JSONデータはvalidかエラーチェッカーとかでチェック
  2. JSONを受け取ったあとパースはできるのか、単純なJSONを自作して確かめる

投稿2019/03/09 21:20

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問