• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Swiftについて教えてください)

SwiftとPHPの連携方法について教えてください

このQ&Aのポイント
  • SwiftとPHPの連携方法について詳しく教えてください。具体的には、Objective-CからPHPファイルに同期通信する方法、PHPファイルで配列を生成し、それをSwiftの配列に取り込む方法について教えてください。
  • 質問者はSwiftとPHPの初心者で、同期通信や配列の取り込みについて詳しく知りたいとしています。質問文章には、SwiftでURLリクエストを作り、同期通信を行い、レスポンスデータを処理する部分が記述されていますが、それ以降の処理についても具体的な説明を求めています。
  • また、質問者はPHP側でディレクトリの存在を確認し、ファイルのみを取得し、そのパスを配列に追加するコードを作成しているようです。どのようにSwiftの配列に取り込むことができるのか、詳しく教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

No.2の補足についてアドバイスします。 エラーが発生した時に、エラーの原因を自分で調べようとしていますか? あるいは、どうやって原因を調べたらいいか基本的なことを理解していますか? JSONObjectWithDataの行で "unexpectedly found nil while unwrapping an Optional value" (オプショナル値をアンラップしようとして期待はずれのnilを検出した) というエラーが発生しているのですから、そのJSONObjectWithDataに指定している data変数の値を確認してください。 エラーメッセージから推測すると、たぶん、data変数がnilになっていて、 それを「data!」でアンラップしようとしてエラーが発生したのではないかと思います。 dataがnilなのであれば、なぜdataがnilになったのか自分で調べてください。 https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/index.html#//apple_ref/occ/clm/NSURLConnection/sendAsynchronousRequest:queue:completionHandler: を確認すると、 「If the request fails, the data parameter is nil and the error parameter contain information about the failure.」 と書かれています。 つまり、リクエストが失敗したということです。 そして、error変数にその原因を示す情報が入っているということですから、 error変数の内容を確認すれば、なぜ失敗したのかヒントが得られるはずです。 それと、今はテスト実行しているだけなのでエラーチェック等あまりしてないのだと 思いますが、本来はdata変数がnilかどうか確認した上でnilでない時だけ JSONObjectWithDataを実行し、nilの時はerror変数を出力する等のエラー処理をすべきです。 そういう処理をちゃんと組み込んでいないのが自分で自分の首をしめている (エラーをわかりくくしている)原因かもしれません。

dkong
質問者

お礼

いつもアドバイスありがとうございます。本当に助かっています。 エラーが発生した時に、エラーの原因を自分でも調べているのです。調べ方が甘いかもしれませんが…。エラーをコピペして検索しているのですが、そこに書かれていることがまた分からなくなってしまう状況です。教えていただいた内容やコードについても調べて理解しようと努めていますが、入門書を数冊読んだ程度などで、深い理解ができていません。おっしゃられるようにの、どうやって原因を調べたらいいか基本的なことを理解できていません。入門書レベルからステップアップしてエラー対策をしていくにはどうしていけばよいでしょうか?アドバイスよろしくお願いします。

その他の回答 (3)

回答No.4

No.3のお礼について回答します。 > おっしゃられるようにの、どうやって原因を調べたらいいか基本的なことを理解できていません。入門書レベルからステップアップしてエラー対策をしていくにはどうしていけばよいでしょうか?アドバイスよろしくお願いします。 No.3でそれを具体的にアドバイスしたつもりなのですが。 エラーメッセージの意味やエラーの状況をよく調べて、その原因を一生懸命考えるしかないと思います。それと、入門書やWebサイトはだいたいの使い方をわかりやすく解説してくれますが、できることを全て網羅しているわけではありません。あまり使われないメソッドや細かいエラーの意味は入門書では詳しく説明していませんので、本格的に自分で使おうとしているクラスについては、最終的にはAppleのリファレンスをよく読んで理解する必要があります。 そうやって個々の問題を1つずつ解決しながら経験と知識を積み上げていくしかないと思います。わからないことを調べたら、さらにわからないことが出てくるのもよくあることだと思います。 それでわからなければ質問サイトで質問してみるのもよいと思いますが、その場合、エラーメッセージだけ書いて「よろしくお願いします」とだけ書くのではなく、そのメッセージを元にどういうところを調べ、どういう点がわからなかったかを説明して質問しないと、エラーメッセージの意味すら調べようとせず、メッセージを書けば誰かが解決してくれると思っているようにしか見られません。 それで腹が立った質問は私は何も回答しませんが、入門者のアドバイスをすることは私にとってもこれまでの知識の再確認になるため、簡単なアドバイスで困っている人の役に立ちそうなら回答します。 No.3の回答も確認すべき点を1つずつ具体的にアドバイスしたつもりなのですが、それをちゃんと確認したのでしょうか? data変数がnilなのかどうか確認しましたか? error変数に何か入っているか確認しましたか? error変数にメッセージが入っていたら、そのメッセージの意味を調べて、原因を考えてみましたか? そういうのを調べた上でさらにわからないところが出てきたら、また聞いてみてください。 気が向いたらまたアドバイスします。

回答No.2

補足の質問に回答します。 > 質問その1 > phpの方は配列をJSON形式にできているのですが、echo json_encode($array);するとスラッシュの前にバックスラッシュが入るのはなぜでしょうか? JSON形式では、バックスラッシュ+スラッシュで、スラッシュ一文字を表しますから、それで正しくJSON形式に変換できています。 詳しくは https://tools.ietf.org/html/rfc7159 の8ページ目に書かれてあるルールでJSON形式の文字列に変換されているということです。 > 質問その2 > swiftの方はfunc responseの部分で以下のエラーがでて、JSONの解析がうまくいっていません。 responseメソッドのパラメータは func response(res: NSURLResponse!, data: NSData!, error: NSError!){ ではなくて func response(res: NSURLResponse?, data: NSData?, error: NSError?){ ではないですか? (参考) https://sites.google.com/a/gclue.jp/swift-docs/ni-yinki100-ios/13-http/fei-tong-qihttp

dkong
質問者

お礼

回答ありがとうございます。 エラーが消えません。補足コメントさせてください。

dkong
質問者

補足

教えていただいたように func response(res: NSURLResponse!, data: NSData!, error: NSError!){ を func response(res: NSURLResponse?, data: NSData?, error: NSError?){ と直したのですが fatal error: unexpectedly found nil while unwrapping an Optional value(lldb) は消えません。 let list:NSArray = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSArray のとろに Thread1:EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP,subcode=0x0) と表示されています 回答よろしくお願いします。

回答No.1

JSON形式に変換して受け渡しすれば比較的簡単で応用もしやすいです。 PHP側は、 http://php.plus-server.net/function.json-encode.html を参考にして、$arrayをjson_encodeでJSON形式に変換したものを出力し、 swift側は、 http://qiita.com/yosi-q/items/7ad1db0dca7b2dd4c065 を参考にして、sendSynchronousRequestの戻り値で受け取ったresDataを NSJSONSerializationでパース(逆変換)すれば、配列で受け取ることができます。

dkong
質問者

お礼

回答ありがとうございます。教えていただいたサイトはとても勉強にになりました。参考にやってみたのですがうまくいかず困っています。追加の質問よろしくお願いします。

dkong
質問者

補足

2点質問があります。教えてください。 質問その1 phpの方は配列をJSON形式にできているのですが、echo json_encode($array);するとスラッシュの前にバックスラッシュが入るのはなぜでしょうか? <?php  // $array = array(); // ディレクトリのパスを記述 $dir = "xxxxxxxx/" ; // ディレクトリの存在を確認し、ハンドルを取得 if( is_dir( $dir ) && $handle = opendir( $dir ) ) { // ループ処理 while( ($file = readdir($handle)) !== false ) { // ファイルのみ取得 if( filetype( $path = $dir . $file ) == "file" ) { // array_push($array, $path); } } } echo json_encode($array); ?> 質問その2 swiftの方はfunc responseの部分で以下のエラーがでて、JSONの解析がうまくいっていません。 fatal error: unexpectedly found nil while unwrapping an Optional value 回答よろしくお願いします。 import UIKit class ViewController: UIViewController, NSURLConnectionDelegate { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let URL = NSURL(string: "http://xxxxxxx/xxx/xxx.php") let req = NSURLRequest(URL: URL!) let connection: NSURLConnection = NSURLConnection(request: req, delegate: self, startImmediately: false)! // NSURLConnectionを使ってAPIを取得する NSURLConnection.sendAsynchronousRequest(req, queue: NSOperationQueue.mainQueue(), completionHandler: response) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } // 取得したAPIデータの処理 func response(res: NSURLResponse!, data: NSData!, error: NSError!){ let list:NSArray = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSArray // 1行ずつログに表示 for var i=0 ; i<list.count ; i++ { println(list[i]) } }