年末ですね、iOS担当の岩間です。
今回は、ParseというBaaSの導入と簡単な使い方について書きます。
Parseでは豊富な機能が提供されており、SDK経由でそれらの機能を利用することが出来ます。Parse上では以下のような機能が提供されています。
・オブジェクトをKVS上で保存/更新/検索する事が出来る
・ユーザー管理機能(認証)
・アプリ上や、Webフォームからのプッシュ通知の送信
・FacebookやTwitterの認証周りのラッパー
・アプリ内課金の簡単な実装と管理
プッシュ通知などに関して一部の機能制限はありますが、一定数のリクエスト数(https://parse.com/plans)までは無料で利用することが出来るので是非試して見て下さい。
PaseのSDKは様々なプラットフォーム向けに提供されていますが、今回はiOS向けの物について紹介したいと思います。
1.Parse側の準備を整える
まずは、Parseのアカウント取得やテスト用のアプリケーションの作成を行います。
Parseのトップページ https://parse.com/ の右上にある Sign Up ボタンを押すと以下の様なフォームが開きます。入力後サブミットすると、アプリ名や開発者の情報を入れるフォームが表示されるのでそれぞれ入力して下さい。
2.Parseの利用に必要な情報を収集する
ParseのiOSSDKを利用して開発するためには、Application IDとClient Keyが必要になります。Parseにログイン後画面上部にあるDashboardをクリックして、登録されているアプリケーションの一覧の画面を開いて下さい。

アプリケーションの詳細画面の左側に、Application IDとClient Keyが記載されていますので控えておきましょう。

3.開発環境を用意する
開発環境を整える方法は、大きく分けて以下の3つです。
・Parseの提供するiOSSDKをDLし自力でプロジェクトに取り込む
 (https://www.parse.com/downloads/ios/parse-library/latest)
・Parseの提供するSDKを組み込み済みのプロジェクトを利用する
 (https://www.parse.com/downloads/ios/parse-starter-project/latest)
・Cocoa Podsを利用する
 (http://cocoapods.org/)
どれを選んでも良いですが、試してみたいだけであれば組み込み済みのプロジェクトを使う方法、既に開発中のプロジェクトであれば自力でのSDK導入、新規での開発であれば依存ライブラリの解決なんかを肩代わりしてくれるCocoa Podsがオススメだと思います。
Cocoa Pods 用の Podfile はこんな感じ
| 
					 1 2 3  | 
						platform :ios, '5.0' pod 'Parse'  | 
					
何のひねりもありません。
4.主な機能を試しに使ってみる
・Parseを利用する準備をする
アプリケーションの起動時にParseフレームワークに必要な設定を行う。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  // Parseフレームワークに2で取得したApplication IdとClient Keyを設定する。     [Parse setApplicationId:PARSE_APPLICATION_ID clientKey:PARSE_CLIENT_KEY];     // いつもの処理     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];     self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];     self.window.rootViewController = self.viewController;     [self.window makeKeyAndVisible];     return YES; }  | 
					
・オブジェクトを保存する
以下のような形で、オブジェクトを作成しParse上に保存することが可能です。保存処理後の処理を指定できる物を主にあげましたが、保存処理後の処理を指定しないメソッドもそれぞれ用意されています。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35  | 
						- (void)save {     // クラス名を指定してPFObjectのインスタンスを生成する     PFObject *pfObject = [PFObject objectWithClassName:@"Test"];     // pfObjectに値をセットする。 画像やファイル、座標などを保存することも出来る。     [pfObject setObject:@"hoge" forKey:@"fuga"]; #warning 適切な物を選んで使う     // 同期保存を行う     NSError *error1;     BOOL result = [pfObject save:&error1];     NSLog(@"%@", result ? @"オブジェクトの同期保存に成功しました" : error1.description);     // 非同期に保存を行い、保存後の処理の指定にCallbackを指定する     [pfObject saveInBackgroundWithTarget:self selector:@selector(foo)];     //  非同期に保存を行い、保存後の処理の指定にBlockを指定する     [pfObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {         if (succeeded) {             NSLog(@"オブジェクトの非同期保存に成功しました");         } else {             NSLog(@"%@", error.description);         }     }];     // アプリケーションの状態に応じて保存を行い、保存後の処理の指定にBlockを指定する     [pfObject saveEventually:^(BOOL b, NSError *error2) {         if (b) {             NSLog(@"オブジェクトの保存に成功しました");         } else {             NSLog(@"%@", error2.description);         }     }]; }  | 
					
・オブジェクトを検索する
オブジェクトの検索に関して、Parseでは多くの手段が提供されています、ここでは限られた方法にしか触れないので詳細はこちらを参照してください。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14  | 
						- (void)retriever {     // 検索対象のクラス名を指定します     PFQuery *pfQuery = [PFQuery queryWithClassName:@"Test"];     // キー"fuga"の値が、”hoge"と等しい     [pfQuery whereKey:@"fuga" equalTo:@"hoge"];     /*     指定された検索条件で検索を行い、合致する物があった場合はobjectとして該当のObjectを返す     合致する物が無い場合はobjectはnilになり、errorを返す      */     [pfQuery getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {         if (object == nil) NSLog(@"%@", error.description);         NSLog(@"%@", [object objectForKey:@"fuga"]);     }]; }  | 
					
・オブジェクトを更新する
オブジェクトの更新は、検索と保存を組み合わせて行うことが出来ます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | 
						- (void)update{     // 更新対象のオブジェクトを検索して取得する     PFQuery *testFindByHoge = [PFQuery queryWithClassName:@"Test"];     [testFindByHoge whereKey:@"fuga" equalTo:@"hoge"];     [testFindByHoge getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {         if (object == nil) NSLog(@"%@", error.description);         NSLog(@"%@", [object objectForKey:@"fuga"]);         // 取得したオブジェクトの値を変更して保存する         [object setObject:@"piyo" forKey:@"fuga"];         [object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error1) {             if (succeeded) {                 // 更新に成功したかを確認する為に検索してみる                 PFQuery *testFindByPiyo = [PFQuery queryWithClassName:@"Test"];                 [testFindByPiyo whereKey:@"fuga" equalTo:@"piyo"];                 [testFindByPiyo getFirstObjectInBackgroundWithBlock:^(PFObject *object1, NSError *error2) {                     if (object1 == nil) NSLog(@"%@", error.description);                     // piyoと出力される                     NSLog(@"%@", [object1 objectForKey:@"fuga"]);                 }];             }         }];     }]; }  | 
					
・プッシュ通知を使って見る
プッシュ通知を利用するためには、Parseに証明書を登録する必要があります。設定箇所は、アプリのダッシュボードからSettingsの中にあります。

デバイストークンをParseに保存する。
| 
					 1 2 3 4  | 
						// [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; した後で - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {     [PFPush storeDeviceToken:deviceToken]; }  | 
					
チャンネルを登録する。
チャンネルはプッシュ通知を送る範囲を絞り込むために利用します。複数のチャンネルを割り当てることが可能です。
| 
					 1 2 3 4 5 6 7 8 9  | 
						- (void)addChannel {     [PFPush subscribeToChannelInBackground:@"IWAMA" block:^(BOOL succeeded, NSError *error) {         if (succeeded) {             NSLog(@"チャンネルの登録に成功しました");         } else {             NSLog(@"%@", error.description);         }     }]; }  | 
					
プッシュ通知をチャンネルを指定して送信する。
| 
					 1 2 3  | 
						- (void)push{     [PFPush sendPushMessageToChannel:@"IWAMA" withMessage:@"test" error:nil]; }  | 
					
Push通知は、Webフォーム上からも送ることが出来ます。送信されたときの表示のプレビューや、絞り込みの設定が簡単にできたりと便利な作りになっています。
・ユーザー認証
ユーザー認証には、Parseの用意したUI(カスタマイズ可能)を利用する方法と、提供されているAPIを自分で叩く方法の二通りの方法があります。
提供されているUIを利用する場合
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56  | 
						- (void)login {     PFLogInViewController *logInController = [[PFLogInViewController alloc] init];     // Login用デリゲートを設定     logInController.delegate = self;     // LoginUIに表示する項目を渡す     logInController.fields = PFLogInFieldsUsernameAndPassword             | PFLogInFieldsLogInButton             | PFLogInFieldsSignUpButton             | PFLogInFieldsPasswordForgotten             | PFLogInFieldsDismissButton             | PFLogInFieldsFacebook;     // LoginUIのSignUpボタンを押したときに立ち上がるSignUpUIに表示される項目を渡す     logInController.signUpController.fields = PFSignUpFieldsAdditional             | PFSignUpFieldsDefault             | PFSignUpFieldsDismissButton             | PFSignUpFieldsEmail             | PFSignUpFieldsSignUpButton             | PFSignUpFieldsUsernameAndPassword;     // SignUp用デリゲートを設定     logInController.signUpController.delegate = self;     [self presentModalViewController:logInController animated:YES]; } #pragma mark Login Protocol - (BOOL)logInViewController:(PFLogInViewController *)logInController shouldBeginLogInWithUsername:(NSString *)username password:(NSString *)password {     return YES; } - (void)logInViewController:(PFLogInViewController *)logInController didLogInUser:(PFUser *)user { } - (void)logInViewController:(PFLogInViewController *)logInController didFailToLogInWithError:(NSError *)error { } - (void)logInViewControllerDidCancelLogIn:(PFLogInViewController *)logInController { } #pragma mark SignUp Protocol - (BOOL)signUpViewController:(PFSignUpViewController *)signUpController shouldBeginSignUp:(NSDictionary *)info {     return YES; } - (void)signUpViewController:(PFSignUpViewController *)signUpController didSignUpUser:(PFUser *)user { } - (void)signUpViewController:(PFSignUpViewController *)signUpController didFailToSignUpWithError:(NSError *)error { } - (void)signUpViewControllerDidCancelSignUp:(PFSignUpViewController *)signUpController { }  | 
					
自分でAPIを叩いて認証する場合(Sign Up)
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | 
						- (void)signIn {     PFUser *user = [PFUser user];     // ユーザー名     user.username = @"IWAMARYO";     // パスワード     user.password = @"MyPass";     // emailには正当性チェックが掛かります     user.email = @"iwama@example.com";     // その他の情報は通常のオブジェクトに情報を保存するのと同じ方法で保存できます     [user setObject:@"アライドアーキテクツ" forKey:@"company"];     [user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {         if (succeeded) {             // 何事も無く完了した場合         } else {             // ユーザー名重複やメールアドレスの正当性チェックを通過できなかった場合など         }     }]; }  | 
					
自分でAPIを叩いて認証する場合(Login)
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						- (void)logIn {     [PFUser logInWithUsernameInBackground:@"IWAMARYO" password:@"MyPass" block:^(PFUser *user, NSError *error) {         // ログインに成功すると該当ユーザーのオブジェクトを取得することが出来る         if (user) {             // ログインに成功した場合         } else {             // ログインに失敗した場合         }     }]; }  | 
					
ここまでがParseでのユーザー認証、オブジェクトの登録・検索・更新、プッシュ通知の送信設定と送信方法になります。これらを抑えておけば、Parseを利用して簡単なアプリケーションを作るのには困らないのでは無いかと思います。アプリ内課金の簡単な実装と管理はかなり便利な機能なのですが、ちょっとボリュームが大きくなってしまうのでまたの機会にでも書こうと思います。
Parseはドキュメントもしっかり揃っていますしサポート体制も厚いので、何か困ったことがあれば公式サイトのドキュメントやHelpページを見てみると大抵の問題は解決できるハズですので、ぼくみたいにサーバーサイドに情報保存したりプッシュ送ったりしたいけどサーバーサイドの実装までするのはキツいなーって人にはかなりオススメです。
アライドアーキテクツではエンジニアも募集していますが、デザイナーも絶賛募集中です興味の有る方は是非。 https://www.find-job.net/fj/showjob.cgi?id=96051&view=view
(写真撮影担当しました、趣味は写真撮ることです)
それでは皆様、よいお年をお迎えください。。
営業→工場で作業→Word&Excel→Java→shellscript→Java→PHP→Python→Objective-C→Swift→PHP→JavaScript→ベトナム 子会社CTO→本社CTO←イマココ
                
            


        


