【NCMB】 ニフティクラウド mobile backend の会員登録/ログインをIObservable化してUniRxで扱えるようにする

**UniRxについての記事のまとめは[こちら](http://qiita.com/toRisouP/items/48b9fa25df64d3c6a392)**

---

niftyのmBaaSであるニフティクラウド mobile backend（NCMB)のログイン周りの処理をObservableに変換し、UniRxで扱えるようにしてみました。

#IObservable化したコード

static classとして定義してあります。利用時にusingして下さい。
あと、ついでに使いやすいように会員登録時に別フィールドも更新できる機能を追加しました。

```csharp:ログイン処理をIObservableに変換する
using System.Collections.Generic;
using NCMB;
using UniRx;

namespace ObservableNcmb
{
    public static class ObservableNcmbUserAuth
    {
        /// <summary>
        /// IDとパスワードによるログインを実行する
        /// </summary>
        public static IObservable<NCMBUser> LoginAsync(string id, string password)
        {
            return Observable.Create<NCMBUser>(observer =>
            {
                NCMBUser.LogInAsync(id, password, e =>
                {
                    if (e == null)
                    {
                        observer.OnNext(NCMBUser.CurrentUser);
                        observer.OnCompleted();
                    }
                    else
                    {
                        observer.OnError(e);
                    }
                });
                return Disposable.Create(() => {; });
            });
        }

        /// <summary>
        /// IDとパスワードによる会員登録を実行する
        /// </summary>
        /// <param name="id">ID</param>
        /// <param name="password">パスワード</param>
        /// <param name="optionalData">その他フィールド</param>
        /// <returns></returns>
        public static IObservable<NCMBUser> SingUpAsync(
            string id,
            string password,
            Dictionary<string, object> optionalData = null)
        {
            return SingUpAsync(id: id, password: password, optionalData: optionalData, mail: null);
        }


        /// <summary>
        /// IDおよびメールアドレスとパスワードによる会員登録を実行する
        /// </summary>
        /// <param name="mail">メールアドレス</param>
        /// <param name="id">ID</param>
        /// <param name="password">パスワード</param>
        /// <param name="optionalData">その他フィールド</param>
        /// <returns></returns>
        public static IObservable<NCMBUser> SingUpAsync(
            string mail,
            string id,
            string password,
            Dictionary<string, object> optionalData = null)
        {
            return Observable.Create<NCMBUser>(observer =>
            {
                var user = new NCMBUser
                {
                    Email = mail,
                    UserName = id,
                    Password = password
                };

                if (optionalData != null)
                {
                    foreach (var opt in optionalData)
                    {
                        user[opt.Key] = opt.Value;
                    }
                }

                user.SignUpAsync(e =>
                {
                    if (e == null)
                    {
                        observer.OnNext(user);
                        observer.OnCompleted();
                    }
                    else
                    {
                        observer.OnError(e);
                    }
                });
                return Disposable.Create(() => {; });
            });
        }

        /// <summary>
        /// ログアウトを行う
        /// </summary>
        public static IObservable<Unit> LogoutAsync()
        {
            return Observable.Create<Unit>(observer =>
            {
                NCMBUser.LogOutAsync(e =>
                {
                    if (e == null)
                    {
                        observer.OnNext(Unit.Default);
                        observer.OnCompleted();
                    }
                    else
                    {
                        observer.OnError(e);
                    }
                });
                return Disposable.Create(() => {; });
            });
        }
    }
}

```


#使用例

実際に今開発してるプロダクトからコードを抜粋してみました。
ユーザ登録時にプレイヤ名（ScreenName）も一緒に登録するというコードです。

```csharp:ユーザの新規登録

/// <summary>
/// ユーザの新規登録を行う
/// </summary>
public void SignUp(string id, string mail, string pass, string screenName)
{
    //プレイヤの表示名を登録時に設定する
    //会員テーブルに予めフィールドを増やしておく必要がある
    var optionalData = new Dictionary<string, object>()
    {
        {"screenName",screenName }
    };

    //ユーザの新規登録
    ObservableNcmbUserAuth
        .SingUpAsync(mail, id, pass, optionalData)
        .Subscribe(user =>
        {
            //NCMBUserインスタンスを保存
            UserProfileProvider.SetUser(user);
            //ログイン成功通知
            onSuccessLoginSubject.OnNext(Unit.Default);
        },
        //エラー時はエラーメッセージにを通知
        ex => failedReasonSubject.OnNext(ConvertExceptionToText((NCMBException)ex)));

}

```

実行するとこのように基本情報に合わせてscreenNameフィールドも設定されます
![s.png](https://qiita-image-store.s3.amazonaws.com/0/47146/cfef2500-40fd-9a88-d249-6a1a83ef5983.png)


非同期処理やコールバック関数を実行するものはIObservableに変換してしまい、全てUniRxの世界で扱えるようにしておくととても捗るのでおすすめです。