2014年12月17日

iOS

サーバーサイド実装を1行もせずにバックエンドと連携するiOSアプリを開発する

  • このエントリーをはてなブックマークに追加

Yahoo! JAPAN Tech Advent Calendar 2014の17日目の記事です。一覧はこちら

parse

ヤフーで iOS エンジニアをやってます平松(@himara2)です。

最近 BaaS, MBaaS という言葉を良く耳にします。
アプリエンジニアのみでサーバーサイド込みの開発もできる、ということで以前より個人的に興味がありました。
実際に触ってみると想像以上に使いやすいものだと感じたので、その感想を紹介してみようと思います。

最近のモバイルアプリ開発事情と BaaS

COMPUTING STACK

最近のモバイルアプリはクライアント側で完結するものは少なく、サーバーサイドと連携して動くものがほとんどです。
サーバーサイド側で必要な機能としては、ユーザー管理、各種データAPI、Push通知機能、画像や動画のストレージなどがありますが、これをアプリ開発の度に毎回用意するのは大変です。

そこで、最近注目されているものに BaaS があります。
BaaS とは Backend as a Service の略で、モバイルアプリのサーバーサイド開発を肩代わりしてくれるものです。

アプリの開発に必要な機能がプラットフォームとして提供されており、利用することでサーバーサイド開発分のリソースを削減し、デベロッパーはアプリ側の開発に集中できるようになります。

Parse.com を使った iOS アプリ開発

今回は幾多ある BaaS の中でも、Facebook に買収され注目を集めた Parse.com を使った場合の例を交えつつ、BaaS を使うことでアプリ開発はどう変わるのか? を書いていきます。

データを保存する

さまざまなデータを Parse.com 上に保存できます。
Parse.com の場合、iOS 向けに SDK が提供されていますので、これを使って、

let newMessage = PFObject(className: "Message")
newMessage.setObject("Hello!", forKey: "message")
newMessage.setObject(101, forKey: "toUserId")
newMessage.setObject(207, forKey: "fromUserId")

newMessage.saveInBackgroundWithBlock({ (isSuccess, error) -> Void in
    // 完了後の処理をここに書く
})

のようにアプリ側でコールすれば、

DB

このようにDBに登録されます。

DBはスキーマレスなため、アプリ側で指定した値に応じて String / Number / Array / Boolean などから適切な型が設定されます。(スキーマを制約することも可能)

データを検索する・更新する

クエリを設定し、テーブルからデータを検索したり、

let query = PFQuery(className: "Message")
query.whereKey("toUserId", equalTo: 101)    // where 指定
query.orderByDescending("createdAt")        // sort 指定
query.findObjectsInBackgroundWithBlock { (messages, error) -> Void in
    // 検索にヒットしたオブジェクトに対して何らかの処理
}

データの更新も非常に簡単です。

// 更新内容をセット
message.setObject("Hello Parse!", forKey: "message")
message.setObject(212, forKey: "fromUserId")

// 更新を反映
message.saveInBackgroundWithBlock({ (isSuccess, error) -> Void in
    // 完了後の処理をここに書く
})

このように、クライアントから直接データベースに値を挿入できます。

ユーザーを管理する

ユーザーを管理する

対象ユーザーを指定してpush通知を打ったり、課金アイテムを付与したり、ユーザーの管理も最近のアプリでは必須となりつつあります。

Parse では以下のようにユーザーを扱えます。

ユーザー登録の処理

let newUser = PFUser()
newUser.username = "himara2"
newUser.password = "my_password"
newUser.email = "email@example.com"
newUser["sex"] = "male"         // アプリ独自の情報をユーザーに持たせる

newUser.signUpInBackgroundWithBlock { (isSuccess, error) -> Void in
    // ... サインアップ後の処理
}

ユーザーログインの処理

PFUser.logInWithUsernameInBackground("himara2",
    password: "my_password")
    { (isSuccess, error) -> Void in
    // ... ログイン処理後の処理
}

ログインしているユーザーかどうかチェック

if PFUser.currentUser() == nil {
    // ... 未ログインのユーザーの処理
}
else {
    // ... ログイン済のユーザーの処理
}

上記は Email & Password でユーザー管理をする例ですが、Twitter や Facebook など SNS 連携するもの、そしてユーザー入力なしでバックグラウンドでユーザー登録をするものなど、さまざまなパターンが用意されています。

Push通知を送る

Push通知を送る(画像引用元: Parse Blog

Push通知の送信もクライアント側から簡単に行えます。

// pushを打つ相手を指定するクエリ
let pushQuery = PFInstallation.query()
pushQuery.whereKey("user", equalTo: user)

// payload の中身を設定
let data = ["alert":"メッセージが届きました",
    "badge":1,
    "sound":"default",
    "type":"reaction"]

// push通知を生成    
let push = PFPush()
push.setQuery(pushQuery)
push.setData(data)

// push通知を送信
push.sendPushInBackgroundWithBlock { (isSuccess, error) -> Void in
    // 送信完了後の処理
}

Sound や Badge に加えて、Custom Payload も自由に持たせることができます。
インターフェースが分かりやすくて使いやすいですね!

Cloud Codeでサーバーサイドを拡張

Cloud Code(画像引用元: Parse Cloud Code Guide

基本的な機能が最初から用意されて便利な Parse.com ですが、開発を進めてくると自分でサーバーサイドをカスタムしたくなってきます。
例えば、あるレコードが insert された時にカウントアップをしたり、ランキングを作成するバッチ処理を走らせたりする場合です。

このような場合は、Cloud Code でサーバーサイドを拡張できます。

Cloud Code は JavaScript 言語で記述します。例えば以下はレコード追加時に検証するコードです。

// Message が登録される前にvalidationをチェックする例
var Message = Parse.Object.extend("Message")

Parse.Cloud.beforeSave("Message", function(request, response) {
    if (!request.object.get("message")) { 
        reponse.error("A Message must have message field")
    }
    else {
        response.success();    
    }
}

ブラウザーでの閲覧・操作

ブラウザーでの閲覧・操作(画像引用元: Parse Blog

Parse.com ではブラウザー上からデータや各種機能にアクセスできます。

登録されているデータ一覧が確認できたり、

登録されているデータ一覧

ブラウザー上から直接値を変更できたり、

ブラウザー上から直接値を変更

全体向け / Segment 向けの Push 通知を送信できたりと、

Push通知の送信

ブラウザーから自由に操作できます。

これにより開発・デバッグの効率が向上するほか、エンジニアがやらなくて良い作業(全体Pushの送信など)を全員で分担することができます。

以上、Parse.com の特徴の紹介でした。

使ってみた感想

開発コストの削減

本記事冒頭で「BaaS 導入によりサーバーサイド開発分のリソースを節約できる」と書きましたが、それに加えてアプリとサーバーの連携コストを削減できるのが大きいと感じました。

例えばDBのスキームに変更があった時、従来だとサーバー側でスキーム変更、APIを変更し、その上でアプリ側でAPI変更に対応、確認する、というようなフローですが、BaaS を利用する場合はアプリ側のスキーム対応だけとなります。
エラーが発生した場合も実装の箇所が少ないため原因の特定が容易です。

「あれ、まだ修正されてない?」「あ、デプロイできてなかった」のようなやりとりで時間をロスすることもないため、テンポよく開発を進められました。

アプリUXへのフォーカス

アプリのUIやUXは最近特に重要視されており、ユーザーが求めるレベルも非常に高くなってきています。
さらにアプリの世界はトレンドの移り変わりも激しいため、長い時間をかけて1つのアプリを開発することは難しくなっている現状があります。
BaaS にサーバーサイドの基本機能を肩代わりしてもらうことで、デベロッパーは限られた時間を「アプリが提供する価値」や「ユーザー体験」を考えることに使え、アプリの質を最大限高められます。

まとめ

スケールした際のことを考えると最初から自社で構築すべきだだという意見もありますが、何が当たるかが非常に見えにくいアプリ戦場では、BaaS を利用してスピード感をもって開発し、提案する数を増やしていくのは良いアプローチだと感じています。

こういったサービスは、依存すると後々離れにくくなるという懸念があるかと思います。しかし Parse.com で Cloud Code を用意しているように、最近では拡張性もかなり上がっていますので、以前ほど意識しなくても良いのではないかと思います。

今回は使ってみた編として Parse.com の基本的な使い方を紹介しましたが、運用の話やセキュリティの話、他 BaaS との比較なども今後書いていければと思います。

それではみなさん、楽しい BaaS ライフを!

参考

-------
IOSの商標は、Ciscoの米国およびその他の国のライセンスに基づき使用されています。

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加