setting an array from another view in objective c - objective-c

I have a class which can be accessed from all other pages just like facebook chat head bubble.Its a cart in my application.Items to the cart could be added from different views. HAve tried with NSNotification and is not working.The array inside the cart view is gettig as null.Any help?What i tried is:
-(IBAction)addToCart:(id)sender{
NSMutableArray *itemToCart=[[NSMutableArray alloc]init];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObject:gearImgView.image forKey:#"equipImage"];
[dict setObject:nameLbl.text forKey:#"name"];
[dict setObject:priceLbl.text forKey:#"price"];
[dict setObject:self.shopifyIDString forKey:#"shopifyID"];
[itemToCart addObject:dict];
[[NSNotificationCenter defaultCenter] postNotificationName:#"equipmentSelected" object:nil userInfo:dict];
}
And in the cart view,
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loadEquipmentview:) name:#"equipmentSelected" object:nil];
[super viewDidLoad];
}
-(void)loadEquipmentview:(NSNotification *)notification{
NSDictionary *dict = [notification userInfo];
NSString *shopifyID = [dict objectForKey:#"shopifyID"];
NSLog(#"%#",dict);
}

Your array exist just in the addCart method's scope. try like this :
-(IBAction)addToCart:(id)sender{
NSMutableArray *itemToCart=[[NSMutableArray alloc]init];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObject:gearImgView.image forKey:#"equipImage"];
[dict setObject:nameLbl.text forKey:#"name"];
[dict setObject:priceLbl.text forKey:#"price"];
[dict setObject:self.shopifyIDString forKey:#"shopifyID"];
[itemToCart addObject:dict];
// Create an other dictionnary to hold the array of dictionary
NSMutableDictionary *otherDict = [NSMutableDictionary dictionary];
otherDict[#"yourArrayKey"] = itemToCart;
// The you post the otherDict
[[NSNotificationCenter defaultCenter] postNotificationName:#"equipmentSelected" object:nil userInfo:otherDict]; //be careful here, you should post the otherDict and not the dic.
}
and you retrieve your array, you can do like this :
-(void)loadEquipmentview:(NSNotification *)notification{
NSDictionary *dict = [notification userInfo];
NSMutableArray *array = dic[#"yourArrayKey"];
....
}

If you aren't using ARC, you might want to change the following line,
NSDictionary *dict = [notification userInfo];
To;
NSDictionary *dict = [notification userInfo] retain];

Related

insert object in an NSMutableArray with NSmutableDictionary in UserDefaults

I have an NSMutableArray. The array is storing NSMutableDictionary. The dictionary object is storing NSUserDefault values. These are slider values previously selected by user. Now I want that, when user move these sliders then new slider values must be saved in NSUserDefaults.
I'm using this method to add a value in the NSMutableArray
NSMutableArray *quarterValueArray = [[[NSUserDefaults standardUserDefaults]arrayForKey:#"QuarterValues"] mutableCopy];
if (!quarterValueArray)
{
NSMutableArray *aQuarterArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 12; i++)
{
NSMutableDictionary *dict1 = [[[NSMutableDictionary alloc] init] mutableCopy];
[dict1 setObject:#"" forKey:#"quarterP"];
[dict1 setObject:#"" forKey:#"quartersliderValue"];
[dict1 setObject:#"" forKey:#"totalOfTheQuater"];
[aQuarterArray addObject:dict1];
}
[[NSUserDefaults standardUserDefaults] setObject:aQuarterArray forKey:#"QuarterValues"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and then for storing slider values i am using this method in sliderviewCntroller
-(void)saveUserDefaultDataQuarter
{
NSMutableDictionary *quarter = [QuarterValueArray objectAtIndex:0];
[quarter setObject:totalQuarter1txt.text forKey:#"totalOfTheQuater"];
[quarter setObject:showQuartertxt.text forKey:#"quarterP"];
[quarter setObject:[NSString stringWithFormat:#"%d",(int)slider4.value]forKey:#"quartersliderValue"];
}
QuarterValueArray =[[[NSUserDefaults standardUserDefaults]arrayForKey:#"QuarterValues"]mutableCopy];
Why this code is crashing when the method is called second time? The crash log says:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
Try this.
NSMutableArray *quarterValueArray = [[[NSUserDefaults standardUserDefaults]arrayForKey:#"QuarterValues"] mutableCopy];
if (!quarterValueArray)
{
NSMutableArray *aQuarterArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 12; i++)
{
NSMutableDictionary *dict1 = [[[NSMutableDictionary alloc] init] mutableCopy];
[dict1 setObject:#"" forKey:#"quarterP"];
[dict1 setObject:#"" forKey:#"quartersliderValue"];
[dict1 setObject:#"" forKey:#"totalOfTheQuater"];
[aQuarterArray addObject:dict1];
}
[[NSUserDefaults standardUserDefaults] setValue:aQuarterArray forKey:#"QuarterValues"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
[self saveUserDefaultDataQuarter];
NSLog(#"%#",quarterValueArray);
and modify like this.
-(void)saveUserDefaultDataQuarter{
NSMutableArray*QuarterValueArray =[[[NSUserDefaults standardUserDefaults]arrayForKey:#"QuarterValues"]mutableCopy];
NSMutableDictionary *quarter = [QuarterValueArray objectAtIndex:0];
[quarter setValue:totalQuarter1txt.text forKey:#"totalOfTheQuater"];
[quarter setValue:showQuartertxt.text forKey:#"quarterP"];
[quarter setValue:[NSString stringWithFormat:#"%d",(int)slider4.value]forKey:#"quartersliderValue"]; }
UPDATE :I have used set value for setting the dictionary key values, as dictionary is already created when we are modifying values.

NSArray crashes app when it has more than 2 objects

so I've been working with NSNotificationCenter in Xcode and I've tried to attach a NSDictionary to my notification using userInfo.
NSArray *objects = [NSArray arrayWithObjects:#"Example Name", #"Example Description", #"Example Date", nil];
NSArray *keys = [NSArray arrayWithObjects:#"name", #"description", #"date", nil];
NSDictionary *dict = [NSDictionary
dictionaryWithObjects:objects
forKeys:keys];
[[NSNotificationCenter defaultCenter] postNotificationName:#"Notification" object:nil userInfo:dict];
When I try to run the app and post the notification, it crashes at the line:
NSArray *keys = [NSArray arrayWithObjects:#"name", #"description", #"date", nil];
I later found that if the array size exceeded 2 objects, the app would crash.
So if I changed my code to the snippet below, it would work.
NSArray *objects = [NSArray arrayWithObjects:#"Example Name", #"Example Description", nil];
NSArray *keys = [NSArray arrayWithObjects:#"name", #"description", nil];
NSDictionary *dict = [NSDictionary
dictionaryWithObjects:objects
forKeys:keys];
[[NSNotificationCenter defaultCenter] postNotificationName:#"Notification" object:nil userInfo:dict];
Is there any way I can work around this, or am I doing something terribly wrong?
Does this code compile? Try cleaning and rebuilding the project.

How to reload TableView data from AppDelegate.m?

I've tryed to reload TableView data from AppDelegate.m but with no success.
Here is code (whis is working in HomeViewController):
AppDelegate.m
...
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self refreshTableData];
}
-(void)refreshTableData{
UINavigationController *navController = [[self.tabBarController viewControllers] objectAtIndex:0];
HomeViewController *home = [[navController viewControllers] objectAtIndex:0];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"MYTable" inManagedObjectContext:home.context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setFetchBatchSize:20];
[request setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"orderEnt" ascending:YES];
NSArray *newArray = [NSArray arrayWithObject:sort];
[request setSortDescriptors:newArray];
NSError *error;
NSMutableArray *results = [[home.context executeFetchRequest:request error:&error] mutableCopy];
[home setArr:results];
//NSLog(#"%#", home.arr);//here is showed correct data
home.context = self.managedObjectContext;
[home.myTableView reloadData];
}
...
Does anybody know how to reload data from AppDelegate.m?
You could implement
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reloadTableViewData) name:#"ReloadAppDelegateTable" object:nil];
in your viewDidLoad() method and
- (void)reloadTableViewData{
[self.myTableView reloadData];
}
in the class where you want to reload the Data.
Then you send a Notification like this
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReloadAppDelegateTable" object:nil];
whenever you want to reload the data.
Note after some years of iOS development experience:
While this is a very easy and comfortable solution, it is not 100% reliable. Notifications can be delayed by several seconds under certain circumstances. I would highly recommend to create a fast and reliable delegate connection to your UITableViewController.

applicationWillResignActive notification uncaught on device

I'm trying to save a simple string on a simple .plist file when the application is closing.
This is my code:
- (void)viewDidLoad {
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
self.kmOld.text = [array objectAtIndex:0];
[array release];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:NULL];
[super viewDidLoad];
}
Then follow the applicationWillResignActive method:
- (void)applicationWillResignActive:(NSNotification *)notification {
NSString *text = [[NSString alloc]initWithFormat:#"%#",kmNew.text];
NSLog(#"%#",text);
if ([text intValue]>0) {
NSArray *array = [[NSArray alloc] initWithObjects:text, nil];
BOOL success = [array writeToFile:[self dataFilePath] atomically:YES];
NSLog(#"%d",success);
[array release];
}
[text release];
}
This work fine on the simulator, but it seems to be ignored by the device...
Where is the problem? Thanks...
Take a look at http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/ for a good overview of the UIApplication lifecycle. Depending on the iOS version your app is running on and the action causing your app to terminate/background you may not be listening for the correct notification and may need to observe UIApplicationWillTerminateNotification as well.

How to use parametrized method with NSNotificationCenter?

I'd like to pass dict to the method processit. But once I access the dictionary, I get EXC__BAD_INSTRUCTION.
NSNotificationCenter *ncObserver = [NSNotificationCenter defaultCenter];
[ncObserver addObserver:self selector:#selector(processit:) name:#"atest"
object:nil];
NSDictionary *dict = [[NSDictionary alloc]
initWithObjectsAndKeys:#"testing", #"first", nil];
NSString *test = [dict valueForKey:#"first"];
NSNotificationCenter *ncSubject = [NSNotificationCenter defaultCenter];
[ncSubject postNotificationName:#"atest" object:self userInfo:dict];
In the recipient method:
- (void) processit: (NSDictionary *)name{
NSString *test = [name valueForKey:#"l"]; //EXC_BAD_INSTRUCTION occurs here
NSLog(#"output is %#", test);
}
Any suggestions on what I'm doing wrong?
You will receive an NSNotification object, not an NSDictionary in the notification callback.
Try this:
- (void) processit: (NSNotification *)note {
NSString *test = [[note userInfo] valueForKey:#"l"];
NSLog(#"output is %#", test);
}
Amrox is absolutely right.
One can also use Object (instead of userInfo) for the same as below:
- (void) processit: (NSNotification *)note {
NSDictionary *dict = (NSDictionary*)note.object;
NSString *test = [dict valueForKey:#"l"];
NSLog(#"output is %#", test);
}
In this case your postNotificationName:object will look like:
[[NSNotificationCenter defaultCenter] postNotificationName:#"atest" object:dict];
You will receive an NSNotification object, not an NSDictionary in the notification callback.
(void) processit: (NSNotification *)note {
NSDictionary dict = (NSDictionary)note.object;
NSString *test = [dict valueForKey:#"l"];
NSLog(#"output is %#", test);
}