Monday, April 20, 2015

How-To use AdMob Interstitial Ads with Delphi XE7-XE8

Hi guys,
as you know by using the Delphi Android JNI you can access to Native features provided by Android SDK. The RAD Studio installation includes also Google Mobile ADS library (Androidapi.JNI.AdMob unit), as built-in java library for Android.
So by using this unit we can use the new Interstitials Ads provided by AdMob.
First of all rember to set to true the AdMob Service ( Project -> Entitlement List -> AdMob Service )



Let's start with the code.
Create an instance of TJInterstitialAd, wich is present in Androidapi.JNI.AdMob.
  
    FInterstitial := TJInterstitialAd.JavaClass.init(MainActivity);
    FInterstitial.setAdUnitId(StringToJString('Your-Publisher-ID'));

For example you can put the previous code in the FormCreate event. Then you have to use this code to display an Interstitial Ad (on button-click event in my demo):

var
  LADRequestBuilder: JAdRequest_Builder;
  LadRequest: JAdRequest;
begin
  LADRequestBuilder := TJAdRequest_Builder.Create;
  LADRequestBuilder.addTestDevice(MainActivity.getDeviceID);
  LadRequest := LADRequestBuilder.build();
  LAdViewListener := TMyAdViewListener.Create(FInterStitial);
  CallInUIThread(
    procedure
    begin
      FInterStitial.setAdListener(TJAdListenerAdapter.JavaClass.init
        (LAdViewListener));
      FInterStitial.loadAd(LadRequest);
    end);
end;

I used the TJAdRequest_Builder to create a request and set my device like a test device (see AdMob guidelines).
I also created a custom AdViewListener to intercept the interstitial events:
  • onAdClosed;
  • onAdFailedToLoad(errorCode: Integer);
  • onAdLeftApplication;
  • onAdOpened;
  • onAdLoaded;
TJAdListenerAdapter adapts my Listener class to Interstitial AdListener, this because I created a custom class to support interstitial events and show effectively the Ad when it was loaded.

TMyAdViewListener = class(TJavaLocal, JIAdListener)
  private
    FAD: JInterstitialAd;
  public
    constructor Create(AAD: JInterstitialAd);
    procedure onAdClosed; cdecl;
    procedure onAdFailedToLoad(errorCode: Integer); cdecl;
    procedure onAdLeftApplication; cdecl;
    procedure onAdOpened; cdecl;
    procedure onAdLoaded; cdecl;
  end;

procedure TMyAdViewListener.onAdLoaded;
begin
  FAD.show;
end;

Here the screenshot of interstitial on my phone:


This code should works also on AppMethod.
You can find the demo in my GitHub repository.

Monday, January 19, 2015

RESTAdapter: a new amazing feature in Delphi MVC Framework

RESTAdapter is a new amazing feature of the famous Delphi MVCFramework (DMVCFramework for short). DMVCFramework (as you know) is a powerful framework for web solution in Delphi that respect the MVC pattern and reach RMM Level 3! Above there is a link to the site project (if you want more info about this wonderful framework). Ok, let's go ahead. What is RESTAdapter? RESTAdapter turn a Delphi Interface into your REST API. In practice you can declare an interface that represents your REST API and the RESTAdapter does all work for you. Below a mini guide on how it works:
  

  [Headers('User-Agent', 'RESTAdapter-Test')]
   IRESTAPIService = interface(IInvokable)
    ['{58B9FA23-92F4-4B8E-814B-05232F32A41F}']

    [RESTResource(HttpGet, '/persons')]
    [MapperListOf(TPerson)]
    function GetListPerson: TObjectList<tperson>;

    [RESTResource(HttpGet, '/persons/{personid}')]
    function GetPersonByID([Param('personid')] APersonID: integer): TPerson;

    [RESTResource(httpPOST, '/persons')]
    function SavePerson([Body] ABody: TPerson): TPerson;

  end;

The RestAdapter class generates an implementation of the IRESTAPIService
interface:

  
  RESTAdapter := TRESTAdapter<IRESTAPIService>.Create; 
  RESTAPIService := RESTAdapter.Build('localhost', 9999);
  Person := RESTAPIService.GetPersonByID(1);

Use RTTI Attributes to describe the REST request:
  • RESTResource: to describe URI and REST verb of resource
  • Headers: a key-value pair that represents a Header of HTTP request
  • MapperListOf: to specify the Object Type of the List
  • Param: to specify that a method parameter is a param of HTTP Request
  • Body: to specify that a method parameter is the body of HTTP Request
The TRESTAdapter class inherits from TVirtualInterface. TVirtualInterface doesn't behave like an ordinary class, each instance has an associated reference counter to automatically free itself. In practice there isn't need to free the RESTAdapter object.

In the DMVCFramework samples folder, in particularly "wincellarclientRESTAdapter" you can find a real work example. 

I hope you enjoy it! 

Thursday, October 9, 2014

Automate Save State Feature in Firemonkey

Hi!
One of the many exciting new features of Delphi XE7 is the Save State in Firemonkey.
The FireMonkey Save State feature allows you to save data describing the state of the application before it closes. The Save State data can be used to recover the state after the application is restarted.
This is a very cool feature but the way in which you save and restore the data is not so refined (for more info see this http://docwiki.embarcadero.com/RADStudio/XE7/en/FireMonkey_Save_State ).
What happen if I need to save 10,15 or more components? I need to specify the save and the restore for each one.
So I decided to write a class helper to automate this process!
Using JSON serialization all the components of type TFMXObject are saved. In particular is stored the Data property.

You can find the demo in my github repository .

This is a snippet of the demo

uses SaveStateHelper;

procedure TForm1.FormCreate(Sender: TObject);
begin
  LoadFormState;
end;

procedure TForm1.FormSaveState(Sender: TObject);
begin
  SaveFormState;
end;

I hope you enjoy it!!