Tips and Frequently Asked Questions
How to avoid error: 'Could not bind socket. Address and port are already in use.'
Another application on your system is already using the port number assigned in App.CallBackPort and App.CallBackURL.
To avoid this error, assign a different port number to App.CallBackPort and App.CallBackURL.
For example: change "http://localhost:8888" to "http://localhost:8889".
Don''t forget to update the Redirect URI value for your App''s configuration in the Web Console of the respective service as well.
How to set the language for a synthesized text with TAdvMSBingSpeech
Use the VoiceFont parameter of the Synthesize call to change the language of the resulting audio. Besides English there are several other languages available, including German, French and Spanish. You can also choose to use a Female or Male voice.
Example:
MSBingSpeech1.Synthesize(Text, Stream, bvGermanDEFemale);
How to retrieve the files and folders for a specific folder from GDrive
TadvGDrive: To retrieve the files and folders for a specific folder, use the GetFolderList call with the folder’s ID as a parameter.
Example:
var
ciFolderList: TCloudItems;
begin
ciFolderList := AdvGDrive.GetFolderList(AdvGDrive.GetFileInfo(FolderID));
Registering an application for using a cloud service
How to store OAuth token in a database table instead of an ini file
Make a dataset with following string fields:
ACCESS_TOKEN
AUTH_TOKEN
ACCESS_TOKEN_SECRET
AUTH_TOKEN_SECRET
REFRESH_TOKEN
EXTRA_DATA
And set
CloudService.PersistTokens.DataSource = yourdatasource;
CloudService.PersistTokens.Location = plDatabase;
Then call:
CloudService.LoadTokens
CloudService.SaveTokens
to read and write to the dataset.
Putting data in the cloud with myCloudData.net and component TAdvmyCloudData
If we’d want to persist application settings information in the cloud on
http://myCloudData.net, this is very simple to do in Delphi.
After connecting with TAdvmyCloudData, we can test for the presence of the table that holds the data to persist, create table & metadata when it doesn’t exist and persist the data.
Code:
var
table: TmyCloudDataTable;
entity: TmyCloudDataEntity;
doins: boolean;
begin
table := AdvMyCloudData1.TableByName(''APPDATA'');
// create table with metadata on the fly if it doesn’t exist for the myCloudData.net account
if not Assigned(table) then
begin
table := AdvMyCloudData1.CreateTable(''APPDATA'');
table.MetaData.Add(''WINWIDTH'', ftInteger);
table.MetaData.Add(‘WINHEIGHT’,ftInteger);
table.MetaData.Add(''WINLEFT'', ftInteger);
table.MetaData.Add(''WINTOP'', ftInteger);
table.MetaData.Add(''USERNAME'', ftString,50);
end;
// check for existing entity holding the data
table.Query;
doins := table.Entities.Count = 0;
if doins then
entity := table.Entities.Add
else
entity := table.Entities[0];
// setting data to persist in the entity
entity.Value[‘WINWIDTH’] := form.Width;
entity.Value[‘WINHEIGHT’] := form.Height;
entity.Value[‘WINLEFT’] := form.Left;
entity.Value[‘WINTOP’] := form.Top;
entity.Value[‘USERNAME’] := GetWindowsUser();
// inserting or updating entity
if doins then
entity.Insert
else
entity.Update;
end;
Simplified code to have our cloud components connect to a cloud service
We have simplified the code that needs to be written to have our cloud components connect to a cloud service. Before it was needed to load persisted tokens, test the tokens, refresh tokens when needed or start a new authentication / authorization process. From now on, this is all simplified. When the cloud component application key & secret are set and the location where to persist tokens is specified, the code can be reduced to a call to Connect and handling the OnConnected event from where you can start calling the cloud service methods:
procedure TForm1.Button1Click(Sender: TObject);
begin
AdvOneDrive1.Connect;
end;
procedure TForm1.AdvOneDrive1Connected(Sender: TObject);
begin
Init;
end;
TAdvGDrive: How to upload a file to a known folder without using GetDriveInfo
Call "SearchFolder" with the folder name as a parameter. If that returns true, the first item of the "Drive" collection contains the required folder.
Then call "Upload" with the folder object and the filename of the file to upload as parameters.
Example:
if AdvGDrive.SearchFolder('FolderName') then
AdvGDrive.Upload(AdvGDrive.Drive.Items[0], 'FileName.ext');
Recurring events in Google calendars
The Recurrence and RecurringID properties of the TGCalendarItem are explained in the
product manual PDF. Below you can find some extended information about these properties.
New recurring events:
Create a new event and simply assign a recurrence string to the Recurrence property and also fill in the relevant time zone in the TimeZone property. Then add the Event.
Example:
var
li: TGCalendarItem;
begin
li := AdvGCalendar1.Items.Add;
li.Summary := ''Summary'';
li.Description := ''Description'';
li.Location := ''Location'';
li.Recurrence := ''RRULE:FREQ=DAILY;COUNT=5'';
li.TimeZone := ''Europe/Brussels'';
li.StartTime := dtStart;
li.EndTime := dtEnd;
li.CalendarID := sCalendarID;
AdvGCalendar1.Add(li);
Existing recurring events:
A recurrent item consists of two types of events. The first is the parent event which contains the Recurrence string. The second are the instances of the recurrent item. By design, only the instances are retrieved when requesting a list of events. To retrieve the parent item separately you can use the RecurringID property value of one of the instances as the ItemID parameter for the GetItemById call.
How to avoid '401 error: invalid_client' when using Google services
Download files from cloud storage service with ID or DownloadURL only
Different APIs provide different information or use different techniques. For example, unlike the Google Drive API, the OneDrive API does not provide a specific download URL for each file.
However only the ID of the file is required to be able download the file, so you can create a dummy CloudItem with only the ID property assigned to be able to use the Download call.
In case of Google Drive, you can use the same technique, but assign the DownloadURL property instead of the ID.
Examples:
OneDrive / SkyDrive
var
i: TSkyDriveItem;
begin
i := TSkyDriveItem.Create(nil);
i.ID := ''abc'';
i.FileName := ''filename.ext'';
AdvSkyDrive1.Download(i, i.FileName);
i.Free;
Google Drive
var
i: TGDriveItem;
begin
i := TGDriveItem.Create(nil);
i.DownloadURL := ''abc'';
i.FileName := ''filename.ext'';
AdvGDrive1.Download(i, i.FileName);
i.Free;
Displaying the login page in the TWebBrowser control
If a login page from a cloud service is not correctly displayed in the TWebBrowser control, you can force your app to use a newer emulated IE version in the Windows registry by adding the executable name at the following location in the registry:
HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
Detailed information can be found here:
https://msdn.microsoft.com/en-us/library/ee330730(VS.85).aspx#browser_emulation
When connecting to FaceBook, I get an error similar to: "Given URL is not allowed by the Application configuration...or the domain must be a subdomain of one of the App"s domains."
Please check if the following settings are correct for your App on developers.facebook.com
- Settings/Basic
App Domains: localhost
Site URL: http://localhost/
- Settings/Advanced
Client OAuth Login: Yes
Embedded Browser OAuth Login: Yes
Supported Delphi & C++Builder versions
TMS Cloud Pack requires Delphi XE / C++Builder XE or newer. Internally TMS Cloud Pack heavily relies on the JSON parser that ships with Delphi and only from Delphi XE / C++Builder XE or newer, this JSON parser is capable of reliably parsing JSON data from modern JSON REST services.
How to post to a Facebook page
Following example shows how you can post to a Facebook page:
AdvFacebook1.GetPages;
if AdvFacebook1.PageList.Count > 0 then
AdvFacebook1.Post('Hello world', '', '', AdvFacebook1.PageList[0]);
Please make sure the page you want to post to is in the PageList collection after calling GetPages and that you have specified the correct index.
Twitter asks to enter a PIN after authentication.
Please make sure a "Callback URL" has been assigned in the Twitter app settings. See screenshots in the
PDF Manual for an example.