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

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

ただいまの
回答率

87.50%

実機でhttp通信をすると失敗する

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 5,168

score 23

 前提・実現したいこと

ローカルのMySQL内のデータを引っ張ってきて
tableViewで一覧表示をしたいのですが、シミュレータだと表示までできるのですが
実機で確認すると、以下のエラーメッセージが表示されてしまいます。

以下のリンク先を参考に
info.plistを編集してみたのですが、解消されませんでした。

手詰まりなためご教示頂けると幸いです。
宜しくお願い致します。

 発生している問題・エラーメッセージ

2018-10-29 09:48:51.732365+0900 WebAPITest[6741:2290709] TIC TCP Conn Failed [1:0x1c4169f00]: 1:61 Err(61)
2018-10-29 09:48:51.732444+0900 WebAPITest[6741:2290709] Task <9BF294B7-56E1-4854-8C45-B5D6FEDF570B>.<1> HTTP load failed (error code: -1004 [1:61])
2018-10-29 09:48:51.732647+0900 WebAPITest[6741:2290710] Task <9BF294B7-56E1-4854-8C45-B5D6FEDF570B>.<1> finished with error - code: -1004

 該当のソースコード

import UIKit
import Alamofire
import Foundation

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    @IBOutlet weak var dbTableView: UITableView!

    var dbItems:[JsonModel] = []
    let refreshControl = UIRefreshControl()
    let url = "http://127.0.0.1/test.php"

    @IBAction func addData(_ sender: UIBarButtonItem) {
        //print("押された")
        showAlert()
    }

    private func showAlert(){
        let alert = UIAlertController(title: "test", message: "aaaaa", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default, handler: {
            (action:UIAlertAction!) -> Void in
            // OKを押した時入力されていたテキストを表示
            if let textFields = alert.textFields {
                // アラートに含まれるすべてのテキストフィールドを調べる
                for textField in textFields {
                    print(textField.text!)
                }

                self.post()
            }
        })
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        alert.addAction(okAction)
        alert.addAction(cancelAction)
        alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in
            textField.placeholder = "テキスト"
        })

        self.present(alert, animated: true, completion: nil)
    }

    //DBにデータを追加する
    private func post(){
        let headers:HTTPHeaders = [
            "Contenttype":"application/json"
        ]

        let parameters:[String:String] = [
            "name":"testName"
        ]

        Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
            if let result = response.result.value as? [String: String] {
                print(result)
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        dbTableView.delegate = self
        dbTableView.dataSource = self
        dbTableView.tableFooterView = UIView(frame: .zero)
        dbTableView.refreshControl = self.refreshControl
        self.refreshControl.addTarget(self, action: #selector(ViewController.refresh(sender:)), for: .valueChanged)

        self.request()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    private func request(){
        //tableViewCell表示用の配列を一度空にする
        self.dbItems = []

        /*ここで通信失敗になる*/
        Alamofire.request(url).responseString { response in
            if let value = response.result.value{
                let data = value.data(using: .utf8)!
                self.decodeJson(data: data)
            }
        }
    }

    private func decodeJson(data:Data){
        let decoder:JSONDecoder = JSONDecoder()
        do{
            let json:[JsonModel] = try decoder.decode([JsonModel].self, from: data)
            for item in json{
                self.dbItems.append(item)
            }
            //データ追加後の再読込
            self.dbTableView.reloadData()
        }catch{
            print("json convert failed in JSONDecoder", error.localizedDescription)
        }
    }

    @objc func refresh(sender:UIRefreshControl){
        request()
        sender.endRefreshing()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dbItems.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = dbItems[indexPath.row].id
        cell.detailTextLabel?.text = dbItems[indexPath.row].name

        return cell
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <!--ここを追加した-->
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    <!---->
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>

 試したこと

こちらを参考にinfo.plistを編集しました。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

http通信をするためにはATSを許可してあげる必要があったと思います
https://dev.classmethod.jp/smartphone/iphone/ios-ats-cheats-info-plist-settings/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

let url = "http://127.0.0.1/test.php"

iOS Simulatorの場合は同じMacの中なのでローカルホストでも大丈夫ですが、
実機の場合指定するIPアドレスはPCのIPアドレスを指定しないといけません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

ローカルPCと実機が同じLANに接続されている必要があります。
スマホをWi-FiでそのPCと同じLANに接続しましょう。
もしくはそのPCがWANで繋がる場所に設置する必要があります。
シミュレータは、ようは自分のPCから自分のPCにつないでるだけなので
ネットワーク上何の問題もないのです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/29 10:17

    ご回答頂きありがとうございます。

    今ローカルのPCがwifi接続されているのですが
    実機の端末も同じwifiに繋げば良さそうでしょうか・・・?
    後程試してみてわからなければ再度質問させて下さい。

    キャンセル

  • 2018/10/29 10:19

    そうです。実機の端末をそのPCと同じLANにWi-Fi接続してください。

    キャンセル

  • 2018/10/29 10:20

    試してみます!ご回答頂きありがとうございました!

    キャンセル

  • 2018/10/30 08:51

    他の方の回答も参考に同じLANに接続したら
    無事実機で動作確認することが出来ました。
    ご回答頂きありがとうございました!

    キャンセル

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

  • ただいまの回答率 87.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る