【cocos2dx】JSONを利用してサーバーと通信する。

サーバーと通信をする際によく使われるデータ形式の1つに「JSON」があります。 これを使って、APIやサーバー上のデータとやりとりができるようになります。 今回は、cocos2dxで、「JSON」を利用する方法を紹介したいと思います。

XMLを使って通信をする場合はこちら

【cocos2dx】XMLを利用してサーバーと通信する。 | albatrus.com

準備 - picojson

今回は「picojson」を利用してJSONの解析をおこないます。 Github : kazuho/picojson

まずは、こちらから「picojson.h」をダウンロードして下さい。

プロジェクトに追加

ダウンロードをしていただい「picojson.h」を、cocos2dxのプロジェクトに追加します。

2014-6-11-fdsasa

これを読み込んで利用をします。

Android側でのエラー対応

Eclipseでビルドをすると3つのエラーが出ます。 これを解消させる必要があります。 [c] //エラー内容 'isinf' was not declared in this scope picojson.h
'struct lconv' has no member named 'decimal_point' [/c]

コードを以下のように変更します。 これでエラーが出なくなり、上手く動作するので多分大丈夫だと思います。 [c] //169 //isnan(n) || isinf(n) isnan(n)

//330 //char decimal_point = localeconv()->decimal_point; char decimal_point = ".";

//688 //num_str += localeconv()->decimal_point; num_str.push_back('.');

[/c]

準備2 - libcurl

libcurlを利用して、サーバーと通信をおこないます。

パスの設定 - Xcode

まずは[Build Settings]->[Search Paths]->[Header Search Paths]に以下のパスを設定して下さい。 [c] //パスを設定 $(SRCROOT)/../cocos2d/external/curl/include/ios [/c]

2014-6-11-dddsas

パスの設定 - Android.mk(Eclipse)

Android側でも、libcurlが使えるようにします。 これは、Android.mkに下記のように記述をします。 [c] //ネットワークが利用できるようにします。 LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static [/c]

準備 - 読み込むJSONファイル

アプリで読み込む、JSONファイルを作成します。 [c] { "test": [ {"x": "alba", "y": "trus"}, {"x": "hogehoge", "y": "cocos2dx"} ] } [/c]

これをサーバーに設置します。 今回はDropboxを利用しました。

実装

JSONファイルの値を取り出すコードを書きました。 「cocos2dxのレシピ本」を参考にしています。 [c] static size_t onCurlWriteData(char ptr,size_t size,size_t nmemb,voiduserdata){

std::vector<char> *buff = (std::vector<char>*)userdata;
size_t sizes = size * nmemb;
buff->insert(buff->end(), (char*)ptr,(char*)ptr+sizes);
return sizes;

}

bool NetWorkLayer::getTextFromUrl(const char url,std::vector response){

CURL *curl;
CURLcode res = CURLE_FAILED_INIT;

curl = curl_easy_init();

if (curl) {

    curl_easy_setopt(curl, CURLOPT_URL, url);

    curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,onCurlWriteData);
    curl_easy_setopt(curl,CURLOPT_WRITEDATA,response);
    res=curl_easy_perform(curl);
    curl_easy_cleanup(curl);

}

if (res == CURLE_OK) {

    CCLOG("res == CURLE_OK");


    if(response->size()){

        CCLOG("response -> size()");


        return true;

    }


}

return false;

}

void NetWorkLayer::getJsonValue(const char *url){

std::vector<char> responseData;

if (getTextFromUrl(url,&responseData)) {

    std::string err;

    picojson::value va;
    picojson::parse(va, responseData.begin(), responseData.end(),&err);

    CCLOG("get json 1 %s",err.c_str());


    if (err.empty()) {

        picojson::object &root = va.get<picojson::object>();

        picojson::array &results = root["test"].get<picojson::array>();
        picojson::array::iterator it;

        CCLOG("get json 2");


        for (it = results.begin(); it != results.end(); it++) {

            picojson::object& text = it->get<picojson::object>();

          //ここで値を取り出しています。 std::string& age = text["x"].get<std::string>(); std::string& name = text["y"].get<std::string>();

            CCLOG("JSON 成功 %s",age.c_str());
            CCLOG("JSON 成功 %s",name.c_str());


        }

    }

}

} [/c]

実際の利用する際にはgetJsonValue()JSONファイルのURLを指定して下さい。 [c] void NetWorkLayer::networkJSON(){

//JSONファイルのURLを指定する
this->getJsonValue("http://dl.dropboxusercontent.com/..............");

}

[/c]

最後に

私がJSONなりXMLでサーバーと通信した理由は、アプリをアップデートしなくてもゲーム内容を変える仕組みが欲しかったからです。 とは言いましても、やりたい事は「広告の媒体の配信率を変える」ことです。 これは今色々なサービスがあるのですが、広告の媒体が限られているので、これを思い通りにできないかと考えています。

いかがでしたでしょうか? サーバ関係、JSONについてはこれまで触ったことがなかったので、コードなど不安です。 もし、もっと良い方法等あれば教えていただけると嬉しいです。

Cocos2d‐x開発のレシピ―iOS/Android対応Cocos2d‐x開発のレシピ―iOS/Android対応
松浦 晃洋,齊藤 建二,古木 映治

秀和システム
売り上げランキング : 45730

Amazonで詳しく見る