Access a JSON webservice with Qt C++

Original post at Makina Corpus

Webservices are everywhere ! There are relevant in many situations, and accessing them from your Qt C++ application is not an heresy.

I will present here a very simple way to retrieve a JSON from a GET request.

HTTP Requests

Using QNetworkAccessManager is a piece of cake :

QNetworkAccessManager networkManager;

QUrl url("http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&alt=json");
QNetworkRequest request;
request.setUrl(url);

QNetworkReply* currentReply = networkManager.get(request);  // GET

But, note that a slightly more generic approach would be to build the QUrl from a parameters list :

QUrl url("http://gdata.youtube.com/feeds/api/standardfeeds/");
QString method = "most_popular";
url.setPath(QString("%1%2").arg(url.path()).arg(method));

QMap<QString, QVariant> params;
params["alt"] = "json";
params["v"] = "2";

foreach(QString param, params.keys()) {
    url.addQueryItem(param, params[param].toString());
}

Parsing JSON

Get yourself a slot to parse the QNetworkReply :

connect(&networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onResult(QNetworkReply*)));
void YourClass::onResult(QNetworkReply* reply)
{
    if (m_currentReply->error() != QNetworkReply::NoError)
        return;  // ...only in a blog post

    QString data = (QString) reply->readAll();

    QScriptEngine engine;
    QScriptValue result = engine.evaluate(data);

    /*
      Google YouTube JSON looks like this :

      {
        "version": "1.0",
        "encoding": "UTF-8",
        "feed": {
          ..
          ..
          "entry": [{
            "title": {
                "$t": "Nickelback- When We Stand Together"
            },
            "content": {
                "type": "application/x-shockwave-flash",
                "src": "http://www.youtube.com/v/76vdvdll0Y?version=3&f=standard&app=youtube_gdata"
            },
            "yt$statistics": {
                "favoriteCount": "29182",
                "viewCount": "41513706"
            },
            ...
            ...
          },
          ...
          ...
          ]
        }
      }
    */

    // Now parse this JSON according to your needs !
    QScriptValue entries = result.property("feed").property("entry");
    QScriptValueIterator it(entries);
    while (it.hasNext()) {
        it.next();
        QScriptValue entry = it.value();

        QString link = entry.property("content").property("src").toString();
        int viewCount = entry.property("yt$statistics").property("viewCount").toInteger();

        // Do something with those...
    }
}

That's it :)

If you want more complexity, and don't mind adding extra-dependencies, check out Tomasz Siekierda's QtWebService !

#c++, #qt, #json - Posted in the Dev category