Illust & Music 月の高いところ

今日のプリン言

謎のプリン語る。
一人書く人増えました。

Objective-C、NSArray、配列をデータベースに保存する方法

2014年04月24日

みやびプリン 140 87

144 144

※この記事は6年以上前の記事です。
現在は状況が異なる可能性がありますのでご注意ください。

どうもお久しぶりです。
みやびです。

だいぶ空きましたね。
ずっとiPhoneアプリの開発やってました。
まだやってるけどね。

というわけで、Objective-Cの記事書いてくぜ!
ほんとに、このObjective-Cがくせ者です。
なんせ、Google先生があまり役に立たないっていうね。こんなん初めてだ。
自分で頭フル回転させて、英語の公式リファレンスみながらやらなきゃいけないなんてな・・・。

はい、毎度のごとく前置き長いっすね。
さて、題号の本題いってみよう。

今回は、一発ではいかないが、やれたら便利な技術。
アプリ側のNSArrayを、PHPにポスとして、データベースに保存する方法だ。
これをやれると便利なのは、例えばユーザーの情報の中に、さらに送り先の住所一覧をいれる、とか。いろいろやれる。

さて、やっていこう。まずはアプリ側からPOSTする方

//NSArrayをNSDataに変換、JSONを生成
//PHP側にJSONとして送った時にDBでレコードを特定するために辞書にID的なものと、配列を格納する
NSMutableDictionary *SubmitDic = [NSMutableDictionary dictionary];
SubmitDic[@"ID"] = @"idString";
SubmitDic[@"Contents"] = ArrayData; //配列が入っている変数

//ここでJSONとしてのNSDataを生成
NSError *error002 = nil;
    
NSData *SubmitData = [NSJSONSerialization dataWithJSONObject:SubmitDic options:NSJSONWritingPrettyPrinted error:&error002];
    
if(error002){
  NSLog(@"%@", [error002 localizedDescription]);
}

//NSURLSessionの生成
NSURLSessionConfiguration *URLSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];

NSURLSession *URLSession = [NSURLSession sessionWithConfiguration:URLSessionConfiguration delegate:nil delegateQueue:nil];

//URLの生成
NSURL *URLU = [NSURL URLWithString:@"http://test.com/db_save.php"];

//NSURLRequestの生成
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URLU];
//HTTPメソッドは"POST"
[request setHTTPMethod:@"POST"];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody: SubmitData];
    
NSURLSessionDataTask *URLSessionDataTask = [URLSession dataTaskWithRequest:request
                                                             completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
                                                                 [URLSession invalidateAndCancel];
                                                             }];
    
[URLSessionDataTask resume];
    
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

大事なのは、JSONに変換すること。
PHPと、Objective-cとの連携はJSONが最もやりやすい。

ではPHP側。
まずはDBに接続する準備として、まずは二つのPHPを用意する。

●DBConfig.php

<?php

define("DB_SERVER","localhost"); // サーバ
define("DB_NAME","データベース名"); // データベース
define("DB_USER","DBユーザ名"); // ユーザ
define("DB_PASSWD","DBパスワード");  // パスワード

●DBConnect.php

<?php

require_once('DBConfig.php');

function connect() {
	$link = mysql_connect(DB_SERVER,DB_USER,DB_PASSWD);
	if(!$link) {
		die("Can not connect ".DB_SERVER." : ".mysql_error());
	}

	if(!mysql_select_db(DB_NAME)) {
		die("Can not use ".DB_NAME." : ".mysql_error());
	}

	return $link;
}

// Close
function close($link) {
	mysql_close($link);
}

// Prepare
function prepare ($value) {
	return mysql_real_escape_string($value);
}

以上二つのファイルは最悪いらない。
というのも、管理しやすいように、ファイルを分けているだけで、一つのphpファイルでもDBに接続できる。
ただし、分けないでやると、一個のファイルの内容がバレると、DBの情報が盗み放題になるので、セキュリティ面を考えても、分けた方がいい。

さて、三つ目のPHP、アプリからPOSTしたJSONを、DBに保存するスクリプトだ。

●db_save.php

<?php

//DB接続処理
require_once('DBConnect.php');

// 接続
$link = connect();

//POSTされた生データ(JSON)を取得
$json_string = file_get_contents('php://input');

//JSONを、PHPで扱える配列(元がNSDictionaryなので連想配列)に変換
$obj = json_decode($json_string);

//連想配列して入っているデータをそれぞれ変数に格納
$RecoadID = $obj -> {'ID'};

$addressBefore = $obj -> {'Contents'};

//'Contents'の中に入っている配列を、文字列にする
$paramAddressList = serialize($addressBefore);

//クエリ文を生成
//今回は、SQLのUPDATEを使って、user_baseというテーブルの、user_idというカラムで検索したレコードのuser_addresslistというカラムを更新している。
$sql = "UPDATE user_base  SET user_addresslist = '$paramAddressList' WHERE user_id = '$RecoadID'";

//クエリの実行
$result = mysql_query($sql);
if (!$result) {
	exit('データを更新できませんでした。');
}

//DBを閉じる(読み込んだPHPにあらかじめ記載している関数を実行)
close($link);

大事なのは、JSON→配列→シリアライズ(文字列化)というように、変換して最終的には文字列としてDBに保存すること。
だいたいにおいて、配列のまんまだとDBにゃ保存できんからね。 それと、SQLに関しては、

ついでにDBからアプリにデータを読み込むもやっておこうか。
こっちはPHPから説明する

●address_get.php

<?php

//DB接続処理
require_once('DBConnect.php');

// 接続
$link = connect();

//POSTから、文字列を取得
$paramID = $_POST['id'];

//SQL文生成
$sql = "SELECT * FROM user_base WHERE user_id = '$paramID'";

//クエリの実行
$result = mysql_query($sql);
if (!$result) {
	exit('データを取得できませんでした。');
}

//配列を取得するためにあらかじめ変数宣言
$result_addressData;

//実行したクエリ($result)から、必要な情報を取ってくる
while($row = mysql_fetch_array($result)){
	//文字列として保存された配列を、配列に直して、変数に格納
	$result_addressData = unserialize($row["user_addresslist"]);
}

//配列をJSONに変換
$json_value = json_encode($result_addressData);

//JSONを出力
header( 'Content-Type: text/javascript; charset=utf-8' );
echo $json_value;

//DBを閉じる
close($link);

先ほどやった行程とは逆を実行する。
文字列→配列(文字列をアンシリアライズ化する)→JSON
そして、JSONをechoすれば、アクセスしたアプリはJSONを読めるってすんぽう。

さてアプリ側の受け取り

//クエリ文を生成
NSString *queryBefore = [NSString stringWithFormat:@"id=%@", @"ユーザーのID"];

//NSURL生成
NSURL *url = [NSURL URLWithString:@"http://test.com/address_get.php"];
//クエリ文をNSDataに変換
NSData *InData = [queryBefore dataUsingEncoding:NSUTF8StringEncoding];

//NSURLRequestを生成    
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:HTTP_METHOD];
[request setValue:HTTP_VALUE forHTTPHeaderField:HTTP_HEADER_FIELD];
[request setHTTPBody:InData];

//JSONをNSDataとして受け取る
NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
NSError *error = nil;

//NSArray型の変数にJSONデータを元のデータに戻したものを入れる
NSMutableArray *InnerData = [NSJSONSerialization JSONObjectWithData:jsonData
                                                          options:NSJSONReadingAllowFragments
                                                            error:&error];

これで、配列が取得できました。

応用するといろんなことができると思う。

そしてさらに、同じ概念で、UserDefaultとか、CoreDataにも、配列を保存できる。
それはまた今度。

今回、コード自体が長い・・・。

チョコットランド - メイン

トラックバック(0)

トラックバックURL:

コメントする