Search code examples
iosobjective-cstructnsnotificationcenternsnotification

NSNotificationCenter to post a C structure and retrieve it back from the notification callback function


I have a complex C structure and it's hard to convert this structure to NSDictionary one by one. How do I post this C structure via NSNotificationCenter and retrieve it back from the NSNotificationCenter callback function? Any suggestion will be appreciated, thanks!


Solution

  • Personally, I find it easiest to stuff the structure into an NSData and then send it as part of the notification. Here's the declaration of the sample structure used in the code that follows.

    typedef struct
    {
        int a;
        int b;
    }
        ImportantInformation;
    

    Here's the code to send the structure as part of a notification. The last part of the third line puts the NSData object into an NSDictionary and passes that dictionary as the userInfo. The key for the NSData in the dictionary is @ImportantInformation.

    ImportantInformation info = { 555, 321 };
    NSData *data = [NSData dataWithBytes:&info length:sizeof(info)];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ImportantChange" object:self userInfo:@{ @"ImportantInformation" : data }];
    

    Here's the code that adds an observer for the notification and defines the block that runs when the notification is received.

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    
    self.observer = [center addObserverForName:@"ImportantChange"
                                        object:nil
                                         queue:nil
    usingBlock:^(NSNotification *notif)
    {
        // this is the structure that we want to extract from the notification
        ImportantInformation info;   
    
        // extract the NSData object from the userInfo dictionary using key "ImportantInformation"
        NSData *data = notif.userInfo[@"ImportantInformation"];  
    
        // do some sanity checking
        if ( !data || data.length != sizeof(info) )
        {
            NSLog( @"Well, that didn't work" );
        }
        else
        {
            // finally, extract the structure from the NSData object
            [data getBytes:&info length:sizeof(info)];
    
            // print out the structure members to prove that we received that data that was sent
            NSLog( @"Received notification with ImportantInformation" );
            NSLog( @"   a=%d", info.a );
            NSLog( @"   a=%d", info.b );
        }
    }];
    

    Note: be sure to remove the observer at some point.

    [[NSNotificationCenter defaultCenter] removeObserver:self.observer];