What am I missing here? I'm just trying to send a simple notification from a modal view controller back to the view controller that launched it, but nothing gets received.
This is the code in the view controller that launches the modal segue:
- (IBAction) chooseSuperGroup:(UIButton *)sender {
NSLog(#"super group choice about to be made");
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(choiceReceived:)
name:#"selectionMade"
object:self];
}
- (void) choiceReceived: (NSNotification *) notification
{
NSLog(#"here");
if ([[notification name] isEqualToString:#"selectionMade"]) {
NSLog(#"received");
NSLog(#"%#", (NSString *)[notification userInfo]);
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name: #"selectionMade"
object:self];
}
Then, over in the modal view controller, this code executes when the user selects a cell from the table view:
NSDictionary *dict = [NSDictionary dictionaryWithObject:selection forKey:#"superGroup"];
NSLog(#"printing dictionary contents");
for (id key in dict) {
NSLog(#"key: %# object: %#", key, [dict objectForKey:key]);
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"selectionMade" object:self userInfo:dict];
My output looks like this:
Super group choice about to be made
printing dictionary contents
key: superGroup object: myChoice
So the choice is captured and added to a dictionary. But there is no evidence of any notification being received. This can't be that hard, but I'm not seeing my mistake. Can someone help me? Thanks!
Try using 'nil' instead of 'self'
// Add Observer
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(choiceReceived:) name:#"selectionMade" object:nil];
// Remove Observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name: #"selectionMade"
object:nil];
// Post Notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"selectionMade" object:nil userInfo:dict];
refer:https://stackoverflow.com/a/8188759/2449268
Related
I am building an cordova application that connects to a bluetooth reader. Everything is working find when the app is running (not minimized). I am able to read the bluetooth data. If I now minimize the app and then maximize it again (not sure if this is the right term) then I am not able to receive any data anymore. I do see the following in XCode:
2015-11-26 12:24:13.944 MyAppName[704:170849]
/SourceCache/ExternalAccessory/ExternalAccessory-288.20.7/EAAccessoryManager.m:__51-[EAAccessoryManager
_checkForConnectedAccessories]_block_invoke-631 ending background task
I have also tried to implement the accessoryDidConnect and accessoryDidDisconnect using the below code, but both functions never get called:
- (void) pluginInitialize
{
NSLog(#"init called");
[[NSNotificationCenter defaultCenter] addObserver:selfselector:#selector(accessoryDidConnect:)
name:EAAccessoryDidConnectNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(accessoryDidDisconnect:)
name:EAAccessoryDidDisconnectNotification object:nil];
}
-(void) accessoryDidConnect:(NSNotification *)notification
{
EAAccessory *connectedAccessory = [[notification userInfo] objectForKey:EAAccessoryKey];
NSLog(#"error :%#", connectedAccessory.protocolStrings);
// Only notify of change if the accessory added has valid protocol strings
if( connectedAccessory.protocolStrings.count != 0 )
{
_accessoryList = [[[EAAccessoryManager sharedAccessoryManager] connectedAccessories] mutableCopy];
}
NSLog(#"connected");
isDeviceLoaded=true;
}
- (void)accessoryDidDisconnect:(NSNotification *)notification
{
// EAAccessory *disconnectedAccessory = (EAAccessory *)[notification.userInfo objectForKey:#"EAAccessorySelectedKey"];
NSLog(#"disconnected");
_accessoryList = [[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]mutableCopy];
isDeviceLoaded=true;
}
The pluginInitialize function is called, but accessoryDidConnect or accessoryDidDisconnect is never called. How do I re-connect to the bluetooth reader?
I got it working. I was missing the following last line inside my plugin:
[[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications];
Here is the full method again:
- (void) pluginInitialize
{
NSLog(#"init called");
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(accessoryDidConnect:)
name:EAAccessoryDidConnectNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(accessoryDidDisconnect:)
name:EAAccessoryDidDisconnectNotification
object:nil];
[[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications];
}
Please tell me how to send the appdelegate to another viewcontroller using NSdoctionary and receive it on the new view controller and show it.
-(void)application:(UIApplication*)application didReceiveRemoteNotification: (NSDictionary*)userInfo
{
NSLog(#"Push received: %#", userInfo);
}
There are few ways/ But I prefer using https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/index.html
Somrewere in constants
NSString *const NOTIFICATION_ID = #"com.yourapp.notificationID";
ViewController.m
- (void)viewDidLoad
{
NSNotificationCenter * notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:#selector(notificationRecieved:)
name:NOTIFICATION_ID
object:nil];
}
- (void)notificationRecieved:(NSNotification*)notification
{
NSLog(#"Push received: %#", notification.userInfo);
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIFICATION_ID object:nil];
}
AppDelegate.m
-(void)application:(UIApplication*)application didReceiveRemoteNotification: (NSDictionary*)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ID object:nil userInfo:userInfo];
}
Use Notifications. The app delegate will post the notification with the notification dictionary, the view controller will be listening for it.
I am using NSNotificationCenter in a code .
[[NSNotificationCenter defaultCenter]addObserverForName:#"NextIndexNotification" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self receiveTestNotification:note];
[[NSNotificationCenter defaultCenter] removeObserver:note];
}];
- (void)receiveTestNotification:(NSNotification *) notification
{
NSDictionary *userInfo = notification.userInfo;
NSString *strServerResultID = [userInfo objectForKey:#"valServerResultID"];
}
//// And I am adding Notification center here ...
dispatch_async(dispatch_get_main_queue(),^{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"%#",[[PerformXMLXPathQuery(responseData,xPathQuery) objectAtIndex:0] valueForKey:kNodeContent]] forKey:#"valServerResultID"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"NextIndexNotification" object:self userInfo:userInfo];
});
in this code , remove notification doesn't being called and my code move to infinite loop .
where am I doing wrong ?
Try
[[NSNotificationCenter defaultCenter] removeObserver:nil];
Remove notification by using blocks.
[[NSNotificationCenter defaultCenter] removeObserver:self];
Instead of passing note (which is the Notification itself, not the observer), pass the return value from the addObserverForName call to removeObserver, like this:
__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:#"NextIndexNotification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note)
{
[self receiveTestNotification:note];
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}];
I am trying to do a notification from a location manager object to my viewController. It's not working - the selector in the addObserver method doesn't get called.
Location Manager Object.m files (singleton with standard dispatch once & init methods)
- (void)setCurrentLocation:(CLLocation *)currentLocation
{
if (!_location) {
_location = [[CLLocation alloc] init];
}
_location = currentLocation;
NSNumber *latitude = [NSNumber numberWithDouble:self.location.coordinate.latitude];
NSNumber *longitude = [NSNumber numberWithDouble:self.location.coordinate.longitude];
NSLog(#"lat %# & long %# in notification section", latitude, longitude);
NSNotification *notification = [NSNotification notificationWithName:#"myNotification" object:self userInfo: #{kSetLat: latitude,
kSetLong: longitude}];
[[NSNotificationCenter defaultCenter] postNotification:notification];
}
ViewController.m (garden variety)
- (IBAction)welcomeNotification:(UIButton *)sender {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(sendGetRequest:) name:#"myNotification" object:[LPLocationManager sharedManager]];
[center removeObserver:self];
NSLog(#"welcomeNotication triggered");
}
The way you do is not correct. Why you add the observer and then remove it immediately. Most of the time, we add/remove observer in viewWillAppear and viewWillDisappear or viewDidAppear and viewDidDisappear.
It should be something like:-
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sendGetRequest:) name:#"myNotification" object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"myNotification" object:nil];
}
Is there any corner case behaviors for removeObserver:name:object:? In the following block of code, my observer isn't being registered properly:
- (void)setPlayerItem:(AVPlayerItem *)playerItem {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:nil
object:playerItem];
[playerItem addObserver:self
forKeyPath:kStatus
options:0
context:(__bridge void*)self];
[playerItem addObserver:self
forKeyPath:kPlaybackBufferEmpty
options:0
context:(__bridge void*)self]; // For adding a buffering activity indicator
id temp = playerItem_;
playerItem_ = [playerItem retain];
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
[temp removeObserver:self forKeyPath:kPlaybackBufferEmpty];
[temp removeObserver:self forKeyPath:kStatus];
[temp release];
}
However, if I change the order around to:
- (void)setPlayerItem:(AVPlayerItem *)playerItem {
[playerItem addObserver:self
forKeyPath:kStatus
options:0
context:(__bridge void*)self];
[playerItem addObserver:self
forKeyPath:kPlaybackBufferEmpty
options:0
context:(__bridge void*)self]; // For adding a buffering activity indicator
id temp = playerItem_;
playerItem_ = [playerItem retain];
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
[temp removeObserver:self forKeyPath:kPlaybackBufferEmpty];
[temp removeObserver:self forKeyPath:kStatus];
[temp release];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:nil
object:playerItem];
}
All the notifications post just fine. This leads me to believe something strange is happening when I call:
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
Am I missing something really obvious here? I'm on iOS 6 with no ARC.
Found the answer. Turns out it has to do with passing in nil for the observer name.
Calling [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
will remove self from observing any notifications posted by temp.
However, in the corner case that temp is nil, this line of code will remove self as an observer all together.
Name shouldn't be nil. Did you try giving your observer a name?
#Lee is correct that the name should not be nil but it also should not be the name of the observer. Rather it should be the name of the notification that you are registering to observe. e.g., UIDeviceOrientationDidChangeNotification.
Add the name of the notification that you want to observe in that param and also pass it as the name param when you remove observer