Parse.comを使ったサーバサイド実装不要のフロントエンド開発[後編]

本記事はParse.comを使ったサーバサイド実装不要のフロントエンド開発[前編]の後編です。前編では、Parseの管理画面と、JavaScript SDKのうちBackbone.jsをベースとしている部分とCollectionの生成に必要となるデータの取得方法をご紹介しました。
後編では引き続き、ParseのJavaScript SDKの機能として以下の3つをご紹介いたします。

  • Parse.User: アカウント管理
  • Parse.File: 画像をはじめとしたファイルのアップロード処理等
  • Parse.Promise: Defferedの仕組み
  • Parse.GeoPoint: 位置情報

Parse.User

Parse.Userは、ユーザーアカウントの管理に特化したオブジェクトで、サインアップやログイン機能を実装することができます。Userは、前編でご紹介したParse.Objectのサブクラスであり、Objectのすべての機能が使えます。Objectと同じように、情報はParseに自動的に永続化されます。Objectと異なる点として、User管理に必要な以下のプロパティを保持します。

  • username(必須)
  • password(必須)
  • email(任意)

■サインアップ

新規ユーザーの作成には、signUpメソッドを使います。サインアップ時には、ユーザー名およびe-mailが一意であるかどうかチェックされ、一意でない場合にはエラーが発生します。また、パスワードはハッシュ化されますので、平文で保存されることはありません。

// 実装時はuserName、passwordをログインフォームから取得var userName = "hiromitsuuuuu";var password = "xxxxx"; Parse.User.signUp(userName, password, {success: function(user){// サインアップ成功},error: function(user, error){// サインアップ失敗}});

emailをユーザー名として使ったり、パスワードのリセット機能を追加することもできます。

■ログイン

ログイン処理にはlogInメソッドを、ユーザーのログイン有無の確認にはcurrentメソッドを使います。一度ログインするとUserオブジェクトがlocalStrageにキャッシュされ、ログイン有無の判別に使われます。このキャッシュはログアウトすると消去されます。

// ログイン処理Parse.User.logIn(userName, password, {success: function(user){// ログイン成功},error: function(user, error){// ログイン失敗}}); // ログイン有無の確認(Boolean値が返ります)if(Parse.User.current()){// ログイン済}else{// 未ログイン} // ログアウトParse.User.logOut();

Userは、logInやsignUpといった認証の結果として得られたオブジェクトでなければsaveもdeleteもできない仕組みになっています。そのため、User一覧を取得したとしても他のユーザーは読み取り専用となり改編できません。Parse.User.current() は認証済みオブジェクトが返されます。

Parse.File

画像やファイルのデータはParse.Objectに収めるには大きすぎるため、これらを扱うためのParse.Fileというオブジェクトが用意されています。ドキュメントやビデオ、音声など最大10MBまでのバイナリデータを保存することができます。自力でファイルアップロードを実装する場合、multipart/form-dataエンコードが必要であったりしますが、Fileではエンコードの処理を書く必要がありません。base64形式のデータを引数として渡し、saveすればアップロードが完了します。

<input type="file" id="profile-photo">
var fileUploadControl = $("#profile-photo")[0];if (fileUploadControl.files.length > 0) {var file = fileUploadControl.files[0];// 新規Fileオブジェクトの作成var parseFile = new Parse.File(file.name, file);// Parseへのデータ保存parseFile.save();}

Fileを含む任意のObjectを作成したい場合、先に画像の保存が完了している必要があります。そのため、以下のような段階的な処理が必要となります。

// Parseへのファイル保存parseFile.save({success: function(file){// articleというObject(Model)のprofilePhotoフィールドに画像を保存するarticle.set("profilePhoto", file);article.save();},error: function(error){// ファイル保存失敗}});

このように、Parseでは非同期処理を段階的に行うことが多いため、SDKでParse.Promiseというオブジェクトが用意されています。

Parse.Promise

jQueryと同様に、ParseのJavaScript SDKの非同期メソッドはPromiseを返すよう設計されています。Backboneのシンタックスと共通のObjectのsaveや、先ほどご紹介したFileのsave、前編でご紹介したQueryのfindがこれにあたります。そのため、thenメソッドを使ってメソッドチェインさせることができます。thenはコールバックのペアを引数に取り、第1引数に成功時の関数、第2引数に失敗時の関数を指定します。

obj.save().then(saveSuccess, saveFailed);// 別途saveSuccess, saveFailed関数を定義 // チェインさせる。第1引数はすべてPromiseを返すメソッドobj.find().then(setAttribute).then(findStudents).then(setStudent, setStudentErrorHandler).then(sayHello, errorHandler);

whenメソッドも提供されているので、並列処理を行うこともできます。

query.find().then(function(results) { var promises = []; _.each(results, function(result) {// 同時に非同期処理を実行promises.push(result.destroy());}); // すべてのPromiseが解決済みになるのを待つreturn Parse.Promise.when(promises); }).then(function() {// すべての処理が完了してから実行される});

独自の非同期メソッドを作成することもできます。

function delay(time) {// Promiseの生成var promise = new Parse.Promise();setTimeout(function() {// Promiseを解決状態にするpromise.resolve();}, time);return promise;}; delay(500).then(function() {// 500ms後に実行される});

このように、Promiseを利用すればコールバックでネストが深くなりがちなソースコードを見通し良く保つことができます。

Parse.GeoPoint

Parse.GeoPointは、位置情報に特化したオブジェクトです。緯度および経度を保存するために使用しますが、Queryの検索条件として指定すれば近接するユーザーや場所を特定することもできます。

// GeoPointの生成var groPoint = new Parse.GeoPoint({latitude: 35.626446, longitude: 139.72344399999997}); // Objectのプロパティとして位置情報を保存するplaceObject.set("location", groPoint);placeObject.save();
// 検索条件に使いたい位置情報//(例:ユーザーの位置情報。userObjectも位置情報をプロパティに持つ場合)var userGeoPoint = userObject.get("location"); // Queryの生成var query = new Parse.Query(PlaceObject); // 検索条件に指定した位置情報に近い位置情報を持っているオブジェクト//(ここではPlaceObject)を検索するquery.near("location", userGeoPoint);query.find();

Related Post

position:fixedを実現するiScrollを使う際に覚えておきたいメソッドたちposition:fixedを実現するiScrollを使う際に覚えておきたいメソッドたち

ヘッダーやフッター等の要素を固定表示するのに利用されるposition:fixed。このposition:fixedがサポートされていない環境で、固定表示を実現する際によく使われるライブラリにiScrollがあります。要素を固定するというよりは、特定要素の範囲をスクロール可能にする、overflow:autoのようなイメージです。 複雑なレイアウトになると、iScrollでスクロールさせている要素の高さが動的に変化したり、スクロール領域が入れ子だったり・・・ユーザ操作に応じて追加の処理を行う必要があります。難しそうなレイアウトは設計の際に回避したいところですが、そういう実装が必要な場合に使えるiScrollのメソッドをまとめてみました。 iScrollの使い方 iScrollの使い方ですが、HTML要素に任意のIDを付け、JSで初期化を行います。下記の例ではid=”scroller”の要素がスクロール可能になります。例でリスト要素になっている部分は何でもかまいませんが、2つのwrapper(例ではIDがwrapperとscrollerのdiv要素)は必要です。また、一番外側の要素には高さを指定しておく必要があります。 ◆HTML <div id=”wrapper”><div id=”scroller”><ul><li></li>……</ul></div></div>

【HTML5】iPhone向けWEBアプリで、Audioを使ってみてハマった点【HTML5】iPhone向けWEBアプリで、Audioを使ってみてハマった点

HTML5のAudio要素を使い、再生する音を遅延無く切り替える方法を、先週8/20(土)に開催された「第5回おばかアプリ選手権」で紹介しましたアプリ、iBooNを例に紹介したいと思います。 iBooNの仕組み iBooNは、Mobile Safari上で動作するWEBアプリです。Mobile Safariから加速度を取得(iOS4.2から加速度センサーに対応)し、前後のシェイクジェスチャ(ぶーんと走らせる動き)、左右の傾き(ドリフト)に応じて異なる車の音を再生させています。 当初は複数のAudioファイルをプリロードさせ、ユーザのアクションに応じて各ファイルを再生させる予定でしたが、Mobile Safariでは複数のAudioファイルをプリロードして保持しておくことが難しく、1音しかプリロードされた状態で鳴らなかったり(参照:iPhoneでHTML5のaudio要素を使うときに気をつけたいこと)、ユーザのアクションごとにAudioデータのロードでタイムラグが発生し、動きによって音が出ているという感じがありませんでした。  ポイント

Gruntで快適な環境を整備したい!【インストール編】Gruntで快適な環境を整備したい!【インストール編】

みなさんはHTML/JS/CSSベースの開発をする際、どんな開発環境で開発していますか?今回は快適な開発環境を目指して、Gruntというタスクの自動化ツールを使ってみます。使用するGruntのバージョンは0.4.1です。 Gruntとは…? Gruntとは、ファイルのコピーや削除、JS/CSSのminifyなどの作業を自動化してくれるビルドツールです。Node.jsベースで動作しており、コマンドラインで使用します。ファイルのコピーや削除は人の手が入るほどミスが発生しがちです。また、JS/CSSのminifyはオンラインで行えるものもありますが、修正の度にすべてのファイルに手動で実行するのは大変手間がかかります。このような単純作業を自動化して、効率化を図ることができるのがGruntです。 Gruntのインストール Gruntの動作には、Node.jsと、Gruntのコマンドラインインターフェースであるgrunt-cliが必要です。まず、この2つをインストールします。  ■Node.jsのインストール Node.jsはインストーラを使ってインストールします。Node.js公式サイトのトップページにINSTALLボタンがあるので、ここからインストーラをダウンロードしてください。画面の指示に従って進めて行けば、インストール完了です。コマンドプロンプトで「node -v」と入力し、バージョンが表示されればインストール成功です。