nirasan's tech blog

趣味や仕事の覚え書きです。Linux, Perl, PHP, Ruby, Javascript, Android, Cocos2d-x, Unity などに興味があります。

cocos2d-x から Parse を使う

はじめに

cocos2d-x から Parse の REST API 経由でユーザー登録とログインをしてみるテスト。

参考書籍

Cocos2d‐x開発のレシピ―iOS/Android対応

Cocos2d‐x開発のレシピ―iOS/Android対応

空のシーンの作成

http://nirasan.hatenablog.com/entry/2013/09/23/124822 に従って空のシーンを作成する

Parse に登録してアプリを作成する

サイトのURLは https://parse.com/
「Sign UP」から、ユーザー登録と、流れでアプリ作成もできる。

ユーザー登録方法を確認

ドキュメントページ https://parse.com/docs/rest#users-signupREST API の使い方と、接続用のパラメータが記載されている。
curlpython を使った例が出ているので、読み替えて使用すること。

curl のバージョンは以下のようなもの。ID や KEY は書き換えている。

curl -X POST \
  -H "X-Parse-Application-Id: SOME_ID" \
  -H "X-Parse-REST-API-Key: SOME_KEY" \
  -H "Content-Type: application/json" \
  -d '{"username":"cooldude6","password":"p_n7!-e8","phone":"415-392-0202"}' \
  https://api.parse.com/1/users

ヘッダーで認証情報を渡して、JSONでユーザーのデータを渡せば良さそう。

ユーザー登録コード作成

  • とりあえず各種パラメータはべた書きで、登録のテストをする。
GameScene.h
  • インクルードの追加
#include "cocos2d.h"
#include "cocos-ext.h"

USING_NS_CC_EXT;
using namespace std;
  • GameScene の public に以下を追記
    void singningUp();
    void dumpData(CCHttpClient* client, CCHttpResponse* response);
GameScene.cpp
  • using namespace の追加
USING_NS_CC;
USING_NS_CC_EXT;
using namespace std;
  • 末尾に追記
// ユーザー登録
void GameScene::singningUp()
{
    // HTTPリクエスト用オブジェクト
    CCHttpRequest* r = new CCHttpRequest();
    
    // ヘッダーに認証情報の設定
    r->setUrl("https://api.parse.com/1/users");
    vector<string> h;
    h.push_back("X-Parse-Application-Id: SOME_ID");
    h.push_back("X-Parse-REST-API-Key: SOME_KEY");
    h.push_back("Content-Type: application/json");
    r->setHeaders(h);
    
    // メソッド
    r->setRequestType(CCHttpRequest::kHttpPost);
    
    // ボディにユーザーデータをJSONで設定
    const char buffer[] = "{\"username\":\"john\",\"password\":\"p_n7!-e8\",\"phone\":\"415-392-0202\"}";
    r->setRequestData(buffer, strlen(buffer));
    
    // レスポンスを処理するコールバックメソッドを指定
    r->setResponseCallback(this, httpresponse_selector(GameScene::dumpData));
    
    // リクエスト実行
    CCHttpClient::getInstance()->send(r);
    r->release();
}

void GameScene::dumpData(CCHttpClient *client, CCHttpResponse *response)
{
    if (!response->isSucceed()) {
        CCLOG("error buffer: %s", response->getErrorBuffer());
    }
    
    std::vector<char> *buffer = response->getResponseData();
    char out[buffer->size()];
    for (int i = 0; i < buffer->size(); i++) {
        out[i] = buffer->at(i);
    }
    CCLOG("data: %s", out);
}
  • GameScene::init でユーザー登録を実行
bool GameScene::init()
{
    if (!CCLayer::init()) {
        return false;
    }
    
    singningUp(); // 追記
    
    return true;
}

ユーザー登録の実行

run でユーザー登録が実行される。
成功すると下記のようなレスポンスがかえってくる。

{"createdAt":"2013-09-29T02:08:59.090Z","objectId":"Agn4dcbqud","sessionToken":"xhjig7gba59ofa33jwwyj18fu"}

もらった sessionToken を使えば、他のユーザーにひもづくAPIも利用できるようになる様子。

ログインのコード作成

GameScene.h
  • public に追記
    void loggingIn();
    string urlEncode(string &str);
GameScene.cpp
  • 末尾に追記
// ログイン
void GameScene::loggingIn()
{
    // HTTPリクエスト用オブジェクト
    CCHttpRequest* r = new CCHttpRequest();
    
    // ヘッダーに認証情報の設定
    vector<string> h;
    h.push_back("X-Parse-Application-Id: SOME_ID");
    h.push_back("X-Parse-REST-API-Key: SOME_KEY");
    r->setHeaders(h);
    
    // メソッド
    r->setRequestType(CCHttpRequest::kHttpGet);
    
    //クエリパラメータでログインデータを渡す
    string host = "api.parse.com";
    string path = "1/login";
    string username = "john";
    string password = "p_n7!-e8";
    CCString* urlString =
        CCString::createWithFormat("https://%s/%s?username=%s&password=%s",
                                   host.c_str(),
                                   path.c_str(),
                                   urlEncode(username).c_str(),
                                   urlEncode(password).c_str()
                                   );
    r->setUrl(urlString->getCString());
    
    // レスポンスを処理するコールバックメソッドを指定
    r->setResponseCallback(this, httpresponse_selector(GameScene::dumpData));
    
    // リクエスト実行
    CCHttpClient::getInstance()->send(r);
    r->release();
}

/* URLエンコード via http://d.hatena.ne.jp/ytakano/20081016/urlencode */
string GameScene::urlEncode(string &str)
{
    std::ostringstream os;
    
    for (int i = 0; i < str.size(); i++) {
        char c = str[i];
        if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
            (c >= '0' && c <= '9') ||
            c == '-' || c == '_' || c == '.' || c == '~') {
            os << c;
        } else {
            char s[4];
            snprintf(s, sizeof(s), "%%%02x", c & 0xff);
            os << s;
        }
    }
    
    return os.str();
}
  • init で実行するように
bool GameScene::init()
{
    if (!CCLayer::init()) {
        return false;
    }
    
    //singningUp(); // コメントアウト
    loggingIn(); // 追記
    
    return true;
}

ログイン実行

アプリを run してログインを実行する。
レスポンスで登録時と同様にユーザーデータがかえってくる。

{"username":"john","phone":"415-392-0202","createdAt":"2013-09-29T02:08:59.090Z","updatedAt":"2013-09-29T02:08:59.090Z","objectId":"Agn4dcbqud","sessionToken":"xhjig7gba59ofa33jwwyj18fu"}

さいごに

GETとPOSTのパターンが試せたので、あとは応用で何とかなりそう。
C++でURLエンコードどうすればいいかがわからなくてはまった。
JSONのパースはまたあとで。