ちろる

理系大学生が自由気ままに

Swift4でMac上のlocalhostにPOST

実行環境

・Swift4
PHP 7.1.16
MAMP 4.4.1
Xcode 9.4.1
macOS High Sierra 10.13.6

MaciPhoneが同一のWiFiに接続していること

サーバーサイド

MAMP(MAMP & MAMP PRO)をインストールし、起動したら下記の画面の"Start Servers"をクリック。
f:id:tsupiano:20180907083441p:plain


"/Applications/MAMP/htdocs"のフォルダ内に以下のようなa.phpを作成する。

<?php 
$title = $_GET["title"];
$note = $_GET["note" ];
print "$title$note";

テストとして、以下のURLをMacのブラウザで検索し、"title : note"と表示されれば成功である。

http://localhost:8888/a.php?title=title&note=note

これでサーバー側は完了。

クライアントサイド

以下のコマンドをterminalで実行し、ipアドレスをメモる。

ifconfig | grep mask

Info.plistのソースコードを開き、末尾に以下を追加する。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>192.168.100.70</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <false/>
        </dict>
    </dict>
</dict>

f:id:tsupiano:20180907084102p:plain

次に、Main.StoryboardとViewControllerを作成する。
f:id:tsupiano:20180907084943p:plain

import UIKit

class ServerController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBOutlet weak var resultLabel: UILabel!
    @IBOutlet weak var inputText1: UITextField!
    @IBOutlet weak var inputText2: UITextField!
    
    @IBAction func onButtonTap(_ sender: UIButton) {
        if inputText1.text != "" && inputText2.text != "" {
            let title = inputText1.text!
            let note  = inputText2.text!
            
            let stringUrl = "http://192.168.1.9:8888/a.php?title=\(title)&note=\(note)"
            // Swift4からは書き方が変わりました。
            let url = URL(string: stringUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)!
            let req = URLRequest(url: url)
            
            let task = URLSession.shared.dataTask(with: req, completionHandler: {
                (data, res, err) in
                if data != nil {
                    let text = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                    DispatchQueue.main.async(execute: {
                        self.resultLabel.text = text as String?
                    })
                }else{
                    DispatchQueue.main.async(execute: {
                        self.resultLabel.text = "ERROR"
                    })
                }
            })
            task.resume()
        }else{
            // 未入力
            alert("error", messageString: "It is not entered.", buttonString: "OK")
        }
    }
    // 標準のアラートを表示させる
    func alert(_ titleString: String, messageString: String, buttonString: String){
        //Create UIAlertController
        let alert: UIAlertController = UIAlertController(title: titleString, message: messageString, preferredStyle: .alert)
        //Create action
        let action = UIAlertAction(title: buttonString, style: .default) { action in
            NSLog("\(titleString):Push button!")
        }
        //Add action
        alert.addAction(action)
        //Start
        present(alert, animated: true, completion: nil)
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool{
        //Close keyboard.
        textField.resignFirstResponder()
        
        return true
    }
}

実行結果

2つのテキストボックスに値を入力してボタンを押すと、下にinputText1 : inputText2が返され表示される。
f:id:tsupiano:20180907085253j:plain