LoginSignup
5
6

More than 5 years have passed since last update.

parse.comからNIFTY Cloud mobile backendへ移行した話(Part1)

Posted at

個人で開発しているアプリ、keyaki2のバックエンドをparse.comからNIFTY Cloudへ移行した話です。
keyaki2は欅坂46のブログリーダーです。メンバーごとに新着ブログの通知をプッシュで送ってくれます。

ついでにCocoaPodsの導入、Gitの導入と、開発と本番で叩くAPIを変えるように実装したいと思っています。
クソプロジェクトを保守しやすいマシなものにしよう(メインはmBaaSの切り替え)
っていう大きなテーマを掲げていきたいと思います。

以降、NIFTY Cloud Mobile BackendをNCMBと称します。

現在の状態

【Parse版 keyaki2】
 CocoaPods未導入。手作業の温かみでライブラリを追加していました。

具体的な移行手順

いきなりParse版からNCMB版に切り替えてしまうと、いろいろ大変なことが起きそうなので
移行期間を作ってゆっくり移行していきたいと思います。

1. Parse版にNCMBのSDKをインストール

こちらも手作業の温かみが良さそうなのでGitHubからSDKを落としてきて入れようとしたのですが、
なぜかうまく行かなかったので、結局CocoaPodsをこちらにも導入することにしました。

ターミナル上で.xcodeprojがあるディレクトリに移動して
$ pod init
生成されたPodfileに

Podfile
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

target 'keyaki2' do
  # Comment this line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for keyaki2
  pod 'NCMB', :git => 'https://github.com/NIFTYCloud-mbaas/ncmb_ios.git'
end

pod NCMB...を追記して保存します。
$ pod install を実行してCocoaPodsのプロジェクトを作成します。

生成された.xcworkspaceをXcodeで開いてビルドが通ればとりあえずOKです。

2. DeviceTokenの設定を行う

必要とする場所に #import <NCMB/NCMB.h> を記述してください。
僕の場合はPrefixHeader.hにライブラリ関係を入れているので、そこに記述しました。(楽ちん

まずはDeviceTokenをParseにも、NCMBにも登録するためにAppDelegate.mにいろいろ書いていきます。
アプリのキーや設定関係をコードに直接書くのがイヤなので、僕はConst.hというファイルに定数を置いてます。
Parseの設定ができているのであれば、一行追加するだけでOKです。

AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Parseの初期化
    [Parse setApplicationId:K2ParseAppId clientKey:K2ParseClientKey];

    //NCMBの設定を行う
    [NCMB setApplicationKey:K2NiftyAppId clientKey:K2NiftyClientKey];

    //通知の設定(デバイストークンの取得などを行う)
    UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
                                                    UIUserNotificationTypeBadge |
                                                    UIUserNotificationTypeSound);
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
                                                                             categories:nil];
    [application registerUserNotificationSettings:settings];
    [application registerForRemoteNotifications];

    //略
}
Const.h
//Parse関連
static NSString *const K2ParseAppId = @"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
static NSString *const K2ParseClientKey = @"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
//Parse関連
static NSString *const K2NiftyAppId = @"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
static NSString *const K2NiftyClientKey = @"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";

次に、DeviceTokenが返ってきた時にNiftyにも送るようにコードを書いていきます。
同じくAppDelegate.mに記述していきます。基本的には追記していくだけです。

AppDelegate.m
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //Parse版で元々記述されていた処理
    PFInstallation *currentInstallation = [PFInstallation currentInstallation];
    [currentInstallation setDeviceTokenFromData:deviceToken];
    [currentInstallation saveInBackground];

    //以下を追記
    //端末情報を扱うNCMBInstallationのインスタンスを作成
    NCMBInstallation *installation = [NCMBInstallation currentInstallation];

    //Device Tokenを設定
    [installation setDeviceTokenFromData:deviceToken];

    //端末情報をデータストアに登録
    [installation saveInBackgroundWithBlock:^(NSError *error) {
        if(!error){
            //端末情報の登録が成功した場合の処理
        } else {
            //端末情報の登録が失敗した場合の処理
            if (error.code == 409001){
                //失敗した原因がdeviceTokenの重複だった場合
                [self updateExistInstallation:installation];
            } else if (error.code == 404001) {
                //deviceTokenの重複以外のエラーが返ってきた場合
                [self reRegistInstallation:installation];
            }
        }
    }];
}

//deviceTokenの重複で端末情報の登録に失敗した場合に上書き処理を行う
- (void)updateExistInstallation:(NCMBInstallation*)currentInstallation{
    NCMBQuery *installationQuery = [NCMBInstallation query];
    [installationQuery whereKey:@"deviceToken" equalTo:currentInstallation.deviceToken];

    NSError *searchErr = nil;
    NCMBInstallation *searchDevice = [installationQuery getFirstObject:&searchErr];

    if (!searchErr){
        //上書き保存する
        currentInstallation.objectId = searchDevice.objectId;
        [currentInstallation saveInBackgroundWithBlock:^(NSError *error) {
            if (!error){
                //端末情報更新に成功したときの処理
            } else {
                //端末情報更新に失敗したときの処理
            }
        }];
    } else {
        //端末情報の検索に失敗した場合の処理
    }
}

- (void) reRegistInstallation:(NCMBInstallation *) installation {
    installation.objectId = nil;
    [installation saveInBackgroundWithBlock:^(NSError *error){
        if (!error) {
            NSLog(@"NCMB installation : successfully re-regist.");
        } else {
            NSLog(@"NCMB installation : failed to re-regist. %@",error);
        }
    }];
}

これでDeviceTokenがParseとNiftyの両方に向くようになりました。
基本的な移行版の作成はこれだけでいいのですが、keyaki2ではメンバーごとにブログの通知を送るため、
ユーザはそれぞれチャンネルに登録を行っています。今回はその設定もNiftyに移行したいため、
こちらのコードも書いていきます。

3.Channelsの設定をNiftyへ移行する

通知チャンネルの移行は、「Parseで登録しているチャンネルリストをNiftyにも送る」という方法で
いきたいと思います。
以下に移行するためのメソッドを示します。僕はどこからでも呼べるようにUtilsクラス内に入れました。

Utils.h
+(void)syncNotificationSettings;
Utils.m
+(void)syncNotificationSettings{
    NSArray *subscribedChannels = [PFInstallation currentInstallation].channels;
    NCMBInstallation *installation = [NCMBInstallation currentInstallation];
    [installation setObject:subscribedChannels forKey:@"channels"];
    //端末情報をデータストアに保存
    [installation saveInBackgroundWithBlock:^(NSError *error) {
        NSLog(@"installationIdInBlock:%@", installation.objectId);
        if(!error){
            //端末情報の登録が成功した場合の処理
            NSLog(@"Sync successful!");
        } else {
            //端末情報の登録が失敗した場合の処理
            NSLog(@"Sync failed...");
        }
    }];
}

とりあえずこれ呼んでおけば同期できるっぽいのでいいのかな…と思ってたりします。
パフォーマンス的にどうかとは思いますが(未検証)、とりあえずAppDelegate内でそういう処理を書いちゃえば
とりあえず移行はできるだろうということで…。
再びAppDelegate.mに戻って

AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //どこか適当な位置に(return直前とかいいかもしれない)
    [Utils syncNotificationSettings];

    return;
}

って置いておけばコールドスタート時にはとりあえず設定は同期できるはずです。
あとはユーザがchannelの設定を変更した時にもこのメソッドを呼べば完璧ですね。

一旦この状態でアプリをビルド、リリースしてユーザには移行期間版を使ってもらうことにします。

次回は新アプリをCocoaPodsで作成して、コードを移行したり整理したりしたいと思います。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6