iPhoneアプリ開発

【Swift】外部サーバーのDBにPHP経由で接続

iPhoneアプリでエックスサーバーのmysqlのテーブル情報を取得するため、サーバーに置いたPHPファイルを経由しJSON形式で取得する。

簡単な流れは以下となる。

 

1.swift-jsonというライブラリを使用するため、ググってライブラリを配置

 

2.PHPからmysqlに接続し、テーブル情報を取得

/* DB定義 */
$dbHost = 'mysqlxxxx.xserver.jp';
$dbUser = 'test_usr';
$dbPass = 'test_pwd';
$dbName = 'test_db';
$tblName = 'test_dbl';

// DBへ接続
$link = mysql_connect($dbHost, $dbUser, $dbPass);
if (!$link) {
    die('接続失敗です。'.mysql_error());
}

print('<p>接続に成功しました。</p>');

$db_selected = mysql_select_db($dbName, $link);
if (!$db_selected){
    die('データベース選択失敗です。'.mysql_error());
}

print($dbName.'<p>データベースを選択しました。</p>');

mysql_set_charset('utf8');

/* データ取得 */
$sql = 'SELECT * FROM '.$tblName. ' ORDER BY id ASC ';
$result = mysql_query($sql);
if (!$result) {
    die('SELECTクエリーが失敗しました。'.mysql_error());
}

// 取得情報をJSON形式に変換
$json= array();
while ($row = mysql_fetch_assoc($result)) {
	$json[] = array(
	'id'=> $row['id']
	,'title' => $row['title']
	,'date' => $row['date']
	);
}

//jsonとして出力
header('Content-type: application/json');
echo json_encode($json);

 

3.アプリからPHPファイルに接続し、JSON形式で取得

func getJson() {
    // APIからJsonを取得してパース
    let json = JSON(url:"http://xxx.com")
        
    // 特定の要素の取り出し
    let title = json[0]["title"]
    print("title \(title)")
}

JSONを取得しSwiftで編集する際、以下エラー発生。

Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.

Swiftファイルと同じ階層にあるInfo.plistを以下のように編集。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-14-9-19-52%ef%bc%882%ef%bc%89

(1)「App Transport Security Settings」を右クリック⇨「Add Row」で「Exception Domains」を追加

(2)「Exception Domains」を右クリック⇨「Add Row」でJSONファイルを置いているサーバーのドメインを入力して追加

(例)http://xxx.com の場合 ⇨ 「xxx.com」

(3)同じく追加で「NSTemporaryExceptionAllowsInsecureHTTPLoads」をBooleanでYesに設定

これで指定したドメインとHTTP通信が可能。

だが、次は以下の別エラーが発生。

Error Domain=NSCocoaErrorDomain Code=3840 “JSON text did not start with array or object and option to allow fragments not set.” UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

どうやらきちんとしたJSON形式ではないと出るエラーらしい。

原因は、非推奨となっていた「mysql_connect」を使ったことで、JSON以外にwarningのメッセージが混入していたため。

推奨されている「mysqli_connect」に書き直したのが以下。

// DBへ接続
$mysqli = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
if ($mysqli->connect_error) {
	echo $mysqli->connect_error;
	exit();
} else {
	$mysqli->set_charset("utf8");
}

/* データ取得 */
$sql = 'SELECT * FROM '.$tblName. ' ORDER BY id ASC ';
$result = $mysqli->query($sql);
if (!$result) {
	
    die('SELECTクエリーが失敗しました。'.mysql_error());
	
	// 結果セットを閉じる
	$result->close();
}

// DB接続を閉じる
$mysqli->close();
	
//取得した結果を取り出して連想配列に入れていく
$json= array();
while ($row = $result->fetch_assoc()) {
	$json[] = array(
	'id'=> $row['id']
	,'title' => $row['title']
	,'date' => $row['date']
	);
}

//jsonとして出力
header('Content-type: application/json');
echo json_encode($json);

これでSwiftでJSON形式でテーブル情報が取得可能になった。