How to receive notifications sent through CPDistributedNotificationCenter

The iOS AppSupport private infrastructure has a class called CPDistributedNotificationCenter , which appears to support a subset of the functions provided by NSDistributedNotificationCenter in OS X.

I am trying to use this class to send notifications from a background daemon so that several clients in other processes can receive these notifications and act on them. I understand that there are other options, including CPDistributedMessagingCenter or CFMessagePort , small low-level ports, or even darwin notify_post . I would prefer that the daemon does not know about clients, and I would like to be able to transmit data along with the notification, and notify_post does not allow this.

This is currently what I am doing in the daemon:

 CPDistributedNotificationCenter* center; center = [CPDistributedNotificationCenter centerNamed:@"com.yfrancis.notiftest"]; [center runServer]; [center postNotificationName:@"hello"]; 

And in the client:

 CPDistributedNotificationCenter* center; center = [CPDistributedNotificationCenter centerNamed:@"com.yfrancis.notiftest"]; [center startDeliveringNotificationsToMainThread]; NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; [nc addObserver:[Listener new] selector:@selector(gotNotification:) name:@"hello" object:nil]; 

where Listener is a simple class that implements the only gotNotification: method gotNotification:

Unfortunately, the client never receives a hello notification. If I replace the name argument in the addObserver call with nil , I see every notification sent to the client’s notification center, but hello is not one of them.

I got inspiration for my code by looking at disassembling SpringBoard and CPDistributedNotificationCenter . Notifications are sent via CPDistributedNotificationCenter deliverNotification:userInfo: which acts as a pad for NSNotificationCenter postNotificationName:object:userInfo:

What am I missing here?

+4
source share
1 answer

Figured it out. Before sending your notification, your daemon must wait for a notification indicating that the client has started listening. There is no lag, even if the daemon server starts in front of the client, registration is delayed. You cannot just start your server and immediately send notifications to listeners. The following works for me:

In the init server:

 self.center = [CPDistributedNotificationCenter centerNamed:@"com.yfrancis.notiftest"]; [self.center runServer]; // requires a runloop NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(clientEvent:) name:@"CPDistributedNotificationCenterClientDidStartListeningNotification" object:self.center]; 

And make sure that the following method is implemented on the server:

 - (void)clientEvent:(NSNotification*)notification { // you can now send notifications to the client that caused this event // and any other clients that were registered previously [self.center postNotificationName:@"hello!"]; { 

I registered this API on iPhoneDevWiki

+5
source

Source: https://habr.com/ru/post/1443844/


All Articles