Sto cercando di interfacciarmi con le OpenWeaterMaps API (http://openweathermap.org/). Le API sono chiare, ho qualche problema lato Lazarus....
Il mio scopo è semplice: recuperare i dati JSON dall'URL appropriato e quindi fare il parsing di alcuni nodi sotto forma di semplici stringhe.
Il mio programma fonora cerca di ottenere il valore di "main" ("Clouds" nell'esempio che segue - notate che ci sono due differenti nodi "main" nella risposta della API, sto cercando di accedere il primo nidificato dentro "weather" o, in altri termini "weather->main:Clouds").
Esempio della API response:
{"coord":
{"lon":145.77,"lat":-16.92},
"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],
"base":"cmc stations",
"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37},
"wind":{"speed":5.1,"deg":150},
"clouds":{"all":75},
"rain":{"3h":3},
"dt":1435658272,
"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870},
"id":2172797,
"name":"Cairns",
"cod":200}
Il mio codice finora (MYCITYID e MYAPPID sono segnaposto per i valori reali, che ovviamente non pubblico...):
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, fphttpclient,
fpjson, jsonparser;
type
{ TForm1 }
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
jData : TJSONData;
jObject : TJSONObject;
wheater_main : String;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
jData := GetJSON(TFPHTTPClient.SimpleGet('http://api.openweathermap.org/data/2.5/weather?id=MYCITYID&appid=MYAPPID'));
wheater_main := jData.FindPath('main').AsString;
Memo1.Lines.Clear;
Memo1.Lines.Add(wheater_main);
end;
end.
Il codice compila correttamente e produce un eseguibile, ma quando tento di lanciarlo appare il seguente errore:
Cannot convert data from object value.
Qualche idea su cosa non funzioni? Temo che sia il parsing....
Grazie in anticipo per il vostro tempo e la vostra attenzione.
ciao CieloInvernale
"weather" è un array, anche se contiene un solo oggetto (di cui "main" è una delle proprietà).
Per questo devi prima identificare quale elemento dell'array vuoi usare per leggere il valore di "main".
Prova il codice quì sotto.
procedure TForm1.FormCreate(Sender: TObject);
var jData : TJSONData;
jObject : TJSONObject;
jObject2 : TJSONObject;
begin
jData:=GetJSON(
'{"coord": ' +
'{"lon":145.77,"lat":-16.92}, ' +
'"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}], ' +
'"base":"cmc stations", ' +
'"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37}, ' +
'"wind":{"speed":5.1,"deg":150}, ' +
'"clouds":{"all":75}, ' +
'"rain":{"3h":3}, ' +
'"dt":1435658272, ' +
'"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870}, ' +
'"id":2172797, ' +
'"name":"Cairns", ' +
'"cod":200} '
);
jObject := TJSONObject(jData.FindPath('weather'));
jObject2 := TJSONObject(jObject.Extract(0));
wheater_main := jObject2.FindPath('main').AsJSON;
Memo1.Clear;
Memo1.Lines.Add(wheater_main);
end;
nomorelogic
Edit:
per info su come gestire XML e JSON, puoi vedere questo documento
http://www.freepascal.org/~michael/articles/webdata/webdata.pdf (http://www.freepascal.org/~michael/articles/webdata/webdata.pdf)
Edit2:
per completezza, riporto il link sullo stesso quesito sul forum ufficiale
http://forum.lazarus-ide.org/index.php/topic,35183.msg232259/topicseen.html#new (http://forum.lazarus-ide.org/index.php/topic,35183.msg232259/topicseen.html#new)