gracetory’s blog

東池袋にある合同会社グレストリのエンジニアブログです

Cocos2d-xで「NIFTY Cloud mobile backend」導入してみた(iOS編)

f:id:gmatsu:20170807124957j:plain

こんにちは。

プログラマのgmatsuです。

この間発売されたドラゴンクエスト11を現在プレイしています。

PS4版でプレイしているのですが、いつになってもドラクエは楽しいですね。

はやく最強装備を手に入れて、スライムに会心の一撃を放ちたいと思っている昨今です。

それはさて置き、先日弊社からこんなアプリをリリースしました(先日と言いつつ3ヶ月程前ですが…)。

にわとりブリード!!を App Store で

にわとりブリード!! かわいいドット絵のにわとり放置ゲーム! - Google Play の Android アプリ

にわとりが産むタマゴでお金を稼ぎ、牧場の設備を整えていくいわゆる放置ゲーになっていて、Cocos2d-xにて作成しています。

キャラクターのにわとりが非常に可愛いだけでなく、ゲーム性も楽しく遊びやすい物になってますので、お時間のある時に是非プレイしてみてください。

いや、是非プレイしてください。

本アプリではユーザの進捗情報等をDBに保存しているのですが、今回はこのような物を使用してみました。

mb.cloud.nifty.com

Nifty社が運営している、いわゆるmBaaSです。 最近のmBaaSはファイルのダウンロード、プッシュ通知、ユーザ会員登録、SNS連携等様々な機能を使用する事ができる様になっており、NIFTY Cloud mobile backend(NCMB)であれば上記した機能が全て使えるのでとても便利です。

しかし残念な事にCocos2d-x用のSDKがありません(Unityには対応しているのに…)。

SDKが無いって事は、iOS、AndroidでNCMBを利用する処理を書き、更にその処理をCocos側から呼び出してあげないといけません。

そこで本記事では、実装からデータ登録までの流れをまとめてみました。

ちなみに公式の導入方法のページは下記となります。

ドキュメント : 開発者向けドキュメント | ニフティクラウド mobile backend

導入目的

iOS、Androidアプリ「にわとりブリード」への通信処理の実装

※ユーザのデバイス情報、登場するニワトリやタマゴの収集情報の保存の為

cocos2d-xバージョン

v3.15.1

NCMBバージョン

iOS

v2.3.6

導入手順にあたっての前提

Cocos2d-x用のプロジェクトが生成済み

NCMBアカウントが作成済みでありアプリのダッシュボード(管理画面)に入る事が出来る

導入手順

iOS

1. SDKの設置

公式の導入方法では「AppDelegateクラスと同じ階層にコピー」と記載していますが、iOS、Androidのファイルが色々散らばって管理しづらいので、自分は以下のように

Classes/External/Ncmb/iOS

を作成し、そこにSDKをコピーしています。

f:id:gracetory:20170714181800p:plain

※SDKはダウンロードしてきた「ncmb_ios-2.3.6.zip」のNCMBディレクトリになります。

2. XcodeにSDKを追加

「1.」でSDKをコピーしたプロジェクト諸々をProjectNavigatorに突っ込んでしまいます。

コピー時はこんな感じ。

f:id:gracetory:20170714181822p:plain

コピー後のツリーはこんな感じになります。

Android用のディレクトリも入っていますが、最終的に無くても問題ありません。

というかSS撮る時に一緒に入れちゃっただけです。

f:id:gracetory:20170714181835p:plain

3. 依存フレームワークの設定
  • AudioToolbox.framework
  • SystemConfiguration.framework
  • MobileCoreServices.framework
  • CoreLocation.framework

この4つが必要になりますので、XcodeのBuildPhasesのLinkBinaryWithLibrariesで追加しましょう。

自分の環境では既に追加されていた物がありましたので、不足している物を追加しましょう。

ここまでの段階で一度ビルドしてみましょう。

問題が無いようであれば無事ビルドが完了する筈です。

4. SDKの読み込み

次はSDKの読み込みです。

これが終わったらNCMBにデータを挿入する事が出来るようになるので、ちゃちゃっとやってしまいましょう。

NCMBを読み込ませておくヘッダファイル、実際の処理を記述していく.mmファイルを今回は以下のように準備しました。

f:id:gmatsu:20170804115547p:plain

iOS版の処理は.mm、Android版の処理は.cpp(※1)に記述する事になりますが、この2つのソースで同じヘッダファイルを使用する事になりますので、上記の様な配置にしておくと管理がしやすかったです。

※1. 正確には.cppにjavaの処理を呼び出すコードを書きます

それでは各ファイルに記述する内容になります。

NcmbManager.h

#ifndef __NCMB_MANAGER_H__
#define __NCMB_MANAGER_H__

#include "cocos2d.h"

/**
 * @brief NiftyMobileBackend接続
 */
namespace NcmbConnect {
    class NcmbManager :public cocos2d::Ref {
    public:

        /**
         * @brief コンストラクタ
         */
        NcmbManager();

        /**
         * @brief デストラクタ
         */
        virtual ~NcmbManager();
    };
}

#endif /* __NCMB_MANAGER_H__ */

NcmbManager.mm

#include "NcmbManager.h"

#import "NCMB/NCMB.h"

USING_NS_CC;

namespace NcmbConnect {
    /**
     * @brief コンストラクタ
     */
    NcmbManager::NcmbManager() {
    }
    
    /**
     * @brief デストラクタ
     */
    NcmbManager::~NcmbManager() {
    }
}

.hの方にはcocos2d.hの読み込み、.mmではNCMB.hの読み込みを行っています。

NCMBを利用する為には必ずNCMB.hが必要になりますので、必ず読み込んでおきましょう。

5. アプリケーションキーとクライアントキーの設定、SDKの初期化

NCMBを使用する為には、NCMBのダッシュボードに表示されているアプリケーションキーとクライアントキーを使用した初期化を行う必要があります。

まずは各キーをダッシュボードから取得しましょう。

画面右上に「アプリ設定」というリンクがありますので、そちらをクリックすると下記のような画面が出ます。

f:id:gmatsu:20170804124155p:plain

下部の赤く塗りつぶしている所がアプリケーションキー、クライアントキーが表示されている場所になります。

ここを範囲指定しても良いのですが「コピー」ボタンを押したほうが確実にコピー出来ると思います。

このキーを使用したSDKの初期化は以下の通りです。

NcmbManager.hに追加

namespace NcmbConnect {
    class NcmbManager :public cocos2d::Ref {
    public:
        /*
            コンストラクタ、デストラクタ
        */

        /**
         * @brief SDK初期化
         */
        static void init(const char* app_key, const char* client_key);
    };
}

NcmbManager.mmに追加

namespace NcmbConnect {
    /*
        コンストラクタ、デストラクタ
     */

    /**
     * @brief SDK初期化
     */
    void NcmbManager::init(const char* app_key, const char* client_key) {
        // 引数の文字列変換
        NSString* app_key_str = [NSString stringWithCString:app_key encoding:NSUTF8StringEncoding];
        NSString* client_key_str = [NSString stringWithCString:client_key encoding:NSUTF8StringEncoding];

        // SDK初期化
        [NCMB setApplicationKey:app_key_str clientKey:client_key_str];
    }
}

[NCMB setApplicationKey:app_key_str clientKey:client_key_str];で初期化が行えます。

後はこのinit関数を呼び出せば初期化が終了です。

AppDelegate.cpp

#include "External/Ncmb/NcmbManager.h"

bool AppDelegate::applicationDidFinishLaunching() {
    // NCMB初期化
    NcmbConnect::NcmbManager::init("アプリケーションキー", "クライアントキー");
}

先程の2つのキーを指定してくだはい。 初期化が成功したか否かはチェックした方が良いと思いますが、そこはよしなにやってください。

6. データ登録

これでデータ登録は出来るようになった訳ですが、登録する処理を作るよりも前にデータを保存するテーブルを作成する必要があります。

テーブルはダッシュボードのデータストアから作成する事が出来ます。

  1. 「+作成」ボタンでテーブル名をきめる
  2. 「+新しいフィールド」ボタンで必要なカラムを追加

今回は以下の名前で作成しています。

f:id:gmatsu:20170804135505p:plain

NCMBではテーブルの事をクラス、カラムをフィールドと呼びます。

テーブルを作成するとobjectId、createDate、updateDate、aclが初期カラムとして追加されます。

その他必要な物は自分で追加する必要があります。

にわとりアプリとは関係ありませんが、今回はRPG的なカラムとしてlv、hp、expを追加で準備しました。

ちなみにテーブル名はUSER_DATAとしました。

ここにデータを登録してみましょう。

NcmbManager.hに追加

namespace NcmbConnect {
    class NcmbManager :public cocos2d::Ref {
    public:
        /*
            コンストラクタ、デストラクタ、SDK初期化
        */

        /**
         * @brief データ登録
         * @param const char* class_name クラス名
         * @param int lv レベル
         * @param int hp HP
         * @param int exp 経験値
         */
        static void add(const char* class_name, int lv, int hp, int exp);
    };
}

NcmbManager.mmに追加

namespace NcmbConnect {
    /*
        コンストラクタ、デストラクタ、SDK初期化
     */

    /**
     * @brief データ登録
     * @param const char* class_name クラス名
     * @param int lv レベル
     * @param int hp HP
     * @param int exp 経験値
     */
    void NcmbManager::add(const char* class_name, int lv, int hp, int exp) {
        // 引数をオブジェクトに変換
        NSString* class_name_str = [NSString stringWithCString:class_name encoding:NSUTF8StringEncoding];
        NSNumber* lv_num = [NSNumber numberWithInt:lv];
        NSNumber* hp_num = [NSNumber numberWithInt:hp];
        NSNumber* exp_num = [NSNumber numberWithInt:exp];

        // NCMBObject生成
        NCMBObject* obj = [NCMBObject objectWithClassName:class_name_str];

        // 登録データと登録先のカラム名の指定
        [obj setObject:lv_num forKey:@"lv"];
        [obj setObject:hp_num forKey:@"hp"];
        [obj setObject:exp_num forKey:@"exp"];

        // 登録
        [obj saveInBackgroundWithBlock:^(NSError* error) {
            if (error) {
                // 失敗
                NSLog(@"NCMB - データ登録失敗");
            } else {
                // 成功
                NSLog(@"NCMB - データ登録成功");
            }
        }];
    }
}

このように準備した関数を使用してデータの登録を行います。

テストですのでcocosのプロジェクトを作成した際に自動で作られるHelloWorld.cppに登録処理を書いてみましょう。

#include "External/Ncmb/NcmbManager.h"

bool HelloWorld::init()
{
    // 登録
    NcmbConnect::NcmbManager::add("USER_DATA", 10, 123, 64);
}

ちゃんとデータが保存されたかダッシュボードで確認してみましょう

f:id:gmatsu:20170804165630p:plain

無事登録出来ましたか?

ふう、とりあえずここまででiOS版の処理は完成です。

Android版は次回の記事で書こうと思っています。

iOS版と同じような処理を書くだけでなく、ネイティブ連携もさせなくてはならないので、Androidの方が骨が折れます。

でもこればっかりはしゃーなしなので、次回頑張っていきましょう。

これから気温もどんどん上がって行くと思いますので、みなさんも体に気をつけながら頑張って下さいね。

私はドラクエ11を頑張ります。