How to pass userInfo in NSNotification? - iphone

I am trying to send some data using NSNotification but get stuck. Here is my code:
// Posting Notification
NSDictionary *orientationData;
if(iFromInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
orientationData = [NSDictionary dictionaryWithObject:#"Right"
forKey:#"Orientation"];
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:#"Abhinav"
object:nil
userInfo:orientationData];
// Adding observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged)
name:#"Abhinav"
object:nil];
Now how to fetch this userInfo dictionary in my selector orientationChanged?

You get an NSNotification object passed to your function. This includes the name, object and user info that you provided to the NSNotificationCenter.
- (void)orientationChanged:(NSNotification *)notification
{
NSDictionary *dict = [notification userInfo];
}

Your selector must have : to accept parameters.
e.g.
#selector(orientationChanged:)
then in the method declaration it can accept the NSNotification parameter.

You are posting the notification correctly.
Please modify the Notification Observer like following.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:#"Abhinav" object:nil];
- (void)orientationChanged:(NSNotification *)notification
{
NSDictionary *dict = [notification userInfo];
}
I hope, this solution will work for you..

In swift
To get userinfo object
let dict = notification.userInfo
print(dict)

Related

iOS 6: UserInfo returns nil for Pasteboard change Notification

Here's the Notification Observer for the Pasteboard change event, I need it to handle the copied selected text
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveClipBoardNotification:)
name:#"UIPasteboardChangedNotification"
object:nil];
And here's the implementation for the selector method receiveClipBoardNotification:
- (void) receiveClipBoardNotification:(NSNotification *) notification {
// NSMutableArray *typesAddedKey = [[notification userInfo] objectForKey:#"UIPasteboardChangedTypesAddedKey"];
// pasteBoardItemType = [typesAddedKey objectAtIndex:0];
NSLog(#"%#", [notification userInfo]);
}
The problem is that [notification userInfo] returns nil on iOS 6, although it works perfectly on iOS 5.
Well, This worked on iOS 6
NSLog(#"%#", [[UIPasteboard generalPasteboard] string]);

postNotification trigger the function correctly , but userinfo(NSDictionary) has nothing

I used the codes below to notify the menu selection index
NSDictionary *userInfo= [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"123"]
forKey:#"Index"];
[[NSNotificationCenter defaultCenter] postNotificationName: #"notifyToMenuSelectionNotification"
object: userInfo];
-(void)menuSelectionNotification:(NSNotification *)notification
{
NSLog(#"%#", notification.userInfo);
}
menuSelectionNotification is triggered correctly,
but NSLog output notification.userInfo is still {null}
Welcome any comment1
you are passing object in wrong way. Please try this -
NSDictionary *userInfo= [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"123"]
forKey:#"Index"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"notifyToMenuSelectionNotification"
object:nil
userInfo:userInfo];
You have to set your dictionary as the userInfo parameter, not as the object. You may want to try
[[NSNotificationCenter defaultCenter] postNotificationName:#"notifyToMenuSelectionNotification" object:nil userInfo:userInfo];
You should post the dictionary in userInfo parameter , like
[[NSNotificationCenter defaultCenter] postNotificationName:#"notifyToMenuSelectionNotification" object:nil userInfo:userInfo];
For more detail, pl. see the NSNotificationCenter documentation
please try this
[[NSNotificationCenter defaultCenter] postNotificationName:#"notifyToMenuSelectionNotification" object:userInfo userInfo:nil];
-(void)menuSelectionNotification:(NSNotification *)notification{
NSDictionary *userInfo = (NSDictionary*)notification.object;
}

Pass object with NSNotificationCenter to other view

I am trying to pass an object from my main view class to other notification receiver in another class.
I want to pass an object named country, that loads all the cities from an SOAP Request in the Main Controller and i want to send it to my next view.
country = [[Country alloc] init];
Country header:
#interface Country : NSObject
{
NSString *name;
NSMutableArray *cities;
}
#property (nonatomic,retain) NSString *name;
- (void)addCity:(Cities *)city;
- (NSArray *)getCities;
- (int)citiesCount;
#end
I found a way to pass data with NSNotificatios is using a NSDictionary in UserInfo. But its not possible to send the whole object instead of converting to an NSDictionary? Or what's the best way to transfer it? Im stuck trying to figure out how to pass the objects.
Actually i got working this simple NSNotification on my App.
NSNotification in the Main View Controller implementation:
//---Call the next View---
DetailViewController *detail = [self.storyboardinstantiateViewControllerWithIdentifier:#"Detail"];
[self.navigationController pushViewController:detail animated:YES];
//--Transfer Data to2View
[[NSNotificationCenter defaultCenter] postNotificationName:#"citiesListComplete" object:nil];
NSNotification in 2View Controller implementation:
// Check if MSG is RECEIVE
- (void)checkMSG:(NSNotification *)note {
NSLog(#"Received Notification");
}
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(checkMSG:)
name:#"citiesListComplete" object:nil];
Oooooo, so close. I have a feeling you do not understand what an NSDictionary is though.
Post your notification with this:
Country *country = [[[Country alloc] init] autorelease];
//Populate the country object however you want
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:country forKey:#"Country"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"citiesListComplete" object:nil userInfo:dictionary];
then get the country object like this:
- (void)checkMSG:(NSNotification *)note {
Country *country = [[note userInfo] valueForKey:#"Country"];
NSLog(#"Received Notification - Country = %#", country);
}
You don't need to convert your object into a NSDictionary. Instead, you need to send a NSDictionary with your object. This allows you to send lots of information, all based on keys in the NSDictionary, with your NSNotification.
For Swift
You can pass dictionary with using the below code
NSNotificationCenter.defaultCenter().postNotificationName(aName: String, object anObject: AnyObject?, userInfo aUserInfo: [NSObject : AnyObject]?)
for example
NSNotificationCenter.defaultCenter().postNotificationName("OrderCancelled", object: nil, userInfo: ["success":true])
And read this dictionary from
func updated(notification: NSNotification){
notification.userInfo?["success"] as! Bool
}

How to search for uploaded files in iCloud

I have succeeded uploading a file to iCloud, which can be seen within icloud space manager(but,what odd is the file name is 'unknown').
I also found a piece of code from apple's document
_query = [[NSMetadataQuery alloc] init];
[_query setSearchScopes:[NSArray arrayWithObjects:NSMetadataQueryUbiquitousDataScope, nil]];
[_query setPredicate:[NSPredicate predicateWithFormat:#"%K == '*.*'", NSMetadataItemFSNameKey]];
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:#selector(fileListReceived)
name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[notificationCenter addObserver:self selector:#selector(fileListReceived)
name:NSMetadataQueryDidUpdateNotification object:nil];
[_query startQuery];
//
[super viewDidLoad];
-(void)fileListReceived
{
NSArray* queryResults = [_query results];
for (NSMetadataItem* result in queryResults) {
NSString* fileName = [result valueForAttribute:NSMetadataItemFSNameKey];
NSLog(#"fileName = %#", fileName);
}
}
but the result is always 0, no matter NSMetadataQueryUbiquitousDataScope or NSMetadataQueryUbiquitousDocumentsScope.
I also know that icloud has backup function, so does backup has any relation with uploading file by app itself?
In your predicate try to use "like" instead of "==".

Cocoa: Problem passing a CGPoint with NSNotification and NSDictionary

I'm trying to fire a Notification in a method called setPosition in one class, that triggers setViewPointCenter in another class. However, I'm trying to send a CGPoint along with it. But Xcode isn't liking it one bit.
-(void)setPosition:(CGPoint)point
{
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:#"sp", point, nil];
[[NSNotificationCenter defaultCenter]
postNotificationName:#"SpriteDidSetPosition"
object:self
userInfo:dict];
[super setPosition:point];
}
Triggers this method in another class, but throws the indicated error
-(id) init{
// Usual stuff, blah blah blah...
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(setViewPointCenter:)
name:#"BownceSpriteDidSetPosition"
object:nil];
}
-(void) setViewPointCenter:(NSNotification *)notification
{
// ERROR: Invalid Initializer
CGPoint point = [[notification userInfo] valueForKey:#"sp"];
// more code here....
}
I've been digging around, and found this solution, but I still get an error.
-(void)setPosition:(CGPoint)point
{
// ERROR: Incompatile type for argument 1 of "Value With Point"
NSValue *pointAsObject = [NSValue valueWithPoint:point];
NSDictionary *dict = [[NSDictionary alloc]
initWithObjectsAndKeys:#"sp",
pointAsObject,
nil];
[[NSNotificationCenter defaultCenter]
postNotificationName:#"SpriteDidSetPosition"
object:self
userInfo:dict];
[super setPosition:point];
}
It's driving me nuts. And to confuse me even further, changing CGPoint to NSPoint like this
-(void)setPosition:(NSPoint)point
{
NSValue *pointAsObject = [NSValue valueWithPoint:point];
NSDictionary *dict = [[NSDictionary alloc] init];
[dict initWithObjectsAndKeys:#"sp", pointAsObject, nil];
[[NSNotificationCenter defaultCenter]
postNotificationName:#"SpriteDidSetPosition"
object:self
userInfo:dict];
[super setPosition:CGPointMake(point.x, point.y)];
}
Get's rid of the error in setPosition, but I'm still screwed in setViewPointCenter. And as I understand it, CGPoint and NSPoint should equal the same thing, but it doesn't look like they do.
Does anyone have a working example of how to pass a CGPoint in a Dictionary? I can't figure it out.
This is for the iPhone, incase that makes a difference.
Try using +[NSValue valueWithCGPoint].
I'd use the NSStringFromCGPoint() function to convert it to a string, and then use the CGPointFromString() function to convert it back.
You could encapsulate the x and y values from the CGPoint into NSNumber objects using +numberWithFloat: and then add the two resulting NSNumber objects into the dictionary. You can then reconstruct the CGPoint on the other side using:
CGPoint myPoint;
myPoint.x = [myNumberObject floatValue];
myPoint.y = [myNumberObject2 floatValue];
The reason it didn't work in the first try was that CGPoint isn't an object, it's a C struct.
Its been too long time after #Ben Gottlieb have given an answer, his answer is well, but for future I'm keeping an example for reference.
// In example, I want to send CGPoint with notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"MyNotification" object:#{#"someKeyToHoldCGPoint":[NSValue valueWithCGPoint:CGPointMake(10, 10)]}];
- (void) getPoints:(NSNotification *)notification {
//get the dictionary object from notification
NSDictionary *p = (NSDictionary *)notification.object;
//get the NSValue object from dictionary p
NSValue *value = [p valueForKey:#"someKeyToHoldCGPoint"];
//convert the value to CGPoint
CGPoint points = [value CGPointValue];
//check if we've the correct value
NSLog(#"%#",NSStringFromCGPoint(points));
}
It should log, (10,10).
I haven't read up on GC and NSPoints, but what data-types can NSDictionary hold? Check the docs, maybe you should cast it to NSData.