Blog
All Blog Posts | Next Post | Previous PostFNC Hidden Gems: JSON persistence
Tuesday, April 28, 2020
Intro
FNC has evolved over time. Each update brings new features, some of them are visible at designtime/runtime. Some of time are happening behind the screens. Some updates are bringing a lot of fixes to make FNC more stable across the multiple frameworks and platforms FNC supports. JSON persistence is one of those hidden gems that is available in TMS FNC Core. Today's blog brings a step by step tutorial on how to implement JSON persistence in your application, and how to import objects from JSON.Getting Started
JSON formatted data can come from a REST service, a database, a local file, plain text ... . It's an easy to read/learn/use and consume format and in FNC we have added support for mapping objects to JSON and vice versa. The code below is a sample of JSON that we will map on an object in Delphi. We'll focus on having an object that can access the properties shown in the JSON below. Note that only the published properties can be accessed.{ "$type":"TPerson", "address":{ "$type":"TPersonAddress", "addressLocality":"Colorado Springs", "addressRegion":"CO", "postalCode":"80840", "streetAddress":"100 Main Street" }, "colleague":[ "http://www.example.com/JohnColleague.html", "http://www.example.com/JameColleague.html" ], "email":"info@example.com", "jobTitle":"Research Assistant", "name":"Jane Doe", "birthDate":"1979-10-12", "gender":"female", "nationality":"Albanian", "telephone":"(123) 456-6789", "url":"http://www.example.com", }
For accessing this data we need to define our classes first:
type TPersonAddress = class(TPersistent) private FPostalCode: string; FAddressLocality: string; FAddressRegion: string; FStreetAddress: string; published property AddressLocality: string read FAddressLocality write FAddressLocality; property AddressRegion: string read FAddressRegion write FAddressRegion; property PostalCode: string read FPostalCode write FPostalCode; property StreetAddress: string read FStreetAddress write FStreetAddress; end; TPerson = class(TPersistent) private FAddress: TPersonAddress; FColleague: TStringList; FBirthDate: string; FName: string; FEmail: string; FTelephone: string; FGender: string; FNationality: string; FJobTitle: string; FURL: string; public constructor Create; destructor Destroy; override; published property Address: TPersonAddress read FAddress; property Colleague: TStringList read FColleague; property Email: string read FEmail write FEmail; property JobTitle: string read FJobTitle write FJobTitle; property Name: string read FName write FName; property BirthDate: string read FBirthDate write FBirthDate; property Gender: string read FGender write FGender; property Nationality: string read FNationality write FNationality; property Telephone: string read FTelephone write FTelephone; property URL: string read FURL write FURL; end;
const jsonSample = '{' + '"$type": "TPerson",' + '"address":{' + '"$type": "TPersonAddress",' + '"addressLocality":"Colorado Springs",' + '"addressRegion":"CO",' + '"postalCode":"80840",' + '"streetAddress":"100 Main Street"' + '},' + '"colleague":[' + '"http://www.example.com/JohnColleague.html",' + '"http://www.example.com/JameColleague.html"' + '],' + '"email":"info@example.com",' + '"jobTitle":"Research Assistant",' + '"name":"Jane Doe",' + '"birthDate":"1979-10-12",' + '"gender":"female",' + '"nationality":"Albanian",' + '"telephone":"(123) 456-6789",' + '"url":"http://www.example.com"' + '}';
1. Use the TTMSFNCPersistence class
Add the unit *TMSFNCPersistence to the uses list (* = FMX., LCL, VCL., WEBLib.), and use the following code:
var p: TPerson; s: TStringStream; begin p := TPerson.Create; s := TStringStream.Create(jsonSample); try TTMSFNCPersistence.LoadSettingsFromStream(p, s); finally s.Free; p.Free; end; end;
var p: TPerson; begin p := TPerson.Create; try p.JSON := jsonSample; finally p.Free; end; end;
p: TPerson; begin p := TPerson.Create; try p.JSON := jsonSample; p.Name := 'tmssoftware.com'; TTMSFNCUtils.Log(p.JSON); //or TTMSFNCPersistence.SaveSettingsToFile(p, 'TPerson.json'); finally p.Free; end; end;
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} uses FMX.TMSFNCTypes, FMX.TMSFNCPersistence; const jsonSample = '{' + '"$type": "TPerson",' + '"address":{' + '"$type": "TPersonAddress",' + '"addressLocality":"Colorado Springs",' + '"addressRegion":"CO",' + '"postalCode":"80840",' + '"streetAddress":"100 Main Street"' + '},' + '"colleague":[' + '"http://www.example.com/JohnColleague.html",' + '"http://www.example.com/JameColleague.html"' + '],' + '"email":"info@example.com",' + '"jobTitle":"Research Assistant",' + '"name":"Jane Doe",' + '"birthDate":"1979-10-12",' + '"gender":"female",' + '"nationality":"Albanian",' + '"telephone":"(123) 456-6789",' + '"url":"http://www.example.com"' + '}'; type TPersonAddress = class(TPersistent) private FPostalCode: string; FAddressLocality: string; FAddressRegion: string; FStreetAddress: string; published property AddressLocality: string read FAddressLocality write FAddressLocality; property AddressRegion: string read FAddressRegion write FAddressRegion; property PostalCode: string read FPostalCode write FPostalCode; property StreetAddress: string read FStreetAddress write FStreetAddress; end; TPerson = class(TPersistent) private FAddress: TPersonAddress; FColleague: TStringList; FBirthDate: string; FName: string; FEmail: string; FTelephone: string; FGender: string; FNationality: string; FJobTitle: string; FURL: string; public constructor Create; destructor Destroy; override; published property Address: TPersonAddress read FAddress; property Colleague: TStringList read FColleague; property Email: string read FEmail write FEmail; property JobTitle: string read FJobTitle write FJobTitle; property Name: string read FName write FName; property BirthDate: string read FBirthDate write FBirthDate; property Gender: string read FGender write FGender; property Nationality: string read FNationality write FNationality; property Telephone: string read FTelephone write FTelephone; property URL: string read FURL write FURL; end; { TPerson } constructor TPerson.Create; begin FAddress := TPersonAddress.Create; FColleague := TStringList.Create; end; destructor TPerson.Destroy; begin FreeAndNil(FAddress); FreeAndNil(FColleague); inherited; end; procedure TForm1.Button1Click(Sender: TObject); var p: TPerson; begin p := TPerson.Create; try p.JSON := jsonSample; finally p.Free; end; end; end.
Pieter Scheldeman
This blog post has received 7 comments.
2. Wednesday, May 6, 2020 at 5:42:57 PM
Hi Bruno, how''s it go?
Any job at Delphi you have for me? (On-site or remote.)
Al Gonzalez
@algonzalez74 in Twitter
Any job at Delphi you have for me? (On-site or remote.)
Al Gonzalez
@algonzalez74 in Twitter
Al Gonzalez
3. Thursday, May 7, 2020 at 3:31:34 PM
Thanks for your interest! We look forward to receive via email your CV & motivation.
Bruno Fierens
4. Saturday, May 16, 2020 at 6:55:22 AM
Thank you very much, Bruno. I already sent you the email with my CV. I await your assessment and response, please.
Best regards.
Best regards.
Al Gonzalez
5. Thursday, June 24, 2021 at 9:00:20 AM
Tried to put this together with the current version and the JSON property seems to be gone. :(
Farmer Christian
6. Thursday, June 24, 2021 at 9:05:10 AM
Hi, I have copy pasted the above sampe in a new project and can still compile and run the example, so maybe you forgot to include a unit? JSON property is included in a class helper in the FMX.TMSFNCTypes unit
Pieter Scheldeman
7. Thursday, June 24, 2021 at 9:16:15 AM
My bad. I setup the uses clause incorrectly.
Farmer Christian
All Blog Posts | Next Post | Previous Post
Price Rhett