StackMobを利用してみました。

2012.07.04

iOSStackMobを試してみました。
StackMobとはBaaS(Backend as a Service)と呼ばれるモバイルアプリケーションに特化したクラウドサービスの一つです。
http://stackmob.com/

ユーザー管理、データストア、FacebookTwitterとの連係、プッシュ配信などがREST APIで提供され、iOSAndroidのSDKも提供されています。 またJavaScalaによるカスタムコードをアップロードすることや、アクセス分析をすることができます。

ユーザー管理、データストアを利用して様々なデバイスで同じデータを使ったアプリケーションが作成できたり、アプリケーションの利用分析ができるなどとても魅力的なサービスと言えそうです。

今回はデータストアとカスタムコードを試してみました。

サービスの利用には無料のユーザー登録とアプリケーションの登録が必要です。
また、iOS用のSDK(今回はStackMobStarterProjectを利用)をダウンロードして、その中に含まれるStackMobConfiguration.hにアプリケーション登録時に発行されたキーを設定する必要があります。
詳細はStackMobのサイトを確認して下さい。
https://stackmob.com/platform/help/tutorials/gs_start

データストアの利用

Datastore APIを利用してデータの保存、読み取り、更新、削除やスキーマ(テーブルのようなもの)の定義を行うことができます。
スキーマの定義はアプリケーションの管理画面で行うこともできますが、予め定義しておかなくてもデータを保存すればIDや更新日時などのフィールドと共に自動で作成してくれます。

データの保存

		    // 保存するデータの作成
		    NSMutableDictionary *dataset = [NSMutableDictionary dictionary];
		    [dataset setValue:@"こんにちは" forKey:@"message"];
		    [dataset setValue:@"takaya" forKey:@"user"];
		    // データ作成のPOST
		    [[StackMob stackmob] post:@"user_message" withArguments:dataset andCallback:^(BOOL success, id result) {
		        if (success) {
		            NSDictionary *resultObj = (NSDictionary *)result;
		            NSLog(@"%@", resultObj);
		        }
		    }];
		

データの読み取り

		    // スキーマのデータ取得
		    [[StackMob stackmob] get:@"user_message" withCallback:^(BOOL success, id result) {
		        if (success) {
		            NSArray *resultObj = (NSArray *)result;
		            for (id one in resultObj) {
		                NSLog(@"%@", one);
		            }
		        }
		    }];
		

作成されたスキーマとデータ

user_message_id, lastmoddate, createddate, sm_ownerは自動で作成されたフィールドです。

その他クエリーなども作成することができます。詳しくは下記URLを確認して下さい。
http://stackmob.com/devcenter/docs/Datastore-API

カスタムコードの利用

StackMobではJavaScalaで自分で作成したコードをデプロイしてREST APIで呼び出すことができます。
SDKが提供されているので、カスタムコード用のインタフェースを継承して必要なメソッドを実装するだけです。
カスタムコードではデータストアにアクセスしたり、プッシュ配信をしたり他のWebサービスを呼び出すことができます。

CustomCodeMethodクラスの作成

				public class MessageCustomeCodeMethod implements CustomCodeMethod {

					/* 
					 * メソッド名を返す。
					 * http://api.mob1.stackmob.com/メソッド名
					 * で呼び出すことになります。
					 * 全体で一意の名前にする必要があるようです。/は使えませんでした。
					 */
				    @Override
				    public String getMethodName() {
				        return "jp_classmethod_user_message";
				    }
				
				    // パラメーター名のリストを返す。
				    @Override
				    public List<String> getParams() {
				        List<String> params = new ArrayList<String>();
				        params.add("user");
				        return params;
				    }
				
				    /*
				     * 呼び出されるメソッド</br>
				     * パラメーターのユーザーのデータを取得して返す。
				     */
				    @Override
				    public ResponseToProcess execute(ProcessedAPIRequest request,
				            SDKServiceProvider provider) {
				        // パラメーターの取得
				        String userValue = request.getParams().get("user");
					
				        // データサービス、クエリーの作成
				        DataService dataService = provider.getDataService();
				        List<SMCondition> query = new ArrayList<SMCondition>();
				        query.add(new SMEquals("user", new SMString(userValue)));
				
				        List<SMObject> result = null;
				        Map<String, Object> resultMap = new HashMap<String, Object>();
				        try {
				            // データサービスの呼び出し
				            result = dataService.readObjects("user_message", query);
				            if (result != null) {
				                for (SMObject one : result) {
				                    resultMap.put("user", one.getValue().get("user"));
				                    resultMap.put("message", one.getValue().get("message"));
				                }
				            }
				            return new ResponseToProcess(HttpURLConnection.HTTP_OK, resultMap);
				        } catch (InvalidSchemaException e) {
				            resultMap.put("error", e.getMessage());
				            return new ResponseToProcess(HttpURLConnection.HTTP_INTERNAL_ERROR,
				                    resultMap);
				        } catch (DatastoreException e) {
				            resultMap.put("error", e.getMessage());
				            return new ResponseToProcess(HttpURLConnection.HTTP_INTERNAL_ERROR,
				                    resultMap);
				        }
				    }
				}
		

JarEntryObjectにCustomCodeMethodクラスを追加

作成したCustomCodeMethodJarEntryObjectを継承したクラスに追加します。

				public class EntryPointExtender extends JarEntryObject {

			    @Override
			    public List<CustomCodeMethod> methods() {
			        List<CustomCodeMethod> list = new ArrayList<CustomCodeMethod>();
			        list.add(new MessageCustomeCodeMethod());
			        return list;
			    }
		

jar作成してをアップロード

指定のmanifestファイルでjarを作成して、StackMobの管理画面にアップロードします。
アップロードが完了すると下記のように表示されます。

カスタムコードの呼び出し

			// パラメーターの作成
			NSMutableDictionary *dataset = [NSMutableDictionary dictionary];
			    [dataset setValue:@"takaya" forKey:@"user"];
			    [[StackMob stackmob] get:@"jp_classmethod_user_message" withArguments:dataset andCallback:^(BOOL success, id result) {
			        if (success) {
			            NSDictionary *resultObj = (NSDictionary *)result;
			            NSLog(@"%@", resultObj);
			        }
			    }];		
		

その他の詳細は下記URLを確認して下さい。
https://www.stackmob.com/devcenter/docs/Getting-Started:-Custom-Code-SDK

今回二つの機能を試してみましたが、分かりやすいドキュメント、SDK、管理画面が提供されているのでどちらもとても簡単に利用することができました。
同じようなサービスは他にもいくつかあるので時間があれば他にも試してみたいと思います。