Jump to content
Sign in to follow this  
Rollo62

[iOS] TNotificationCenter

Recommended Posts

Hi there,

I was trying to package the notifications in a more easy to handle function, to be set at runtime.
What I noticed was that the NotificationCenter doesn'T seem to work with this method (at least I checked iOS only):

FNotificationCenter := TNotificationCenter.Create( nil );
FNotificationCenter.OnReceiveLocalNotification := EvOnReceiveLocalNotification;

The internal methid shows a class constructor:

class constructor TCustomNotificationCenter.Create;
begin
{$IF defined(IOS) or defined(ANDROID)}
  // We need to create the NotificationCenter to register the external notification messages from the system in the app initialization
  TBaseNotificationCenter.InternalGetInstance;
{$ENDIF}
end;

But this seems never be called, neither the normal Create of the Notification center constructor.

 

constructor TBaseNotificationCenter.Create;
begin
  inherited;
  TMessageManager.DefaultManager.SubscribeToMessage(TMessage<TNotification>, DoReceiveLocalNotification);
end;


Maybe somebody knows how it would be possible to create the notification center via runtime safely ?
What works is if I pass the normal IDE component to my class, then it works correctly.
It seems to me that there are maybe special requirements on the sequence or timing of the creation, or maybe it needs an Owner to work correctly.


 

Edited by Rollo62
Typo

Share this post


Link to post

I just made some more tests.

I've tried to create a TNotificationCenter variable, created with Owner, like this:

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

procedure TForm1.Notification_Center_Create( AOwner: TComponent );
begin
    FNotificationCenter := TNotificationCenter.Create( AOwner );
    FNotificationCenter.OnReceiveLocalNotification := EvOnReceiveLocalNotification;
end;

! But on the Form I have NOT dropped any TNotificationCenter component.

 

  • OK: Creation works fine
  • OK: Sending local notification works fine
  • OK: When in background & pressing a notification, the app is shown
  • nOK: When in background & pressing a notification, EvOnReceiveLocalNotification is never fired.

With a second test, same app, the only difference is: I drop a TNotificationCenter component on the form

  • Just drop component
  • No further "uses" appear
  • Not touching this component at all: No Event handler, no method call, not changing properties

! Suddenly the same code from above magically works.

OK: When in background & pressing a notification, EvOnReceiveLocalNotification is fired as it should (before BecameActive).

 

It seems that somehow dropping the component on the form changes something, maybe creation order or registrations.
Perhaps somebody has a clue how I could get rid of the designtime component here ?

 

Edit: Another test

It also worked as expected without the owner:

FNotificationCenter := TNotificationCenter.Create( nil ); <-- Works also, when somewhere a TNotificationCenter was dropped

The only difference is that the component needs to be dropped on the main form, to get the event working.

Edited by Rollo62

Share this post


Link to post

I think I found the reason: It has to do with the Loaded function when components are created

procedure TNotificationCenterIOS.DidFormsLoad;
begin
  FIsApplicationLoaded := True;
  NotifyDelayedNotifications;
end;

procedure TNotificationCenterIOS.DoLoaded;
begin
  inherited;
  DidFormsLoad;
end;

procedure TCustomNotificationCenter.DoLoaded;
begin
  if Supported then
    FPlatformNotificationCenter.DoLoaded; //<-- This is never loaded when created during runtime
end;

I have to simulate the Loaded function, so below is the workaround that fixes the behaviour:

procedure TForm1.Notification_Center_Create( AOwner: TComponent );
begin
    FNotificationCenter := TNotificationCenter.Create( AOwner );
    FNotificationCenter.OnReceiveLocalNotification := EvOnReceiveLocalNotification;
    FNotificationCenter.Loaded;  //<-- this works and simulates the component "loaded" state
end;

 

I hope that it might be useful for somebody else too.
All this was not nice to find, because the libraries also couldn't be debugged in my setting, for some reason.
Usually I can debug all the included libraries.

 

Anyway, I can get back to more productive coding again :classic_smile:

 

  • Like 1

Share this post


Link to post

So, is this considered a bug? If so, have you reported it?

Share this post


Link to post

Not really, I would say.
TNotificationCenter is considered to be used in DesignTime only.

 

EMBT would respond to this issue as "by design" probably :classic_smile:

  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×