Delphi XE4 iOS. Flexibilizando el Soporte a Push Notification. Solucíon mas elegante!

Sirva como la continuación del soporte a «Apple Push Notification«. Realize los siguientes cambios a la unidad «FMX.Platform.iOS»

  • La clase TApplicationDelegate se colocó en la seccion interface, se modificaron los nombres de los métodos para evitar conflictos de nombres y adicionalmente se colocaron virtuales, con la finalidad de poder ser sobreescritos a través de la herencia.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Disponibilizar la clase ApplicationDelegate. Colocandola en interface.
  TApplicationDelegate = class
  private
    FMainWindow: TFMXWindow;
  public
    procedure didChangeStatusBarFrame(Sender: UIApplication; didChangeStatusBarFrame: CGRect); cdecl;
    procedure didChangeStatusBarOrientation(Sender: UIApplication; didChangeStatusBarOrientation: UIInterfaceOrientation); cdecl;
    // Colocado virtual, para ser sobreescrito en nuestra clase ApplicacionDelegate
    procedure didFailToRegisterForRemoteNotificationsWithError(Sender: UIApplication; didFailToRegisterForRemoteNotificationsWithError: NSError);virtual; cdecl;
    // Colocado virtual, para ser sobreescrito en nuestra clase ApplicacionDelegate
    function didFinishLaunchingWithOptions(Sender: UIApplication; didFinishLaunchingWithOptions: NSDictionary): Boolean; virtual; cdecl;
    procedure didReceiveLocalNotification(Sender: UIApplication; didReceiveLocalNotification: UILocalNotification); cdecl;
    // Colocado virtual, para ser sobreescrito en nuestra clase ApplicacionDelegate
    procedure didReceiveRemoteNotification(Sender: UIApplication; didReceiveRemoteNotification: NSDictionary); virtual; cdecl;
    // Colocado virtual, para ser sobreescrito en nuestra clase ApplicacionDelegate
    procedure didRegisterForRemoteNotificationsWithDeviceToken(Sender: UIApplication; didRegisterForRemoteNotificationsWithDeviceToken: NSData); virtual; cdecl;
    function handleOpenURL(Sender: UIApplication; handleOpenURL: NSURL): Boolean; cdecl;
    function openURL(Sender: UIApplication; openURL: NSURL; sourceApplication: NSString; annotation: Pointer): Boolean; cdecl;
    procedure willChangeStatusBarFrame(Sender: UIApplication; willChangeStatusBarFrame: CGRect); cdecl;
    procedure willChangeStatusBarOrientation(const Sender: UIApplication; const willChangeStatusBarOrientation: UIInterfaceOrientation; const duration: NSTimeInterval); cdecl;
    procedure didBecomeActive(const Sender: UIApplication); cdecl;
    procedure didEnterBackground(const Sender: UIApplication); cdecl;
    procedure applicationDidFinishLaunching(Sender: UIApplication); cdecl;
    procedure didReceiveMemoryWarning(Sender: UIApplication); cdecl;
    procedure protectedDataDidBecomeAvailable(Sender: UIApplication); cdecl;
    procedure protectedDataWillBecomeUnavailable(Sender: UIApplication); cdecl;
    procedure significantTimeChange(Sender: UIApplication); cdecl;
    procedure willEnterForeground(Sender: UIApplication); cdecl;
    procedure willResignActive(Sender: UIApplication); cdecl;
    procedure willTerminate(Sender: UIApplication); cdecl;
    procedure setWindow(window: UIWindow); cdecl;
    function window: UIWindow; cdecl;
    property MainWindow: TFMXWindow read FMainWindow;
  end;
  • Se completaron los métodos necesarios para adicionarlos a la clase «DelphiAppDelegate‘.
980
981
982
983
984
985
986
{ Adicionado para el Soporte a las Notificaciones Remotas!! }
  class_addMethod(appDelegateClass, sel_getUid('application:didReceiveRemoteNotification:'),
    @didReceiveRemoteNotification, 'v@:@@');
  class_addMethod(appDelegateClass, sel_getUid('application:didRegisterForRemoteNotificationsWithDeviceToken:'),
    @didRegisterForRemoteNotificationsWithDeviceToken, 'v@:@@');
  class_addMethod(appDelegateClass, sel_getUid('application:didFailToRegisterForRemoteNotificationsWithError:'),
    @didFailToRegisterForRemoteNotificationsWithError, 'v@:@@');
  • Se adicionador métodos nuevos que sirven de Wrapper para invocar los métodos de la clase TApplicationDelegate.
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
procedure didReceiveRemoteNotification(self, _cmd, app, remoteNotif: Pointer{NSDictionary*}); cdecl;
begin
  PlatformCocoa.FAppDelegate.didReceiveRemoteNotification(TUIApplication.Wrap(application),
    TNSDictionary.Wrap(remoteNotif));
end;
 
procedure didFailToRegisterForRemoteNotificationsWithError(self, _cmd, app, error : Pointer{NSError*}); cdecl
begin
  PlatformCocoa.FAppDelegate.didFailToRegisterForRemoteNotificationsWithError(TUIApplication.Wrap(app),
    TNSError.Wrap(error));
end;
 
procedure didRegisterForRemoteNotificationsWithDeviceToken(self, _cmd, app, deviceToken: Pointer {NSData*}); cdecl;
begin
  PlatformCocoa.FAppDelegate.didRegisterForRemoteNotificationsWithDeviceToken(TUIApplication.Wrap(app),
    TNSData.Wrap(deviceToken));
end;
  • Se adicionó un procedimiento para asignar un nuevo delegate.
118
119
// Metodo para asignar nuestra propia Clase Delegate!!
procedure SetApplicationDelegate(const NewAppDelegate : TApplicationDelegate);
660
661
662
663
procedure SetApplicationDelegate(const NewAppDelegate : TApplicationDelegate);
begin
  PlatformCocoa.FAppDelegate := NewAppDelegate;
end;

Terminadas las modificación de la unidad «FMX.Platform.iOS«, se crea una unidad donde se demuestra el uso de la misma.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
unit ApplePushRemoteUnit;
 
interface
 
uses
  iOSapi.CocoaTypes, FMX.Platform.iOS, iOSapi.UIKit, iOSapi.Foundation;
 
type
  // Implementar mi propia Clase para controlar el ApplicationDelegate
  TMyApplicationDelegate = class(TApplicationDelegate)
  public
    // Necesario para Darle el Soporte a Notificaciones Remotas
    function didFinishLaunchingWithOptions(Sender: UIApplication; didFinishLaunchingWithOptions: NSDictionary): Boolean; override;cdecl;
    // Sobreescribiendo el metodo
    procedure didReceiveRemoteNotification(Sender: UIApplication; didReceiveRemoteNotification: NSDictionary);override;cdecl;
    // Sobreescribiendo el metodo
    procedure didRegisterForRemoteNotificationsWithDeviceToken(Sender: UIApplication; didRegisterForRemoteNotificationsWithDeviceToken: NSData); override;cdecl;
    // Sobreescribiendo el metodo
    procedure didFailToRegisterForRemoteNotificationsWithError(Sender: UIApplication; didFailToRegisterForRemoteNotificationsWithError: NSError);override;cdecl;
  end;
 
implementation
 
uses
  FMX.Dialogs, SysUtils, UMain;
 
var
  MyAppDelegate : TMyApplicationDelegate;
 
{ Limpiar todas las notificaciones de la Aplicacion!! }
procedure CleanAllNotifications;
begin
  TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication).setApplicationIconBadgeNumber(0);
  TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication).cancelAllLocalNotifications;
end;
 
{ TMyApplicationDelegate }
 
{ Es necesario sobreescribir este metodo para darle el soporte a las notiicaciones }
function TMyApplicationDelegate.didFinishLaunchingWithOptions(Sender: UIApplication;
  didFinishLaunchingWithOptions: NSDictionary): Boolean;
var
  ANotifTypes : NSUInteger;
begin
  ANotifTypes := (0 shl 1) or (1 shl 1) or (2 shl 1);
  // Asignar el soporte a las notificaciones remotas!!!
  TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication).registerForRemoteNotificationTypes(Addr(ANotifTypes));
  // Limpiar las Notificaciones!
  CleanAllNotifications;
  inherited;
end;
 
{ Este metodo se ejecuta y nos permite capturar la notificacion! }
procedure TMyApplicationDelegate.didReceiveRemoteNotification(Sender: UIApplication;
  didReceiveRemoteNotification: NSDictionary);
begin
  Form1.Label3.Text := didReceiveRemoteNotification.description.UTF8String;
//  ShowMessage(didReceiveRemoteNotification.description.UTF8String);
  // Limpiar las Notitificaciones
  CleanAllNotifications;
end;
 
{ Este metodo se ejecuta y nos permite obtener el deviceToken. }
procedure TMyApplicationDelegate.didRegisterForRemoteNotificationsWithDeviceToken(Sender: UIApplication;
  didRegisterForRemoteNotificationsWithDeviceToken: NSData);
begin
  Form1.Label3.Text := didRegisterForRemoteNotificationsWithDeviceToken.description.UTF8String;
//  ShowMessage(didRegisterForRemoteNotificationsWithDeviceToken.description.UTF8String);
end;
 
{ Permite capturar los errores! }
procedure TMyApplicationDelegate.didFailToRegisterForRemoteNotificationsWithError(Sender: UIApplication;
  didFailToRegisterForRemoteNotificationsWithError: NSError);
begin
  Form1.Label3.Text := didFailToRegisterForRemoteNotificationsWithError.userInfo.description.UTF8String;
//  ShowMessage(didFailToRegisterForRemoteNotificationsWithError.userInfo.description.UTF8String);
end;
 
initialization
  MyAppDelegate := TMyApplicationDelegate.Create;
  SetApplicationDelegate(MyAppDelegate);
 
end.

 

Esta entrada fue publicada en Apple iOS, Delphi, FireMonkey. Guarda el enlace permanente.

Deja una respuesta