Pass Array to NSObject Class - ios

I'm new to iphone app development and I'm stuck on this problem I'm having with the app I'm trying to develop.
I have a datacontroller for populating a tableview. I created it using this tutorial:
About Creating Your Second iOS App
I'm trying to pass an array from one of my viewcontrollers that was created from a JSON response.
Here is some code from my viewcontroller.h that needs to pass the array:
#interface ViewController : UIViewController
#property (nonatomic, retain) DataController *Data;
#property (nonatomic, retain) NSMutableArray *array;
#end
viewcontroller.m:
#import "DataController.h"
[Data setMasterList: self.array];
DataController.h:
#interface DataController : NSObject
#property (nonatomic, strong) NSMutableArray *masterList;
- (void)setMasterList:(NSMutableArray *)newList;
#end
DataController.m
#import "LoginViewController.h"
- (void)setMasterList:(NSMutableArray *)newList {
if (_masterList != newList) {
_masterList = [newList mutableCopy];
NSLog("List: %#", newList);
}
}
The NSLog message never shows up in the console and the array is nil.
Any help is appreciated.
Thanks.
EDIT:
Here's the updated viewcontroller.m:
Data = [[DataController alloc] init];
[Data setMasterList: self.array];
The datacontroller.m:
- (void)setMasterList:(NSMutableArray *)newList {
if (_masterList != newList) {
_masterList = [newList mutableCopy];
NSLog("List: %#", self.masterList);
}
}
- (NSUInteger)countOfList {
NSLog("List: %#", self.masterList);
return [self.masterList count];
}
The first nslog inside setMasterList returns the correct array values, but the second nslog inside countOfList returns null. The list always returns null anywhere outside of setMasterList. Is it because I'm creating a new instance of the DataController? If so, how else could I pass the array to the datacontroller.

As in first comment Till have suggested, Data must be initialized before calling setMasterList. Such As:
Data = [[DataController alloc] init];
[Data setMasterList: self.array];

Related

Can't write NSDictionary parameters into custom Object

I was stuck on writing NSDictionary into Object process, I am sure that problem is simple as I imagine but would be great to get assistant. Here is my code:
my custom object:
#interface User : NSObject
#property (nonatomic, retain) NSString *cId;
#property (nonatomic, retain) NSString *firstName;
#property (nonatomic, retain) NSString *lastName;
....
-(instancetype) initWithParameters:(NSDictionary*) parameters;
#end
#import "User.h"
#implementation User
-(instancetype) initWithParameters:(NSDictionary*) parameters
{
self = [super init];
if (self) {
[self setParameters:parameters];
}
return self;
}
- (void) setParameters:(NSDictionary*) parameters{
_cId = parameters[#"cId"];
_firstName = parameters[#"first_name"];
_lastName = parameters[#"last_name"];
....
}
and writing process:
id userObjects = [resultData objectForKey:#"data"];
NSMutableArray* mUsers = [[NSMutableArray alloc] init];
for (NSDictionary* userParameters in userObjects) {
User *user = [[User alloc] initWithParameters:userParameters];
[mUsers addObject:user];
}
userObjects - NSArray got from JSON object from server data.
The problem is : nothing happening and user object still empty after initialization, then I have tried - setValuesForKeysWithDictionary after I called variables same as keys in dictionary and nothing changed.
after adding in mUsers:
Could anybody tell me what I am doing wrong? Thank you!
I believe you think those objects are uninitialized because you are seeing 0 key/value pairs next to each User object.
Your code looks good and I think things will change once you implement [NSObject description] (or [NSObject debugDescription]) like this:
- (NSString *)description
{
return [NSString stringWithFormat:#"cId=%#, firstName=%#, lastName=%#",
_cId, _firstName, _lastName];
}

accessing the setMethod of a #property in ios

after many hour of tutorials and googling i knew that when we define a property inside the header file the compiler automatically generate the setters and getters here is an example:
"example.h"
#property(strong,nonatomic) NSNumber *test;
example.m
[self.test setTest [#"3"]];
so what i want is to access this method to check the method declaration and here is the reason that i want
Full Scenario
#interface exampleController ()
{
int example;
}
// here is a instance variable used to save a value while the app running i am getting this value from a dictionary and then save the value of the example variable to the core data
here is the entity class
exampleEntity.h
#property(strong,nonatomic) NSNumber *example;
exampleEntity.m
#dynamic example;
// since the instance variable is int we need to cast it to NSNumber so i follow this link
[entry setExample : [NSNumber numberWithInt:example]];
Finally after running this code i go into this exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException'
Full Code
#import "viewController.h"
#interface viewController ()
{
int example;
}
- (void)viewDidLoad {
gettingTheExampleValueFromDictionary();
}
-(void)gettingTheExampleValueFromDictionary()
{
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:requestHandler options:0 error:&jsonParsingError];
example = [[dictionary objectForKey:#"exampleId"] intValue];
}
- (IBAction)doneButton:(id)sender {
[self insertDataToCoreData];
[self dismissSelf];
}
-(void)insertDataToCoreData {
CoreData *coreDataStack = [CoreData defaultStack];
ExampleEntity *entry = [NSEntityDescription insertNewObjectForEntityForName:
#"ExampleEntity" inManagedObjectContext:coreDataStack.managedObjectContext];
[entry setExample :[NSNumber numberWithInt:example]];
// here we go into the error //
[coreDataStack saveContext];
}
#end
// and if you ask me for entity class here is:
#import <Foundation/Foundation.h>
#interface ReservationEntity : NSObject
#property (nonatomic,strong) NSNumber *example;
#end
#import "exampleEntity.h"
#implementation exampleEntity
#dynamic example;
#end
// and if you ask me for core data here is the pic needed //
// the configuration of xcdatamodel
In your case you should change:
#dynamic example;
to
#synthesize example;
or just delete the line of code #dynamic example.
Because #synthesize generates the getter&setter for the property, while #dynamic means the getter&setter are created in runtime(e.g. NSManagedObject's subclasses)

Updating an NSMutableArray passed into a method

I'm very new to objective-c so be easy :-) I have a container object, "Data", who has a number of NSMutableArrays.
Data.h
#interface Data : NSObject{
NSMutableArray *one;
NSMutableArray *two;
}
#property (nonatomic, retain) NSMutableArray *one;
#end
and would like to pass it to a load method in which case it will update each corresponding array in the Data class.
Parser.h
+ (Parser *)load:(Data*) store;
Parser.m
+ (Parser *)load:(Data *) store {
...
[store.one addObject:name.stringValue];
}
But no matter what I do the string in "name.stringValue" doesn't get appended to the array. Is there something I'm missing when passing in the "Store" data object to the parse method? Let me know if I should provide more details but I feel this covers the issue.
Check in your implementation of Data that you are properly initializing the mutable arrays - here is a simple example below given your Data interface:
#import "Data.h"
#implementation Data
{
#pragma mark - Properties
- (NSMutableArray *)one
{
if (!_one) {
_one = [[NSMutableArray alloc] init];
}
return _one;
}
- (NSMutableArray *)two
{
if (!_two) {
_two = [[NSMutableArray alloc] init];
}
return _two;
}
}
Use one = [NSMutableArray array]; before you start using it. This will create an empty mutable array.

NSMutableArray not printing correct data - iOS/Objective C

I'm struggling to get my array to print the correct data.
I've got it linked to a button, so it gets the textfield data and adds it to a Person class which has a subclass called PhoneBookEntry which contains firstName, and then adds it to an NSMutableArray called entries. here's the button code:
PhonebookEntry *person = [[PhonebookEntry alloc] init];
self.firstName.text = person.firstName;
[self.entries addObject:person];
NSLog(#"%#", self.entries);
Here's the start where I initialise everything:
#interface ViewController ()
#property (nonatomic, strong) PhonebookEntry *person;
#property (nonatomic, strong) NSMutableArray *entries;
#end
in my viewDidLoad, this is the code to create the NSArray.
self.entries = [NSMutableArray arrayWithCapacity:1];
I've tested and it works fine when adding normally and prints etc, just not with the array.
Thanks
The output
test,
test2,
"<PhonebookEntry: 0x8c69770>"
It is printing correctly.
Actually you want something more from your code or Objective-C.
For this you need to override description in PhonebookEntry class to break to the level where NSLog can print. NSLog can't print person object values.
-(NSString *)description{
return [NSString stringWithFormat:#"%# , %#", self.firstName, self.lastName];
}
This self.firstName.text = person.firstName; should be the other way around, so change it to this:
person.firstName = self.firstName.text;

Program crush on [order setPrice:price] break point at #synthesize name

please help me to solve a simple problem.
I am a beginner in objective-c, and I am just switched to objective-c from java. I know java fair well, but not quite super deep into it.
I am building a iphone app. My app is quite simple.
The purpose of my iphone app is to take order with my iphone app in a restaurant.
Progress of My App:
My app only has couple viewPanels and buttons now :)
Here is my app sourcecode, firstview screenshot & secondview screenshot
Problem:
When i click on the Coffee button, my textField wont show up the coffee name & coffee price, which suppose to show up " coffee 1" .
and xcode will take me to the debugger from the iphone similator.(i think its crush at a line so the dubugger took me to the IBaction method and break at the line #synthesize name; It compiles with no error. please help trouble shoot why xcode take me to debugger when i press the coffee button.
SCREEN SHOWS UP RIGHT AFTER PRESS THE COFFEE BUTTON
here is the action code of the coffee button
- (IBAction)Coffee:(id)sender {
int price = 1;
NSString *name = #"coffee";
Storage *order = [[Storage alloc] init];
[order setName:name]; // i assume the program crush at here when it look into setName method.
[order setPrice:price];
[orders addOrders:order];
// Sanity check: // the program not even hit this line yet before crush;
NSLog(#"There are now %d orders in the array.", [orders.getOrders count]);
for (Storage *obj in orders.getOrders){
[check setText:[NSString stringWithFormat:#"%#",[obj description]]]; // check is the TextField instant varible. and the description method is from storage.m to print out the name and price.
}
}
The codes below are my storage classes that store all items that my customer orders.
it is a 2 dimensional array, and My Storages class is a wrapper class of Storage class.
the array format looks like this:
arrayindex1-> name, price
arrayindex2-> name, price
arrayindex3-> name, price
arrayindex4-> name, price
Storage.h
#import <Foundation/Foundation.h>
#interface Storage : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, assign) NSInteger price;
#end
Storage.m
#import "Storage.h"
#implementation Storage
#synthesize name; // program crush and goes to here.
#synthesize price;
- (NSString *)description {
// example: "coffee 1"
return [NSString stringWithFormat:#"%# %d", self.name, self.price];
}
#end
Storages.h
#import <Foundation/Foundation.h>
#import "Storage.h"
#interface Storages : NSObject
#property (nonatomic,strong, readwrite) NSMutableArray *orders;
-(void) addOrders:(Storage *)anOrder;
-(NSMutableArray *) getOrders;
#end
Storages.m
#import "Storages.h"
#implementation Storages
#synthesize orders;
- (id)init {
self = [super init];
if (self) {
orders = [[NSMutableArray alloc] init];
}
return self;
}
-(void) addOrders:(Storage *)anOrder{
[orders addObject: anOrder];
}
-(NSMutableArray *) getOrders{
return orders;
}
#end
There are a couple of problems here.
1) Don't use a pointer for the price property. Generally, unless you're doing something unusual, your properties that are objects will be pointers and your properties that are primitives (NSInteger, BOOL, float, etc) will not be pointers.
2) You will want to make sure that the orders NSMutableArray is initialized with the Storages object, otherwise orders will remain nil and whenever you try to add objects to it, nothing will happen. To initialize the NSMutableArray, do this in your init method as shown below. You can also check that the object is actually getting into a valid mutable array this by putting a simple NSLog statement in the for (Storage *obj in orders.getOrders) { ... } loop and making sure you get at least one iteration through the loop. If orders.getOrders is nil, the work block of the for loop will never get run.
3) It sounds like you need to override (and may have already overridden) the -[NSObject description]method for your Storage object. My guess is you have a mismatch in this method with the -[NSString stringWithFormat:...] format string. For example, you might be using %d or %# in the format string for the NSInteger *. Something like that could definitely cause a crash (which is what I think you mean by "Xcode taking you to the debugger"). For NSIntegers you need to use %d or %i. And as myself and others have mentioned, you want NSInteger here and not NSInteger * and you should change your property declaration.
4) Based on what you have here, I don't think you need the order property in the Storages class at all.
5) Make sure you haven't overlooked the possibility of forgetting to hook up the IBOutlet in Interface Builder to the check textField. A good test for this, besides just confirming it's connected in Interface Builder, would be a reality check test like [check setText:#"This is a test."];
6) Keep in mind that once this works, your for loop is going to execute very quickly, and you'll immediately see only the description for the last object in the orders array. But that doesn't seem to be what your question is about.
I'd suggest you make the following changes:
Storage.h
#import <Foundation/Foundation.h>
#interface Storage : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, assign) NSInteger price;
#end
Storage.m
#import "Storage.h"
#implementation Storage
#synthesize name;
#synthesize price;
- (NSString *)description {
// example: "coffee 1"
return [NSString stringWithFormat:#"%# %d", self.name, self.price];
}
#end
Your IBAction method
- (IBAction)Coffee:(id)sender {
int price = 1;
NSString *name = #"coffee";
Storage *order = [[Storage alloc] init];
[order setName:name];
[order setPrice:price];
[orders addOrders:order];
// Sanity check:
NSLog(#"There are now %d orders in the array.", [orders.getOrders count]);
for (Storage *obj in orders.getOrders){
[check setText:[NSString stringWithFormat:#"%#",[obj description]]]; // check is the TextField instant varible. and the description method is from storage.m to print out the name and price.
}
}
Storages.h
#import <Foundation/Foundation.h>
#import "Storage.h"
#interface Storages : NSObject
#property (nonatomic,strong, readwrite) NSMutableArray *orders;
-(void) addOrders:(Storage *)anOrder;
-(NSMutableArray *) getOrders;
#end
Storages.m
#import "Storages.h"
#implementation Storages
#synthesize orders;
- (id)init {
self = [super init];
if (self) {
orders = [[NSMutableArray alloc] init];
}
return self;
}
-(void) addOrders:(Storage *)anOrder{
[orders addObject: anOrder];
}
-(NSMutableArray *) getOrders{
return orders;
}
#end
What does description do in the following? (I cannot see any description object in Storage class):
[check setText:[NSString stringWithFormat:#"%#",[obj description]]];
I think if you want to print the name the do like:
[check setText:[NSString stringWithFormat:#"%#: %#",obj.name, obj.price]];
You have taken NSInteger pointer in Storages class which is not correct. NSInteger is basic data type and not a pointer. Remove that pointer and use NSInteger variable.
I hope this would resolve your problem.
You could use below code:
#interface Storage : NSObject
#property (nonatomic, retain)NSString *name;
#property (nonatomic, assign)NSInteger price;
You have two mistakes:
1- You declared price as an NSInteger and passed it as a reference. The correct is to pass it as an integer as it is and deal with it as an integer through the whole application.
2- You didn't initialize orders array in Storages class so it will be always nil and will not hold any added object.
You code may looks like:
In the button's IBAction pass the price directly
[order setPrice:price];
In the Storage class
- (NSString *)description {
return [NSString stringWithFormat: #"%# %d", name, price];
}
Add the following to the Storages class
-(id)init
{
if (self = [super init])
{
orders = [[NSMutableArray alloc] init];
}
return self;
}

Resources