Utiliser l’API Graph de Facebook avec C++Builder

Facebook se passe sans doute de présentation, par contre son API est peut-être moins connu. Dans cet article nous irons chercher les informations publiques d’un utilisateur qui ne nécessitent aucune autorisation.

La première étape est de créer un nouveau projet FireMonkey HD. Dans la Form il faut insérer un TIdHTTP, un TIdSSLIOHandlerSocketOpenSSL, un TStringGrid, un TImage, un contrôle TEdit, un TLabel et finalement un TButton. Vous pouvez donner comme texte à votre bouton le mot « Rechercher » et pour le TLabel vous pouvez y inscrire « Nom d’utilisateur: ». Je vous propose de placer les composants dans la fenêtre de la manière suivante:
Pour ceux qui se le demande j’ai utilisé le style Air.Style. Ça change un peu des fenêtres Windows que l’on voit tout le temps.

Dans votre fichier cpp voici le fichier d’en-tête à ajouter:

#include <Data.DBXJSON.hpp>

Voici le code à ajouter dans votre constructeur:

    IdHTTP1->IOHandler = IdSSLIOHandlerSocketOpenSSL1;

    // Ceci est nécessaire pour les redirections
    IdHTTP1->HandleRedirects = true;

    // Propriété par défaut pour le contrôle grille
    StringGrid1->ShowSelectedCell = false;
    StringGrid1->ReadOnly = true;
    StringGrid1->RowCount = 0;

    // Ajout de la première colonne
    StringGrid1->AddObject(new TStringColumn(this));
    StringGrid1->Columns[0]->Header = L"Nom";
    StringGrid1->Columns[0]->Width = 150;

    // Ajout de la deuxième colonne
    StringGrid1->AddObject(new TStringColumn(this));
    StringGrid1->Columns[1]->Header = L"Valeur";
    StringGrid1->Columns[1]->Width = 150;

Étant donné que nous accéderons à un site web qui utilise SSL (https), la première ligne de code est critique. Sans elle, une exception dans la classe EIdIOHandlerPropInvalid produira le message « IOHandler value is not valid ». Parce que nous utilisons OpenSSL, les fichiers ssleay32.dll et libeay32.dll devront être distribués avec votre application.

La prochaine étape est d’ajouter le code dans l’événement OnClick du bouton.

    System::Classes::TMemoryStream* ResponseContent = new System::Classes::TMemoryStream;

    try
    {
        // On vide la liste avant d'ajouter les valeurs
        StringGrid1->RowCount = 0;
        Image1->Bitmap = NULL;

        String URL = "https://graph.facebook.com/" + Edit1->Text;

        String Response = IdHTTP1->Get(URL);

        TJSONObject* Obj = static_cast<TJSONObject*>(TJSONObject::ParseJSONValue(Response));
        TJSONPair* Pair;
        TJSONString* Answer;

        if((Pair = Obj->Get("id")) != NULL)
        {   // ID Facebook
            const int Pos = StringGrid1->RowCount;
            StringGrid1->RowCount++;
            Answer = static_cast<TJSONString*>(Pair->JsonValue);
            StringGrid1->Cells[0][Pos] = "ID";
            StringGrid1->Cells[1][Pos] = AnsiDequotedStr(Answer->ToString(), '\"');
        }
        if((Pair = Obj->Get("name")) != NULL)
        {   // Nom complet
            const int Pos = StringGrid1->RowCount;
            StringGrid1->RowCount++;
            Answer = static_cast<TJSONString*>(Pair->JsonValue);
            StringGrid1->Cells[0][Pos] = "Nom";
            StringGrid1->Cells[1][Pos] = AnsiDequotedStr(Answer->ToString(), '\"');
        }
        if((Pair = Obj->Get("first_name")) != NULL)
        {   // Prénom
            const int Pos = StringGrid1->RowCount;
            StringGrid1->RowCount++;
            Answer = static_cast<TJSONString*>(Pair->JsonValue);
            StringGrid1->Cells[0][Pos] = "Prénom";
            StringGrid1->Cells[1][Pos] = AnsiDequotedStr(Answer->ToString(), '\"');
        }
        if((Pair = Obj->Get("last_name")) != NULL)
        {   // Nom de famille
            const int Pos = StringGrid1->RowCount;
            StringGrid1->RowCount++;
            Answer = static_cast<TJSONString*>(Pair->JsonValue);
            StringGrid1->Cells[0][Pos] = "Nom de famille";
            StringGrid1->Cells[1][Pos] = AnsiDequotedStr(Answer->ToString(), '\"');
        }
        if((Pair = Obj->Get("gender")) != NULL)
        {   // Sexe (female ou male)
            const int Pos = StringGrid1->RowCount;
            StringGrid1->RowCount++;
            Answer = static_cast<TJSONString*>(Pair->JsonValue);
            StringGrid1->Cells[0][Pos] = "Sexe";
            StringGrid1->Cells[1][Pos] = AnsiDequotedStr(Answer->ToString(), '\"');
        }

        delete Obj;

        // Téléchargement de l'image
        IdHTTP1->Get(URL + "/picture", ResponseContent);

        Image1->Bitmap = new Fmx::Types::TBitmap(ResponseContent);
    }
    catch(...)
    {
    }

    delete ResponseContent;

Dans le code on insère dans la liste seulement quelques informations, mais il en existe plusieurs autres qui sont disponibles.

À présent, vous connaissez le minimum requis pour commencer à vous amuser avec cette interface API .

Utiliser l’API Google Street View Image

L’API Google Street View Image permet de télécharger une image statique par l’envoi d’une requête HTTP standard.

La première étape est de créer un nouveau projet FireMonkey HD. Dans la Form il faut insérer un TIdHTTP, un TImage, un TEdit, un TTrackBar et quatre contrôles TButton. Je vous propose de placer les composants dans la fenêtre de la manière suivante:

Google Street View Image API

Le TEdit servira à entrer les coordonnées de latitude et longitude. La barre graduée permet d’agrandir et de réduire l’affichage de l’image. Un nombre plus petit signifie un plus grand niveau de zoom. Les boutons servent à déplacer la caméra dans différentes directions. Le résultat sera évidemment affiché dans le composant TImage.

Voici les attributs et la méthode à ajouter à votre fichier .h:

    int FHeading;
    int FFieldOfView;
    int FPitch;

    void __fastcall UpdateImage();

Voici tout le code qui sera nécessaire pour l’application:

//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
    // On fait croire à Google que l'on est Firefox 16.0
    IdHTTP1->Request->UserAgent =
        "Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20100101 Firefox/16.0";

    // Valeur par défaut
    FHeading = 0;
    FFieldOfView = 90;
    FPitch = 0;

    TrackBar1->Tracking = false;
    TrackBar1->Value = FFieldOfView;
    TrackBar1->Min = 10;
    TrackBar1->Max = 120;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::UpdateImage()
{
    System::Classes::TMemoryStream* ResponseContent = new System::Classes::TMemoryStream;

    try
    {
        String URL = Format("http://maps.googleapis.com/maps/api/streetview?size=%dx%d&location=%s&sensor=false&heading=%d&fov=%d&pitch=%d",
            ARRAYOFCONST((
            (int)Image1->Width, // Image Width
            (int)Image1->Height, // Image Height
            EditLocation->Text, // Location
            FHeading, // Heading (0 to 360)
            FFieldOfView, // Field of view
            FPitch // Pitch
            )));

        IdHTTP1->Get(URL, ResponseContent); // Téléchargement de l'image

        Image1->Bitmap = new Fmx::Types::TBitmap(ResponseContent);
    }
    catch(...)
    {
    }

    delete ResponseContent;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditLocationKeyUp(TObject *Sender, WORD &Key,
          System::WideChar &KeyChar, TShiftState Shift)
{
    if(Key == vkReturn)
    {   // La touche Entrée a été appuyée, on met à jour l'image
        UpdateImage();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{
    FFieldOfView = TrackBar1->Value;
    UpdateImage();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonLeftClick(TObject *Sender)
{
    // Déplacement de la caméra d'un angle de 20° vers la gauche
    FHeading = (FHeading - 20) % 360;
    UpdateImage();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonRightClick(TObject *Sender)
{
    // Déplacement de la caméra d'un angle de 20° vers la droite
    FHeading = (FHeading + 20) % 360;
    UpdateImage();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonTopClick(TObject *Sender)
{
    if((FPitch += 10) > 90)
    {   // La caméra est complètement vers le haut
        FPitch = 90;
    }
    UpdateImage();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonBottomClick(TObject *Sender)
{
    if((FPitch -= 10) < -90)
    {   // La caméra est complètement vers le bas
        FPitch = -90;
    }
    UpdateImage();
}
//---------------------------------------------------------------------------

Le code qui est le plus important se trouve dans la méthode UpdateImage. Tous les évènements servent uniquement à modifier l’un des paramètres de l’URL.

J’aurais bien aimé utiliser le composant TLocationSensor disponible dans C++Builder XE3 pour aller chercher mes coordonnées de latitude et longitude, mais je n’ai pas le matériel nécessaire pour le tester. C’est dommage car ça me semble facile à utiliser.