CLOUD

BaaS Tutorial: Triggering Password Reset Emails using Kinvey

Written by Sarina D on . Posted in CLOUD

This tutorial outlines how to leverage the cloud based password reset email functionality that many BaaS providers offer. This tutorial uses Kinvey and assumes that you have signed up for an account on Kinvey.com.

The demo used in this tutorial shows you how to derive from the existing Kinvey API class for the Kinvey component and add a new method for executing Kinvey’s password reset.

Step 1: Set up your Email Template

Inside your Kinvey.com account, go to AddOns->Messaging->Email Templates. Next, select the ‘Password Reset‘ email template. There you can define Sender and Reply To information, the Subject line and the HTML for the body of your email. The App Name referenced in the email is the name of your application you defined inside your Kinvey.com account.

 

Step 2: Build the C++ Multi-Device Application

Your application consists of a toolbar with a title, several buttons and 4 edit controls parented to 4 TListBox items.TListBox has GroupingKind set to Grouped and StyleLookUp set to ‘transparentlistboxstyle’.

 

Step 3: Add your KinveyProvider component and account credentials

Add the KinveyProvider1 component to your form and enter the AppKey, AppSecret and MasterSecret that is displayed inside your Kinvey.com account under ‘AppName’->Manage Environments. In order to extend the functionality, you will need to add a new method for triggering a password reset email notification which you can see in the code samples below.


Shown: Mobile app running on Windows with Mobile Preview style.

 

Step 4: Extend the KinveyProvider API and write your application code

Here is the code for my ExtendKinveytemplate.h file:

//---------------------------------------------------------------------------
#ifndef ExtendApiTemplate_h
#define ExtendApiTemplate_h

#include <System.Classes.hpp>
#include <memory>
//---------------------------------------------------------------------------
template<typename T, typename L>
class TExtendApi : public T
{
public:
    __fastcall TExtendApi(TComponent* AOwner): T(AOwner, NULL){}
    void __fastcall SignupUser(const String & AUserName, const String & APassword,
        const String & AEmail, L & ALogin);

    void __fastcall PasswordReset(const String &AEmail);
};

template<typename T, typename L>
void __fastcall TExtendApi<T,L>::SignupUser(const String & AUserName, const String & APassword,
    const String & AEmail, L & ALogin)
{
    std::auto_ptr<TJSONObject> jsonEmail(new TJSONObject());
    jsonEmail->AddPair("email", AEmail);
    T::SignupUser(AUserName, APassword, jsonEmail.get(), ALogin);
}

template<typename T, typename L>
void __fastcall TExtendApi<T,L>::PasswordReset(const String &AEmail)
{
#ifdef _KINVEY_
    Request->ResetToDefaults();
    // Basic Auth
    ConnectionInfo = this->ConnectionInfo;
    ConnectionInfo.UserName = AEmail;
    T::AddAuthParameter(TAuthentication::UserName);
    // App credentials
    T::AddAuthParameter(TAuthentication::AppSecret);
    Request->Method = TRESTRequestMethod::rmPOST;
    Request->Resource = "rpc/{appkey}/{email}/user-password-reset-initiate";
    Request->AddParameter("email", AEmail, TRESTRequestParameterKind::pkURLSEGMENT);
#else
    Request->ResetToDefaults();
    T::AddAuthParameters();
    Request->Method = TRESTRequestMethod::rmPOST;
    Request->Resource = "requestPasswordReset";
    std::auto_ptr<TJSONObject> jsonEmail(new TJSONObject());
    jsonEmail->AddPair("email", AEmail);
    Request->AddBody(jsonEmail.get());
#endif
    Request->Execute();
    int validCodes[] = {201};
    T::CheckForResponseError(validCodes, 1);
}

#endif

Here is the code for my mobile client:

//---------------------------------------------------------------------------

#include <fmx.h>
#pragma hdrstop

#define _KINVEY_

#include "KinveyFormUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TKinveyForm *KinveyForm;
//---------------------------------------------------------------------------
__fastcall TKinveyForm::TKinveyForm(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TKinveyForm::FormCreate(TObject *Sender)
{
	fApi = new TExtendApi<TKinveyApi, TKinveyApi::TLogin>(this);
	KinveyProvider1->UpdateApi(fApi);
}
//---------------------------------------------------------------------------

void __fastcall TKinveyForm::ButtonSignupClick(TObject *Sender)
{
	TKinveyApi::TLogin lLogin;
	EditUserName->Text = "";
	fApi->SignupUser(EditUserName->Text, EditPassword->Text, EditEmail->Text, lLogin);
	fApi->Login(lLogin);

	EditSessionToken->Text = lLogin.AuthToken;
	ShowMessage("Welcome" + lLogin.User.UserName);
}
//---------------------------------------------------------------------------

void __fastcall TKinveyForm::ButtonPasswordResetClick(TObject *Sender)
{
  fApi->PasswordReset(EditEmail->Text);
  ShowMessage("Message sent to " + EditEmail->Text);
}
//---------------------------------------------------------------------------

 



Below you see a screenshot of the email that I received after clicking on the ‘Reset Password via Email’ button inside my app:

After clicking on the automatically generated reset URL, you see a web based form where you can reset your password:


Upload Images to the Cloud using BaaS

Written by Sarina D on . Posted in CLOUD

In RAD Studio, we integrate with leading Backend as a Service (BaaS) providers to add functionality and platform services to your applications. With BaaS, you get easy access to common services in the cloud without having to build or maintain the backend services yourself. This includes support for being able to upload images to your BaaS account using RAD Studio.

 

This demo consists of the following functionality:

  1. Load an image from the gallery
  2. Upload the image to your Parse.com or Kinvey.com account (you will need to sign up for an account)
  3. Display the image URL in an Edit control
  4. Download the uploaded image and display it in your app

 

Drop the following BaaS components onto your form:

  • TBackendFiles
  • TParseProvider or TKinveyProvider, connected to TBackendFiles
To be able to select images from the photo album on your device using either the 'Access Gallery' button or by clicking on the TImage, use the built-in action (TActionList). The TakePhotoFromLibrary action allows you to access an image from the library and then execute that action again on button click. In addition, the URL of my image location is assigned to an Edit control after you upload the image to Parse or Kinvey. The last step is to set up an on-click event to download the image using the provided URL and then assign it to a TImage.
 
 
The user interface of my application consists of a toolbar with a parented TLabel for the title, a TListbox with several listbox items and two TListbox Groupheaders for displaying the titles.
  

Here is the C++ for the application:

//---------------------------------------------------------------------------

#include <fmx.h>
#pragma hdrstop

#include "ImageUploadBaaS_C.h"
#include <memory>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm6 *Form6;
//---------------------------------------------------------------------------
__fastcall TForm6::TForm6(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
TStream * __fastcall TForm6::SaveImage(void)
{
	TMemoryStream  * _return = new TMemoryStream();
	try
    {
		Image1->Bitmap->SaveToStream(_return);
	}
	 catch(...)
	{
		delete _return;
		_return = NULL;
		throw;
	}
	return _return;
}
//---------------------------------------------------------------------------
void __fastcall TForm6::DownloadImage(const String &AUrl)
{
	std::auto_ptr<TMemoryStream> lStream(new TMemoryStream());
	Rest::Client::TDownloadURL::DownloadRawBytes(AUrl, lStream.get());
	Image2->Bitmap->LoadFromStream(lStream.get());

}
//---------------------------------------------------------------------------
void __fastcall TForm6::btnUploadImageClick(TObject *Sender)
{
	std::auto_ptr<TStream> lStream(this->SaveImage());
	TBackendEntityValue AFile;
	BackendFiles1->Files->UploadFile("mypicture3.png", lStream.get(), "image/png" , AFile);
	ShowMessage("Image has been uploaded");
	Edit1->Text = AFile.DownloadURL;
}
//---------------------------------------------------------------------------
void __fastcall TForm6::Image1Click(TObject *Sender)
{
	TakePhotoFromLibraryAction1->ExecuteTarget(btnAccessGallery);
}
//---------------------------------------------------------------------------

void __fastcall TForm6::Image2Click(TObject *Sender)
{
	DownloadImage(Edit1->Text);
}
//---------------------------------------------------------------------------

void __fastcall TForm6::btnDownloadImageClick(TObject *Sender)
{
	DownloadImage(Edit1->Text);
}
//---------------------------------------------------------------------------
void __fastcall TForm6::TakePhotoFromLibraryAction1DidFinishTaking(TBitmap *Image)

{
	Image1->Bitmap->Assign(Image);
}
//---------------------------------------------------------------------------

 


Adding user account creation to your BaaS enabled apps

Written by Sarina D on . Posted in CLOUD

Our BaaS support in Appmethod includes components for both Kinvey and Parse. Part of our component pack is the TBackendUsers component which is designed to be hooked into either the ParseProvider or KinveyProvider component.

My sample application that I am building as part of this tutorial will allow me to create a user account on either Kinvey.com or Parse.com, with a defined username and password. If the account creation was successful, a message dialog will be shown. If the username already exists inside my BaaS account, it will automatically return a message, telling me to choose a different username. 

UI specs:

I placed a TToolbar onto my form, with a TLabel parented to it that is aligned to Center with a Stylelookup property of ‘toollabel’.

I also placed a TListbox onto my form with one Listboxitem that contains 2 TEdits (one for the username, one for the password) and a TSpeedbutton (you can also use a TButton).

For the Password edit, you can check the ‘Password’ property, but I am leaving it unchecked for demo purposes.

The Listbox Groupingkind property is set to Grouped and the Stylelookup property is set to ‘transparentlistboxstyle’. The Listbox is aligned to Center with a Bottom Margin of 100, and a Top Margin of 30.

The Stylebook that I dropped onto my form has the AndroidJet style assigned to it. I also changed the font color to green in the TextSettings property.

BaaS components:

Place either a TParseProvider or TKinveyProvider component onto your form and enter your credentials. You will need to go to Parse.com or Kinvey.com to sign up for an account.

Next, add a TBackendUsers component and set the provider to ParseProvider1 or KinveyProvider1, depending on the BaaS provider that you have selected for your project.

My last step was to setup the on-click event that is fired when the user clicks on ‘Create’ to sign up for the account.

C++ Code:

void __fastcall TForm1::btnCreateAccountClick(TObject *Sender)
{
 TBackendEntityValue entity;
 BackendUsers1->Users->SignupUser(Username->Text, Password->Text, NULL, entity);
 ShowMessage("Account created");
}

Object Pascal Code:

procedure TAccountSignup.btnCreateAcctClick(Sender: TObject);

var

ACreatedObject: TBackendEntityValue;

begin

BackEndUsers1.Users.SignupUser(Username.Text, Password.Text, nil, ACreatedObject);

ShowMessage(’Account created’);

end;

 

Below are some screenshots of my app in action:


Leveraging Backend Storage in your Appmethod apps

Written by Sarina D on . Posted in CLOUD

One of the Appmethod features I wanted to highlight is our BaaS support. BaaS stands for Backend as a Service, and in Appmethod, we integrate with leading Backend as a Service providers to add functionality and platform services to your mobile applications. This includes out of the box support for Kinvey and Parse. With BaaS, you get easy access to common services in the cloud without having to build or maintain the backend services yourself.

Here is a quick summary of the features you get with our BaaS integration:

  • Use push notifications to engage your users on any device or platform
  • Access data and object storage in the cloud
  • User authentication
  • Builds on the REST client support introduced in XE5
  • Built-in support for Kinvey and Parse with a common API component set

This tutorial show you how to use the KinveyProvider component for querying data that lives in a data collection in the cloud using our BackendQuery component.

First, I signed up for an account on Kinvey.com. While this demo uses Kinvey, you could also use the ParseProvider component. Once you sign up for the account, you will get an app key, master secret and app secret that you will need to enter for the KinveyProvider component. You will also need a BackendQuery, RestResponseDataSetAdapter and FDMemTable component.  BaaS requires Open SSL which means that you will need to get the necessary library files onto your file system before deploying your application.

Before hooking the RestResponseDataSetAdapter component into FDMemTable and BackendQuery, you will need to setup a new data collection since this demo consumes existing data that lives in the cloud. After you have created a new data collection, you will need to add rows and columns and add some data.

Next, set your properties as shown in the two screenshots below, then execute your BackendQuery request, by right-clicking the component.

My application consists of a TTabcontrol with 2 tabs that have a master-detail relationship. The ListView on Tab1 (Master) is bound into FDMemTable, and my toolbar label and memo on Tab2 (Detail) are also bound into FDMemTable. Binding TListView’s Sync property into FDMemTable’s * property ensures that the data stays in sync.

 

C++ Code:

void __fastcall TForm3::BackClick(TObject *Sender)

{

TabControl1->ActiveTab = master;

}

//—————————————————————————

void __fastcall TForm3::ListView1ChangeRepainted(TObject *Sender)

{

TabControl1->ActiveTab = detail;

}

//—————————————————————————

void __fastcall TForm3::FormCreate(TObject *Sender)

{

BackendQuery1->Execute();

}

Object Pascal Code:

procedure TForm3.BackClick(Sender: TObject);

begin

TabControl1.ActiveTab :=  master;

end;

procedure TForm3.FormCreate(Sender: TObject);

begin

BackendQuery1.Execute;

end;

procedure TForm3.ListView1ChangeRepainted(Sender: TObject);

begin

TabControl1.ActiveTab := detail;

end;


Feeling the Beat with REST

Written by Sarina D on . Posted in CLOUD

Being a big music fan, I was really excited to try out the Beats Music API. Not too long ago, Beats introduced a music subscription service and opened up their API to developers. I decided to create a fun sample that allows you to search for an artist by name and then return the list of available audio tracks for that particular artist.

This example requires an SSL encrypted connection to access the API. For Windows and iOS, this means you will need to install/include the SSL libraries. For Android, that is not necessary. More info on that topic can be found here.

This application consists of a tab control that is aligned to the client, containing two tab items and a toolbar with the title of the application parented to each of the 2 tab items. Tab1 contains several graphics for the design of the application and a top aligned toolbar with the name of the application.

Tab2 includes a client aligned ListView that displays all the audio tracks that are returned based on the query.

The search bar is just a bitmap (since I was going for a specific look) with a parented TEdit. The Search button is part of the bitmap, so I just used a TRectangle with no fill or stroke color to create a clickable masked area over the Search button part of the graphic. For TEdit, I right-clicked on the component at design time and selected ‘Add Item -> TClearEditButton’. This added the ‘x’ for clearing the input field. Alternately, you could have also used the TClearingEdit component instead of the TEdit component.

You will need the following Appmethod components to access the Beats Audio REST API and use it in your application:

  • RestClient
  • RestResponse
  • RestResponseAdapter
  • RestRequest
  • FDMemTable

You will also need to sign up for a developer account to get the required developer key (https://developer.beatsmusic.com/member/register).

I defined the following parameters:

For the display of the list on the second tab, I selected the ListItemRightDetail option. This provides me with 2 bindable members (Item.Text and Item.Detail) in the LiveBindings Designer.

I created the following bindings via the LiveBindings Designer (View->LiveBindings Designer).

This app only required a couple lines of code. When we first create the form, we want to execute the REST request:

procedure TForm1.FormCreate(Sender: TObject);

begin

RestRequest1.Execute;

end;

When the user clicks the Rectangle (the mask over the ‘Search’ bitmap), we need to change the tab (navigate to the second tab), and then also execute the REST request:

procedure TForm1.Rectangle1Click(Sender: TObject);

begin

TabControl1.ActiveTab := TabItem2;

RestRequest1.Execute;

end;

We also want the user to be able to leverage the back button on Android to navigate from the second tab back to the first tab which includes our search bar:

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;

var KeyChar: Char; Shift: TShiftState);

begin

if Key = vkHardwareBack then

begin

if TabControl1.ActiveTab = TabItem2 then

begin

TabControl1.ActiveTab := TabItem1;

Key := 0;

end;

end;

end;

 

Here are some screenshots of the running app:

 


Accessing data on Parse.com using the REST framework in Appmethod

Written by Sarina D on . Posted in CLOUD

The Appmethod REST Library is a framework for accessing REST-based web services (REST stands for Representational State Transfer). The library is available for all platforms that are supported by Object Pascal.

The framework focuses on JSON as the representation format.

I thought I would create a tutorial that shows you how to access and retrieve data you have stored in a data collection on Parse.com. For Parse.com's REST API documentation, click here.

 

On Parse.com, I signed up for a new account and selected a name for my application. I then created a class called 'GameScore'. By default, Parse creates several fields for you, including createdAt, updatedAt and objectId. For my games sample application, I decided to add 2 more columns for my GameScore collection inside my Parse.com account. The first column was named 'PlayerName' with a String type and the second column was named 'Score' with a Number type. After creating the column, I added some sample data, i.e. PlayerName = Scott Mitchell and Score = 100; 

Here is what I saw inside my Parse.com account:

 

 

Inside Appmethod, I went to File->New Mobile Application->Blank Application. 

For the UI portion of my application, I dropped a TListView onto my form and set the alignment to alClient (you can access the ListView via the tool palette). I also placed a TToolbar onto my form with a parented TLabel (which displays the application title). TToolbar was aligned to the top, and the TLabel was aligned to alContents with the TextAlign property set to alCenter.

For TListView, I set the ItemAppearance to ListItemRightDetail. This exposes 2 bindable members (Text item and detail item) for me in the LiveBindings Designer. The LiveBindings Designer can be accessed via the View menu.

 

Next, we need to drop the REST components onto our form. For that, we need the following components:

  • TRestRequest
  • TRestResponse
  • TRestResponseAdapter
  • TRestClient
  • TFDMemTable

For TRestClient, I set the Base URL to:

https://api.parse.com/1/classes/GameScore/YourObjectIDgoeshere

 Next, we need to define our parameters:

Next, define your parameters as shown in the screenshot below. To add a new parameter, click on the yellow document icon. The IDs are found inside your Parse.com account under the 'App keys' tab:

You can leave the value for Score and PlayerName blank since we will retrieve that data from the server. 

Now, let's right-click onto the FDMemTable component, select Fields Editor and then right-click inside the Fields Editor to add the data fields. On RESTResponseDataSetAdapter1, set the Dataset property to FDMemTable1. 

 

Now, let's bind our Item.Text property to PlayerName and Item.Detail to Score:

 

You will also need to execute the Rest request at runtime:

procedure TForm2.FormCreate(Sender: TObject);
begin
  RestRequest1.Execute;
end;

This example requires an SSL encrypted connection to access the api. For Windows and iOS, this means you will need to install/include the SSL libraries. For Android, that is not necessary. More info on that topic can be found here. 


Find the best surf spots using REST

Written by Sarina D on . Posted in CLOUD

Appmethod includes a range of code snippets and sample applications that are designed to help you get started building applications quickly.

SurfSpot Finder is a master/detail sample application that is included with Appmethod and shows you how to integrate REST services in your application by using the Spitcast API.

Surfspot Finder


The application consists of a TTabcontrol with three invisible tabs (Tabcontrol tpPosition = tpNone).
Each tab item has a toolbar with a TLabel parented to it to display the title of each tab.
Tab1 includes a TListView that is aligned to the client. For TListview, SearchVisible and
SearchAlwaysOnTop are set to True in the Object Inspector to allow for list filtering. Tab1 also has a TSpeedButton parented to it for accessing the Favorites list.
Tab2 includes a TListBox with 3 listbox items, displaying the longitude, latitude and county name of the selected surf spot. It also includes a bottom aligned TWebBrowser component for displaying the location on a map.
To use the built-in slide transition action for transitioning between tabs, a TActionList component has been added
to the form and the ChangeTabAction has been assigned to the back button.
When clicking the plus icon, the current surf spot gets saved to a text file and added to the ListBox on the Favorites tab (Tab3).

RESTRequest1’s Response property has been set to api/spot/all and RESTClient1’s BaseURL to http://api.spitcast.com
A TRestReponse component has been added to the form.
RESTRequest1’s Response property has been set to RESTResponse1. A TRestReponseDataSetAdapter was also placed onto the form and the Response field was set to RESTResponse1. Next, a TFDMemTable component was placed onto the form.
To execute the request, right-click on RESTRequest1 and select ‘Execute’.  Set TRESTResponseDataSetAdapter’s Dataset field to FDMemTable1. Then, right-click on FDMemTable, select ‘Fields Editor’, right-click inside the Fields Editor and select ‘Add Fields’. You should now see 5 available fields, including ‘county_name’, ‘latitude’, ‘longitude’, ’spot_id’ and ’spot_name’.

Via the LiveBindings Designer (View->LiveBindings Designer), bind spot_name to Item.Text and Sync to * by dragging a line between the two components.


To data bind to each of the Listbox items, click on the … for each listbox item in the LiveBindings Designer. When the ‘Bindable Members’ dialog appears, select the ItemData.Text checkbox. This now exposes a bindable member.

To show data at Design Time, right-click on RestRequest1 and select 'Execute'.

For additional information on how to use the REST components, please visit:

http://docwiki.appmethod.com/appmethod/1.13/topics/en/REST_Client_Library


Third Party Notice:
Public distribution of Spitcast API content must acknowledge Spitcast as the content source, and provide a link to Spitcast.com.
The Spitcast API is available for non-commercial use. Commercial use is possible by prior arrangement.
 


Planning a vacation? Do it mobile REST Client style!

Written by DavidI on . Posted in CLOUD

Planning a vacation? Like to know what the weather will be like at your chosen location? This article shows you how to build a mobile application using the REST Client Library components to choose a date, location and see current seven day weather forecast. You can start building the mobile vacation app using the File->New->Mobile Application to bring up the mobile application projects templates and choose the "Tabbed Application" template (click on the bitmaps in the article to see larger sized versions of all of this article's images). Since this app only need 3 tab items, you can delete one of the tabs.

The UI contains a TTabControl to contain three tabs for Weather, Browser and Settings. The app uses TGeocoder to get the latitude and longitude for an address. The app uses TWebBrowser to use Google Maps to display my vacation spot. I use TCalendarEdit to select the vacation date using the native date picker for iOS. Finally, the app uses the REST Client library components to access the WeatherBug weather forecast JSON api to display the next seven days of weather.

Here are the three TabItems in my mobile application:

The first thing the code does, using the form's OnCreate event, is initialize some variables, set up the Geocoder and load the WeatherBug API key from an INI file. I used the Project | Deployment menu to add the "weather.ini" file to my deployment and place it in the "StartUp\Documents" folder for iOS and in ".\assets\internal" for Android. [note: I place the INI file in the "c:\temp" folder on Windows - see the code for the OnCreate event handler]. Here is the INI file (minus my WeatherBug API key - you can get your own key by following the steps at http://developer.weatherbug.com/page):

weatherbug.ini:

[WeatherBug]
APIKey=xxxxx

Here is the Object Pascal code for the form's OnCreate event handler :

procedure TForm5.FormCreate(Sender: TObject);
var
   Ini: TIniFile;
begin
  // set up for Geocode
  FGeocoder := TGeocoder.Current.Create;
  FGeocoder.OnGeocode := OnGeocodeEvent;
  VacationTabControl.ActiveTab := WeatherTabItem;
  FoundLatitude := 0.0;
  FoundLongitude := 0.0;
  FoundAddrLatLong := false;
  RefreshButton.Visible := false;
  // read WeatherBug API Key from INI file
  {$IF DEFINED(IOS) or DEFINED(ANDROID) or DEFINED(MACOS)}
  Ini := TIniFile.Create(TPath.GetDocumentsPath + PathDelim + 'weather.ini');
  {$ELSE}
  Ini := TIniFile.Create('c:\temp\weather.ini');
  {$ENDIF}
  APIKeyString := Ini.ReadString('WeatherBug','APIKey','');
end;

The following bitmap shows the Project | Deployment entry for the "weather.ini" file showing it being deployed to the right folders on iOS (StartUp\Documents) and Android (.\assets\internal).

On the Settings TabItem, you can select your vacation date and address. When the address is changed, the OnChange event handler fires, stores the address in the TCivicAddress class and calls Geocode to get the new Latitude and Longitude. TGeocoder also has a GeocodeReverse method and OnGeocodeReverse event that takes latitude/longitude and returns TCivicAddress information. You can find more information about Geocoding and ReverseGeocoding on the Appmethod DocWiki. There is also an Object Pascal Mobile Tutorial: Using Location Sensors (iOS and Android) on the Appmethod DocWiki.

Here is the Object Pascal code for the AddressEditChange event.

procedure TForm5.AddressEditChange(Sender: TObject);
begin
  // Address changed - get Latitude/Longitude via GeoCoding
  RefreshButton.Visible := false;
  // use address to find Latitude and Longitude
  lAddress := TCivicAddress.Create;
  try
    lAddress.Address := AddressEdit.Text;
    FGeocoder.Geocode(lAddress);
  finally
    lAddress.Free;
  end;
end;

Geocode is called with the CivicAddress and when the geocoding completes, the OnGeocodeEvent fires. The parameter for the OnGeocodeEvent handler contains the coordinate array with the latitude and longitude. If the address is found and returns the coordinates, then I display them on the settings page and also call the Navigate method of the TWebBrowser to load a Google Map on the Browser TabItem.

Here is the Object Pascal code for the OnGeocodeEvent:

procedure TForm5.OnGeocodeEvent(const Coords: TArray);
begin
  if Length(Coords) > 0 then begin
    FoundLatitude := Coords[0].Latitude;
    FoundLongitude := Coords[0].Longitude;
    FoundAddrLatLong := true;
    LatLongLabel.Text :=
      Format('%3.5f/%3.5f',[Coords[0].Latitude, Coords[0].Longitude]);
    {$IF DEFINED(IOS) or DEFINED(ANDROID)}
    FormatSettings.DecimalSeparator := '.';
    WebBrowser1.Navigate(Format(LGoogleMapsURL, [FoundLatitude.ToString, FoundLongitude.ToString]));
    {$ENDIF}
    RefreshButton.Visible := true;
  end
  else begin
    FoundAddrLatLong := false;
    LatLongLabel.Text := 'Address not Found!'
  end;
end;

To finish the coding, my app has a TActionList component and I created an action, MyAction. The action executes when the RefreshButton is clicked. The RESTRequest is executed to call the WeatherBug weather REST GetForecast API and the RESTResponse gets the JSON result. The RESTRequestDataSetAdapter converts the returned JSON and populates the FDMemTable with the 7 days of weather forecast. The code fills in the WeatherListBox by iterating through the FDmemTable rows. Here are bitmaps of the REST Client components and their properties in the Object Inspector. I've circled in red the properties most used to process the API call and return the results to the FDMemTable.

Each ListBox item contains the high and low temperatures and the weather description for each day.

Here is the Object Pascal code for MyAction:

procedure TForm5.MyActionExecute(Sender: TObject);
var
  MyListBoxItem : TListBoxItem;
begin
  // days to vacation
  CountdownLabel.Text :=
    'Days to Vacation: '
    + IntToStr(DaysBetween(
        Now(),
        CalendarEdit1.Date)
      )
  ;

  if FoundAddrLatLong then begin

    // uses WeatherBug REST API
    // http://developer.weatherbug.com/docs/read/WeatherBug_Rest_XML_API
    // update RESTRequest Resource property
    // with latitude, longitude and API key
    RESTRequest1.Resource :=
      'REST/Direct/GetForecast.ashx?'
      + 'la='+FoundLatitude.ToString
      + '&'
      + 'lo='+FoundLongitude.ToString
      + '&ht=t&ht=i&ht=d&'
      + 'api_key='+APIKeyString
    ;

    // get weather temperatures
    RestRequest1.Execute;

    // Populate listbox with temperatures for next 7 days
    WeatherListBox.Items.Clear;
    WeatherListBox.BeginUpdate;
    FDMemTable1.First;
    while not FDMemTable1.Eof do begin
// TODO: get day and night icons for condition codes // For now just display strings MyListBoxItem := TListBoxItem.Create(WeatherListBox); MyListBoxItem.Text := copy(FDMemTable1.FieldByName('dayTitle').AsString,1,3) + ' Hi: ' + FDMemTable1.FieldByName('high').AsString + ' Lo: ' + FDMemTable1.FieldByName('low').AsString + ' ' + FDMemTable1.FieldByName('dayDesc').AsString ; MyListBoxItem.TextAlign := TTextAlign.taCenter; WeatherListBox.AddObject(MyListBoxItem); FDMemTable1.Next end; WeatherListBox.EndUpdate end end;

That's all of the code that I needed to write. For completeness, here is the form's declaration showing the components used and the privately declared variables and the OnGeoCodeEvent that are used throughout the application:

  TForm5 = class(TForm)
    ToolBar1: TToolBar;
    CountdownLabel: TLabel;
    Layout1: TLayout;
    WeatherListBox: TListBox;
    RefreshButton: TSpeedButton;
    ActionList1: TActionList;
    MyAction: TAction;
    RESTClient1: TRESTClient;
    RESTRequest1: TRESTRequest;
    RESTResponse1: TRESTResponse;
    BindingsList1: TBindingsList;
    RESTResponseDataSetAdapter1: TRESTResponseDataSetAdapter;
    BindSourceDB1: TBindSourceDB;
    LinkFillControlToField1: TLinkFillControlToField;
    ClientDataSet1: TClientDataSet;
    VacationTabControl: TTabControl;
    WeatherTabItem: TTabItem;
    SettingsTabItem: TTabItem;
    ListBox1: TListBox;
    AddressListBoxItem: TListBoxItem;
    LatLongListBoxItem: TListBoxItem;
    AddressEdit: TEdit;
    WebBrowser1: TWebBrowser;
    DateListBoxItem: TListBoxItem;
    CalendarEdit1: TCalendarEdit;
    LatLongLabel: TLabel;
    BrowserTabItem: TTabItem;
    procedure RefreshButtonClick(Sender: TObject);
    procedure MyActionExecute(Sender: TObject);
    procedure AddressEditChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FoundAddrLatLong : boolean;  // if LatLong found using Address
    FoundLatitude : double;
    FoundLongitude : double;
    lAddress : TCivicAddress;
    APIKeyString : string;
    FGeocoder: TGeocoder;
    procedure OnGeocodeEvent(const Coords: TArray<TLocationCoord2D>);
  public
    { Public declarations }
  end;

Here are the live screens for the Appmethod app running on my iPhone 4S. The mobile app also runs on my Samsung Galaxy S4. The screens show: 1) Settings tab with the DatePicker, 2) Settings tab with the Address and latitude/longitude returned from the Geocoder, 3) Browser tab showing the Google Map and 4) Weather tab showing 7 days of weather forecast via the WeatherBug JSON API.

If you want to use other weather related APIs, there is a good blog post on ProgrammableWeb, "5 Weather APIs – From WeatherBug to Weather Channel", at http://blog.programmableweb.com/2009/04/15/5-weather-apis-from-weatherbug-to-weather-channel/. There are additional weather API sites at World Weather Online and ForeCast.io.

Click on this download zip file link to download the complete Mobile Vacation Countdown source project.


Create a Multi-Device Application with Appmethod and Parse

Written by Sarina D on . Posted in CLOUD

At Embarcadero, we know and love developers and are building developer tools that allow you to create apps for multiple devices, faster, without limits. With our release of Appmethod, we are really excited to include integration with Parse for storage, push notifications, user management and more.

Appmethod is a development platform for building natively compiled, multi-device apps for Android, iOS, Windows, Mac OS X and wearables, like Google Glass, with a single codebase but without compromising the performance and user experience of the app. The Appmethod platform provides the tools you need to get amazing apps to market faster,  including a full featured IDE, visual design, natively compiled languages, direct platform API access, a rich component framework and Enterprise Mobility Services for a robust end-to-end solution from client to cloud to backend.

The Appmethod component framework includes a set of components for Parse that make it very easy for you to leverage Parse services in your Appmethod natively compiled, mobile apps. As you know, Parse services allow you focus on creating a great user experience with your application by taking the headache out of having to develop your own backend. With Appmethod and Parse, you have all the tools you need to deliver the best UX and performance on the frontend and a hassle free, robust backend.

In this tutorial, I am going to show you how to build a basic notes application using C++, Appmethod, and Parse, that builds and runs on Android and iOS with the exact same source code. This application queries the Parse storage service for data that was added via the Parse web browser interface. The app also allows you to add data to your data collection on Parse using the mobile application interface.

In Appmethod, we include both visual (i.e. buttons, toolbars, lists etc.) and non-visual components (database, REST, BaaS components etc.) that are accessible via the Tool Palette.


Step 1: Create the User Interface

Inside the Appmethod IDE, select to create a new blank mobile application.



Appmethod IDE with the FireMonkey Application Framework

This application consists of a tab control with three tabs. First, set up a master/detail relationship between the first and second tab, and then add a third tab for creating a new meeting notes record. The user interface includes three tabs, numerous buttons, toolbars and background graphics. Appmethod has built-in support for both native and custom user interface styling for all four supported platforms (iOS, Android, Windows and Mac).


Tab Control with three tabs, Master, Detail and Add with several visual and non-visual components

Tool Palette with drag-and-drop visual and non-visual components


Structure pane displaying the parent-child relationship between the UI components on the current form

Step 2: Setup and Connect to Parse Data Storage

To connect to Parse backend services, drop the following three components onto your form:

  • TParseProvider
  • TBackendStorage
  • TBackendQuery


On the ParseProvider component, I entered my ApplicationID, MasterKey and RestApiKey which you can find inside your Parse.com account.

On the BackEndStorage component, I selected ParseProvider1 as my connected component. This indicates that I want to use Parse for my app storage solution.

To set the BackendClassName on the BackendQuery component, I first defined my class name inside my Parse account.
Next, I clicked on + Create App…. and selected ‘My Meeting Notes’ as the name of my application.




I then clicked on the Data Browser tab and selected + New Class. I named my class ‘MeetingNotes1’.

 

I clicked on +Col and added two columns of datatype string, one called ‘MeetingType’, and another called ‘MeetingDiscussion’.  I also added several rows of meeting related data.



 

After setting up my data class and columns on Parse, I entered ‘MeetingNotes1’ as my BackendClassName on my ParseProvider1 component in the IDE. Next, I selected ‘Storage’ as my BaaS BackendService and ‘ParseProvider1’ as my BaaS provider.


                                            BaaS components

In order to display data, I also added an in-memory data table component and JSON response component to my form. The response component moves data from the JSON response into columns in the data table. 

 

Step 3: Visually Bind Data to User Interface Elements

The LiveBindings Designer in Appmethod makes it really easy to visually connect data sources to user interface elements. I bound the ListView Item.Text and Item.Detail properties into my data table by dragging lines between both end points. I also bound the ListView1 Sync property into the * field in my data table to keep the data synchronized as the user navigates between their master/detail views.

LiveBindings Designer showing UI components connected to Parse data storage


With Appmethod, you can see and scroll through live data at design time by right-clicking on the BackendQuery1 component to execute the query.



Step 4: Write C++ Code for Querying Existing Data and Navigating the UI

Once you have finished building the part of the application responsible for querying Parse’s data collection for existing data and the UI for displaying the data, the C++ code should look like this:

 

Step 5: Write C++ Code for Adding a New Meeting Record

Besides consuming existing data that I entered via Parse’s web interface, I also wanted to be able to add new meeting notes to my Parse data storage using my mobile application. On the Add tab, I added an Edit control for entering the meeting title and a Memo for adding the meeting notes.

Most components (including visual and non-visual components) have a set of events predefined, such on-click, on-change etc.

 
 

For the Save button, I set up the following on-click event:



Step 6: Select Target Platforms and Build

With Appmethod, you can target iOS, Android, Windows and Mac all from the same codebase.

In the Project Manager, you can select your Target platform by double-clicking on it. To build the application for the selected target, you just need to hit Run in the IDE.


Inside the IDE, you can also easily toggle between numerous iOS and Android devices to see what your application is going to look like on a specific form factor.



And there you have it – an app using Parse’s backend storage in just a few short steps! Below are some screenshots of the app in action, running on an iPod Touch with iOS 7, Nexus 4 phone with Android Kit Kat and Windows Desktop.

       
   

Step 7: Try It For Yourself

If you’re ready to build an app with Parse support, drop by www.appmethod.com to download the free edition of Appmethod. With our new free version of Appmethod, you can build Android phone apps for free.

To learn more about Appmethod, visit http://www.appmethod.com or follow us on Twitter @Appmethod.

 


Check out more tips and tricks in this development video: