国産MBaaSのKiiCloudをXamarin.Formsから使用する


この記事は、[Xamarin Advent Calendar 2015](http://qiita.com/advent-calendar/2015/xamarin) の18日目の記事です
ここではXamarin.Formsとkii Cloud SDKを組み合わせて、
モバイルバックエンドサービス(MBaaS)を利用したクロスプラットフォーム開発をご紹介します。
 
# Kii Cloudとは
[公式HP](http://jp.kii.com/index.html)
kii株式会社が提供する国産のBaaSです。
モバイルアプリ開発に欠かせないことの多いサーバー機能をサービスとして提供しています。

# Kii Cloudが提供するMBaaS機能
いわゆるMBaaSとしての機能は一通り備えています。
加えて、IoTデバイス向けにもSDKを提供していたり、分析、A/Bテストといったシーンでも活用することができます！[くわしくはこちら](http://jp.kii.com/service_price/)
- ユーザ管理
- データ管理
- プッシュ通知
- 位置情報
- サーバー拡張機能
- アプリ分析
- A/Bテスト
- モノ管理
- Kii Game Cloud

# 対応しているプラットフォーム
- Android
- iOS
- HTML5(JavaScript)
- Unity

上記はSDKが提供されているプラットフォームです。
これ以外にもREST APIが用意されていますので頑張ればなんでもできます。
あ・・・気付きました？
Xamarin、対応してないですよね。
安心してください。使えます！詳細は後ほど。
国産なので日本語の[リファレンス](http://documentation.kii.com/ja/guides/)が非常に充実しています！


# 料金
- Kii Cloud 利用登録：無料
- ストレージ：1GBまで無料
- APIリクエスト：月間100万APIコールまで無料
- プッシュ通知：月間100万プッシュ通知まで無料

・・・成功するまでは無料ですね！
もちろん大規模向けのプランもあります。

# 使い方
それでは実際にKii Cloudで開発者登録をして、
Xamarin.Forms上でユーザ登録、データの保存までを行ってみましょう。

## 1. Kii Cloudへの登録
[こちら](https://developer.kii.com/jp/signup)から開発者登録ができます。
名前、メールアドレス、パスワードが必要です。
登録が完了すると、下記画面が表示されます。
![DevRegister.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/5da18750-23dc-421f-23cc-1e904d85eb88.png)

今回は「Create App」を選択しましょう。


## 2. kiiCloud アプリの作成
「Create App」を選択すると、アプリ作成画面が表示されます。
![AppCreate.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/13d8a35e-f2de-a8f9-e833-2230cb5d4ff8.png)

①アプリ名を入力します。
　ここで入力するアプリ名はKii側での管理に使用するものです。
　アプリのバンドル等とは関係のないもので構いません。
　今回は「Xamarin.Forms.KiiTutorial」とします。
 ②サーバーのロケーションを選択します。
　今回は「Japan」とします。
③プラットフォームを選択します。
　今回は「Android, iOS」を選択します。

では「Create Your App」を選択して、アプリを作成しましょう。


## 3. Kii Cloud SDKのダウンロード
「Create Your App」を選択すると、SDKのダウンロード画面が表示されます。
![SDKDownload.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/7b60c1aa-6ef4-8540-0dd5-6f251b7d3156.png)

Xamarin向けのSDKは提供されていませんが、代わりにUnity向けSDKをダウンロードします。
unity-cloud-sdk-3.1.1.unitypackage(2015.12.17現在)がダウンロードできます。
このunitypackageのなかに含まれる下記DLLを引っこ抜きます！
 - KiiCloudStorageSDK.dll
 - JsonOrg.dll


UnitypackageをUnity経由で解凍して上記DLLだけ取り出すのが手間だったので、
SDK単体で配信してもらえないか中の人に聞いてみました。
http://community-jp.kii.com/t/kiicloudstoragesdk-dll/441
結果はダメとのことでしたが、質問から回答まで12時間という即レスをいただきました。
合わせて、オープンソースでこんなのあるよとご紹介を頂きました。感謝。
[Unityを介さずUnityPackageを解凍するツール](https://github.com/gered/extractunitypackage)
使い方は[こちら](http://baba-s.hatenablog.com/entry/2015/06/29/102022)をご参照ください。
[開発者community](http://community-jp.kii.com/)は中の人も丁寧迅速にサポートしていますので、困ったらぜひ活用してみてください。

さて、ダウンロードが完了したら、Finishを選択しましょう。
そうすると、アプリ一覧画面が開きます。
![AppMaster.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/3456c46b-d48d-e583-f236-602d6660bc4d.png)

今後ログインすると、この画面が表示されます。
アプリを選択し、詳細画面を開いてみましょう。
![AppDetail.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/12ce6683-d21d-e6d3-1b91-f6b391de639b.png)
現在のユーザ数やObject数などが表示されています。
作ったばかりなのでまだ0ですね。

では、Xamarin側に入っていきましょう！

## 4. プロジェクトの作成
Xamarin.Forms PCLで作っていきます。
Xamarin Advent Calenderも18日目なので、詳細は割愛します。
Blank App(Xamarin.Forms Portable)で新規プロジェクト作成します。
今回は「XamarinKiiTutorial」としました。

プロジェクトテンプレートが開いたら、PCL側に
UnityPackageから取得した下記DLLを参照追加します。
![SDKImport.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/e572d01a-899e-98d9-8d47-cfc4768d1c28.png)

続いて、SDKのInitializeを行い、SDKを使用する準備を行います。
下記ファイルを作成し、アプリ起動時に呼び出す[Initializeメソッド](http://docs.kii.com/references/dotnet/storage/latest/KiiCorp.Cloud.Storage/Kii.html#M:KiiCorp.Cloud.Storage.Kii.Initialize(System.String,System.String,KiiCorp.Cloud.Storage.Kii.Site))を定義します。

```csharp:KiiService.cs
using System;
using System.IO;
using System.Threading.Tasks;
using KiiCorp.Cloud.Storage;

namespace XamarinKiiTutorial
{
    public static class KiiService
    {
        private const string APPID = "********";
        private const string APPKEY = "********";
        private const Kii.Site SITE = Kii.Site.JP;
        
        public static bool kiiInitialize()
        {
            try
            {
                Kii.Initialize(KiiServiceObject.APPID, KiiServiceObject.APPKEY, KiiServiceObject.SITE);
                return true;
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
```
先ほど作成したアプリのAPPIDとAPPKEYを埋め込みます。
※APPIDとAPPKEYの取得方法は[こちら](http://documentation.kii.com/ja/guides/unity/quickstart/)。
このメソッドをアプリ起動時に一度呼び出せばOKです。
これでPCL側からSDKを使用する準備ができました。

## 5. ユーザ登録／ログイン
[Kii Cloud Storage SDK](http://docs.kii.com/references/dotnet/storage/latest/KiiCorp.Cloud.Storage/index.html)はUnity向けに構成されており、コールバックを渡すタイプのAPIになっています。

```csharp:
//User登録
public void Register (string password, KiiUserCallback callback)
//KiiUserCallback
public delegate void KiiUserCallback (KiiUser user, Exception e)
```
これだとasync/await演算子が使えず可読性が下がるので、Taskを返すタイプのAPIとしてラップします。
先ほど作成したKiiService.csクラスに、ユーザ登録、ログイン用のメソッドを追加していきます。

```csharp:KiiService.cs        
        public static Task<KiiUserResponse> KiiUserRegisterAsync(string username, string password)
        {
            KiiUser.Builder builder;
            builder = KiiUser.BuilderWithName(username);
            KiiUser user = builder.Build();

            var tcs = new TaskCompletionSource<KiiUserResponse>();
            user.Register(password, (KiiUser registeredUser, Exception e) => { tcs.TrySetResult(new KiiUserResponse(user, e)); });
            return tcs.Task;
        }

        public static Task<KiiUserResponse> KiiUserLoginAsync(string username, string password)
        {
            var tcs = new TaskCompletionSource<KiiUserResponse>();
            KiiUser.LogIn(username, password, (KiiUser user, Exception e) =>{tcs.TrySetResult(new KiiUserResponse(user,e));});
            return tcs.Task;
        }
```

レスポンスクラスを定義します。

```csharp:KiiUserResponce.cs
using System;
using KiiCorp.Cloud.Storage;

namespace XamarinKiiTutorial
{
    public class KiiUserResponse
    {
        public KiiUser user { get; set; }
        public Exception e { get; set; }

        public KiiUserResponse(KiiUser User , Exception e)
        {
            this.user = User;
            this.e= e;
        }
    }
}

```

呼び出し側は以下のように使用します。

```csharp:Login.xaml.cs
        private async void _Regist_Clicked(object sender, EventArgs e)
        {
            var res = await KiiService.KiiUserRegisterAsync(_UserName.Text, _Password.Text);
            if (res.e != null)
            {
                await this.DisplayAlert("Registration failed", res.e.ToString(), "OK");
                return;
            }
            App.LoginUser = res.user;
            await this.Navigation.PushAsync(new CreateObject());
        }

        private async void _Login_Clicked(object sender, EventArgs e)
        {
            var res = await KiiService.KiiUserLoginAsync(_UserName.Text, _Password.Text);
            if (res.e != null)
            {
                await this.DisplayAlert( "SignIn failed", res.e.ToString(),"OK");
                return;
            }
            App.LoginUser = res.user;
            await this.Navigation.PushAsync(new CreateObject());
        }
```

呼び出し側はawait演算子を用いて、同期っぽい書き方で非同期処理を記述することができます！


## 6. データの保存
KiiCloudでは、データスコープがいくつか存在します。
- Application Scope : アプリ全体で共有するデータ
- Group Scope : 特定のグループで共有するデータ
- User Scope : ユーザ単位のデータ
- Thing Scope : IoT単位のデータ

kiiCloudのデータ管理には、Bucket、Objectという概念があり、ObjectにはJSONもしくはファイルを格納できます。詳細は[リファレンスガイド](http://documentation.kii.com/ja/starts/cloudsdk/managing-data/)に任せて、今回はApplication Scopeにデータを書き込んでみます。

まずこれまでと同様にKiiService.csに[データ作成メソッド](http://docs.kii.com/references/dotnet/storage/latest/KiiCorp.Cloud.Storage/KiiObject.html#M:KiiCorp.Cloud.Storage.KiiObject.Save(KiiCorp.Cloud.Storage.KiiObjectCallback))を追加しましょう。

```csharp:KiiService.cs
        public static Task<KiiObjectResponse> KiiObjectCreateAsync(KiiObject obj)
        {
            var tcs = new TaskCompletionSource<KiiObjectResponse>();
            obj.Save((KiiObject savedObj, Exception e) => { tcs.TrySetResult(new KiiObjectResponse(savedObj, e)); });
            return tcs.Task;
        }
```

呼び出し側は以下のように使用します。
下記はApplication Scopeに"XamarinKiiTutorial" Bucketを作成し、その中にObjectを作成しています。
Objectの中に下記JSONを設定しています。

```json
{ "username" : "{前画面で入力したユーザ名}" }
```

```csharp:CreateObject.xaml.cs
        private async void _CreateObject_Clicked(object sender, EventArgs e)
        {
            KiiObject obj = Kii.Bucket("XamarinKiiTutorial").NewKiiObject();
            obj["username"] = App.LoginUser.Username;

            var res = await KiiService.KiiObjectCreateAsync(obj);
            if (res.e != null)
            {
                await this.DisplayAlert("KiiObject creation failed", res.e.ToString(), "OK");
                return;
            }
        }
```

それでは、実際に動かしてみましょう！
## 7. 動作確認
シンプルにユーザ登録・ログイン画面とObject作成画面だけ用意しました。

まずユーザ登録・ログイン画面です。
![SignUp.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/ab0ffae3-b9c1-b6cc-768b-a2be0d246f58.png)
ユーザとパスワードを入力してサインアップします。
![SignUpSucceed.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/ed87a352-18c6-357a-6763-d594608cc255.png)
ユーザ登録成功が返却されました。kiiの管理画面を見てみましょう。
![kiiUserCreated.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/ea6c98c6-b2d2-95db-2616-c11f00e43887.png)

ユーザ数が 1 になっていますね！

続いて、Objectを作成してみましょう。
![object_create.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/ab4a3514-4023-5f90-3148-d3c5df000671.png)
Object作成ボタンをタップします。
![ObjectCreateSucceed.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/98aee999-c80a-0918-4f3d-db2728e3cbf2.png)
Object作成成功が返却されました。kiiの管理画面を見てみましょう。
![kiiObjectCreated.PNG](https://qiita-image-store.s3.amazonaws.com/0/75755/086837e4-a4fa-95b8-3562-228f4334e77d.png)

Application Scopeの"XamarinKiiTutorial" Bucketに Objectが生成され、指定したKey-Valueが格納されています。
今回ObjectのIDを指定していないので、UUIDが発行されていますが、明示的にObjectIDを指定して作成することもできます。


# まとめ
今回、Xamarin.FormsからKii Cloud SDKを使用する方法をご紹介しました。
[Xamarin.iOS,Xamarin.AndroidからKii Cloudを使用するTODOアプリ](https://en.kii.com/blog/build-a-cross-platform-app-with-kii-and-xamarin-in-minutes/)もあります。

Unity用のSDKですが、少しラップをしてあげるとXamarinでも使いやすくなります！
本当はPush通知とかもやりたかったのですが、また別の機会に。
今回のサンプルは[こちら](https://github.com/Masaaki-Yoshida/XamarinKiiTutorial)においています。
興味がわいた方はぜひ触ってみてください。