?»??»?unit Apple.RemoteNotification; // A unit for installing remote (push) notifications into iOS applications // Call RegisterForRemoteNotifications to register your app for push notifications // The events should be self-explanatory // Modify any part of it to suit your needs interface uses Classes; type TRemoteNotificationType = (rnBadge = 1, rnSound = 2, rnAlert = 4, rnNewsstand = 8); TRemoteNotificationTypes = set of TRemoteNotificationType; TRemoteNotificationEvent = procedure(Sender: TObject; const Value: string) of object; TRemoteNotifications = class(TObject) private FDeviceToken: string; FOnReceive: TRemoteNotificationEvent; FOnRegisterFail: TRemoteNotificationEvent; FOnRegisterSuccess: TNotifyEvent; procedure AddRemoteNotificationMethods; procedure DoReceive(const Msg: string); procedure DoRegisterFail(const Error: string); procedure DoRegisterSuccess(const DeviceToken: string); public procedure RegisterForRemoteNotifications(Types: TRemoteNotificationTypes); procedure UnregisterForRemoteNotifications; property DeviceToken: string read FDeviceToken; property OnReceive: TRemoteNotificationEvent read FOnReceive write FOnReceive; property OnRegisterFail: TRemoteNotificationEvent read FOnRegisterFail write FOnRegisterFail; property OnRegisterSuccess: TNotifyEvent read FOnRegisterSuccess write FOnRegisterSuccess; end; var RemoteNotifications: TRemoteNotifications; implementation uses SysUtils, Macapi.ObjCRuntime, iOSapi.Foundation, iOSapi.CocoaTypes, iOSapi.UIKit; function SharedApplication: UIApplication; begin Result := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication); end; procedure didReceiveRemoteNotification(self, _cmd, app, remoteNotif: Pointer {NSDictionary*}); cdecl; begin RemoteNotifications.DoReceive(TNSDictionary.Wrap(remoteNotif).description.UTF8String); end; procedure didFailToRegisterForRemoteNotificationsWithError(self, _cmd, app, error : Pointer {NSError*}); cdecl; begin RemoteNotifications.DoRegisterFail(TNSError.Wrap(error).userInfo.description.UTF8String); end; procedure didRegisterForRemoteNotificationsWithDeviceToken(self, _cmd, app, deviceToken: Pointer {NSData*}); cdecl; begin RemoteNotifications.DoRegisterSuccess(TNSData.Wrap(deviceToken).description.UTF8String); end; { TRemoteNotification } procedure TRemoteNotifications.AddRemoteNotificationMethods; var AppDelegate: Pointer; begin // Add methods that were left out in FMX.Platform.iOS AppDelegate := objc_getClass('DelphiAppDelegate'); // this presumes that this classname will not change class_addMethod(AppDelegate, sel_getUid('application:didReceiveRemoteNotification:'), @didReceiveRemoteNotification, 'v@:@@'); class_addMethod(AppDelegate, sel_getUid('application:didRegisterForRemoteNotificationsWithDeviceToken:'), @didRegisterForRemoteNotificationsWithDeviceToken, 'v@:@@'); class_addMethod(AppDelegate, sel_getUid('application:didFailToRegisterForRemoteNotificationsWithError:'), @didFailToRegisterForRemoteNotificationsWithError, 'v@:@@'); end; procedure TRemoteNotifications.RegisterForRemoteNotifications(Types: TRemoteNotificationTypes); var NTypes : NSUInteger; RN: TRemoteNotificationType; begin AddRemoteNotificationMethods; NTypes := 0; for RN := Low(TRemoteNotificationType) to High(TRemoteNotificationType) do if RN in Types then NTypes := NTypes or Ord(RN); SharedApplication.registerForRemoteNotificationTypes(Pointer(NTypes)); end; procedure TRemoteNotifications.UnregisterForRemoteNotifications; begin SharedApplication.unregisterForRemoteNotifications; end; procedure TRemoteNotifications.DoReceive(const Msg: string); begin if Assigned(FOnReceive) then FOnReceive(Self, Msg); end; procedure TRemoteNotifications.DoRegisterFail(const Error: string); begin if Assigned(FOnRegisterFail) then FOnRegisterFail(Self, Error); end; procedure TRemoteNotifications.DoRegisterSuccess(const DeviceToken: string); begin FDeviceToken := StringReplace(DeviceToken, '<', '', [rfReplaceAll]); FDeviceToken := StringReplace(FDeviceToken, '>', '', [rfReplaceAll]); FDeviceToken := StringReplace(FDeviceToken, ' ', '', [rfReplaceAll]); end; initialization RemoteNotifications := TRemoteNotifications.Create; finalization RemoteNotifications.Free; end.