Posted at

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

More than 3 years have passed since last update.

個人で開発しているアプリ、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で作成して、コードを移行したり整理したりしたいと思います。