I'm trying to use the parse.com data browser to inset a new string array into my code.
So if I've got a code with an array of #"blue", #"yellow", #"black", nil then how can I change it to #"white", #"gold", #"brown", nil ?
In the app, I have the user press a button and one of said string value appears at random. I would like to put a new array on a backend to have new values so that I don't have to update the app every time.
Is there an example of how to do this? I haven't been able to get the Data Browser to replace the array in my code with the array in the data browser.
I've got:
PFQuery *query = [PFQuery queryWithClassName:#"colorArray"];
self.colors = [query findObjects];
But it crashes when I try to retrieve the values of the array when it gets to this part of the code in a later method -
NSUInteger index = arc4random_uniform(self.colors.count];
self.colorLabel.text = [self.colors objectAtIndex:index];
self.colors, by the way, is synthesized from the header file as an array. It looks like the code doesn't understand the "index" part of the equation when it tries to set the self.colorLabel.text using the obectAtIndex
The crash is "-[PFObject length]: unrecognized selector sent to instance 0xcb56740".
Am I doing this right?
self.colors is an array of PFObjects - not NSStrings
That is why this line fails:
self.colorLabel.text = [self.colors objectAtIndex:index];
What you need is something like:
NSUInteger index = arc4random_uniform(self.colors.count];
PFObject *colourPFObject = [self.colors objectAtIndex:index];
self.colorLabel.text = [colourPFObject objectForKey:#"columnNameForColour"];
Don't forget to change columnNameForColour to whatever name you call your colour column in your the Parse.com colorArray class
See the #Carl Veazey comment.
{colors = (Red,Blue,Black);}
is from the description method of PFObject, you need to use the accessor methods of PFObject to get at the colors (or array of colors).
Related
I have an array - placeObjectsArray, that hold a lot of objects called place. Place is object of class PlaceHolder, in which i create different properties, filled with data:
self.place = [[PlaceHolder alloc]init];
// A lot of code here during parson XML with data
[self.placeObjectsArray addObject:self.place];
Header of this file look like this:
#interface PlaceHolder : NSObject
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSString *description;
#property (strong, nonatomic) NSString *webPage;
It actually a container for an entity, each one hold data for name, description, image links etc. At now, i have array with place objects. What i want to, to manipulate with that objects inside an array. For example, how could i find all of data for specific "name"? (Name is one of properties in PlaceHolder class). How could i make an array that contain only names? How could i see in console 10 random "description"?
Any advice would be appreciated, thanks!
You're asking a bunch of separate questions.
First, how to select items in your array that match a particular name: Create an NSPredicate and use filteredArrayUsingPredicate. Google NSPredicate and you should find lots of examples.
Alternately you could use indexesOfObjectsPassingTest to get an index set of the items in the array that match your search criteria, and then use objectsAtIndexes: to turn the index set into a sub-array.
As for how to get all the names from the entries in your array, you can use a very cool trick in key value coding.
If you send an array the valueForKey message, it tries to fetch an item from each entry in the array using that key, and return them all in a new array. The code would look like this:
NSArray *names = [placeObjectsArray valueForKey #"name"];
Fetching 10 random descriptions is a little more complicated. You would need to write code that loops through the array, selecting 10 random items, and appends the description of each one into a new mutable array.
The trick there is to use arc4random_uniform to get a random index in your array:
NSUInteger random_index = arc4random_uniform(placeObjectsArray.count);
I leave the rest to you as a learning exercise.
If you want to fetch 10 random descriptions and make sure you never fetch the same description twice it's more complicated. You need to create a mutable copy of your array, then loop through the copy, fetching a random item, adding it's description to an array, and deleting the item from the array.
You can use NSPredicates:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name LIKE[cd] %#", nameSearch];
NSArray *filtered = [self.placeObjectsArray filteredArrayUsingPredicate:predicate];
You could iterate over your array looking for the PlaceHolder with a given name, like:
PlaceHolder *namedPlaceholder = nil;
for (PlaceHolder *placeholder in theArray) {
if ([placeholder.name isEqualToString:"whateverName"]) {
namedPlaceholder = placeholder;
break;
}
}
If you want to find PlaceHolders by name efficiently you might consider using a dictionary instead of an array. With a dictionary you can map names to objects, like:
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
myDictionary[#"foo"] = somePlaceholder;
myDictionary[#"bar"] = someOtherPlaceholder;
and retrieve them like:
PlaceHolder *somePlaceholder = myDictionary[#"foo"];
To get random objects from an array, I recommend getting random indexes using arc4random_uniform. This gives pseudo-random numbers with a better uniform distribution than rand or random, and does not require you to explicitly seed the sequence with srand or srandom.
PlaceHolder *randomPlaceholder = theArray[arc4random_uniform(theArray.count)];
or
const NSUInteger arrayCount = theArray.count;
for (NSUInteger j = 0; j < 10; j++) {
PlaceHolder *randomPlaceholder = theArray[arc4random_uniform(arrayCount)];
// Do something with randomPlaceholder.
}
I want to clear my array, what i did is,
I have tableview view in my app, first i am fetching data from server and loading it in tableView.
-(void)viewDidLoad{
//fetching data from server using background thread and storing it in array called (msg_array)
[table reloadData];
}
when last row comes on screen i want to fetch new data from server and i want to display it,
-(void)LoadMoreData{ //this method gets fire when last cell is on screen
if ([msg_array count]>0)
{
[msg_array removeAllObjects]; //crashes here
}
}
This gives the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSArrayI removeAllObjects]: unrecognized selector sent to instance
Why does it cause a crash:
The array is allocated like this:
msg_array = [dictShow copy];
dictshow contains the data and copying it to msg_array and dictshow is mutabledictionary
(Taken from comments)
'-[__NSArrayI removeAllObjects]: unrecognized selector sent to instance
This means that the array doens't have the method you're trying to call. That's because it is an immutable array (NSArray), not mutable (NSMutableArray).
Either make it mutable if you want to mutate it. Or, replace:
[msg_array removeAllObjects];
with:
msg_array = #[];
Based on your comment, the array should be mutable. That means that you have a mutable property / instance variable, but that you're creating an immutable instance to store into it. Find that location and update it (to create / return a mutableCopy at least).
Its because you are trying to modify a immutable array, you have two options here:
msg_array = #[];
OR
NSMutableArray *mutableMessageArray = [msg_array mutableCopy];
[mutableMessageArray removeAllObjects];
msg_array = [mutableMessageArray copy];
I prefer the first option as its neater, but if you need to do any other modifications of the array the latter option might be best for you.
NB:
Check how you declare msg_array, can you post that code?
msg_array could be immutable thats why it is crashing. removeAllObjects is only for NSMutableArray
__NSArrayI, looking carefully at this bit, we can see it's suffixed with an i. This i means the array is immutable and can't be changed.
You possibly want to use an NSMutableArray
msg_array = [dictShow copy]; dictshow contains the data and copying it to msg_array and dictshow is mutabledictionary
This is very strange! I expect that calling copy on a dictionary would always return a dictionary. Unless you are mistaken there, I can only imagine that either the dictionary's keys or its values are being returned.
I think you might have meant mutable array; assuming you did, the call to copy returns an immutable object, try [dictShow mutableCopy] instead
msg_array = [NSMutableArray arrayWithArray:_MoodsArray].mutableCopy;
I basically have have a custon subclass of an UIViewController, which has a NSMutableArray called waypoints. I initialise it in the -(void)viewDidLoad method of the controller with
waypoints = [[NSMutableArray alloc] init];
Later, in a method which gets called via a presentedViewController with some parameters including a NSMutableDictionary as waypointData, I call
[waypoints insertObject:waypointData atIndex:0];
and I also tried
[waypoints addObject:waypointData];
But neither seems to work!
I logged some stuff there to make it more clear. The parameters get transmitted correctly and the NSMutableDictionary saved under waypointData is the correct content it should be. Logging the waypoints array before the insertion shows it empty (which is correct; app got launched; no data added yet) and after the insertion it's still empty. The log:
2014-02-19 14:40:11.050 xxx[xxx] waypoints before insertion: (null:)
2014-02-19 14:40:11.051 xxx[xxx] INSERT WAYPOINT
2014-02-19 14:40:11.052 xxx[xxx] waypoints after insertion: (null:)
INSERT WAYPOINT gets logged directly before the insertion, so the program routine is really executing the insertObject:atIndex: method.
TL;DR:
Even though insertObject:atIndex: (and -addObject:) for an NSMutableArray get called the object won't get inserted in the array.
EDIT:
This method gets called in -viewDidLoad too:
- (void)loadWaypoints {
id unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithFile:[[self applicationDocumentsDirectory] stringByAppendingString: kAppDataFilePlistName]];
waypoints = (NSMutableArray *)unarchivedObject;
}
unarchivedObject of course is NULL if there hasn't been anything saved yet. Thanks to 0x7fffffff.
Check your waypoints NSArray it shouldn't be nil when you call at [waypoints addObject:waypointData];
easiest way to make sure your 'waypoints' array isn't nil is doing this:
if (!waypoints)
{
waypoints = [NSMutableArray new];
}
[waypoints insertObject:waypointData atIndex:0];
or
if (!waypoints)
{
waypoints = [NSMutableArray new];
}
[waypoints addObject:waypointData];
It sounds like your waypoints array is nil. Post your header file, including the declaration of waypoints. Post your whole viewDidLoad method where you create the empty array.
The 2 most likely causes I can think of are that you declared waypoints as weak, or that you have a local variable waypoints in your viewDidLoad and you're creating an empty array in the local variable but not saving it to the instance variable.
Set a breakpoint in viewDidLoad at the line that creates the empty array. Step over it and make sure your array is being created. Then right-click on the variable down in the variables section of the debugger window and add a watchpoint to that variable. If it is getting cleared out then the breakpoint will cause your program to break at the offending line.
(My post assumes that you are using ARC. Are you?)
Please use following code:
if(waypoints == nil){
waypoints = [[NSMutableArray alloc] init];
}
[waypoints addObject:waypointData];
I have an iOS app that pulls data from a server and persists it using CoreData. I have a UITableView that I am trying to populate with only select portions from a given core data attribute.
Before the table is populated I cycle through the data and pass what I want into a NSMutableArray. The problem is when I find an item I want it is not being added to the array.
I declare the array in my .h file like so...
#property (strong, nonatomic) NSMutableArray *theNewSource;
And Synthesize it in the .m file
#synthesize theNewSource = _theNewSource;
Here is the method...
-(NSMutableArray *)setDataSourceArray
{
for(int i = 0; i < rcount ; i++)
{
NSIndexPath *countingInteger = [NSIndexPath indexPathForItem:i inSection:0];
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:countingInteger];
NSString *action = [object valueForKey:#"theActionName"];
if (![action isEqual:#"Login"])
{
[_theNewSource addObject:action];
}
}
NSLog(#"the array is now %#",_theNewSource);
return _theNewSource;
}
I've set a breakpoint in the line [_theNewSource addObject:action]. I can see in the console that the variable action does have a value but it is never added to _theNewSource array... I'm sure this is Objective C 101 but I can't get it figured out. Please Help!
Have you even created your _theNewSource array? It seems like you haven't done the following:
_theNewSource = [[NSMutableArray alloc] init];
Make sure you are creating your instance before trying to use it.
You should use a predicate in the NSFetchedResultsController's fetchRequest directly:
[NSPredicate predicateWithFormat:#"theActionName != %#", #"Login"];
NSFetchResultsControllers are particularly useful for driving table views and collection views, so filtering their results to create a separate data source is a code smell.
Doing it this way means that you can use the NSFetchedResultsController directly as the data source for your table instead of using it to create a filtered array to act as the datasource.
I'm new to iOS programming. I'm trying to bind the specific field from the objects in an array to a UITableView. Here's my code:
NSArray *personInfo; //contains a record with fields: name, address, email
personInfo = [[PersonDatabase database] getAllPersons]; //pulling the record into array
From there, I'm trying to get the field "name" from my array.
cell.textLabel.text = [NSString stringWithFormat:#"%#", [personInfo objectAtIndex: indexPath.row] retain]
As it seems you have objects in your array, what you may be looking for is the -[NSArray valueForKey:] method (documentation here).
For example:
NSArray *names = [personInfo valueForKey:#"name"];
This should return you an array containing all of the names in the array.
Are you trying to create a 2D Array?. If so you'll need to call objectAtIndex: twice on it in a nested call, but since you're new I'd suggest breaking down to a few lines so you can see more clearly what is happening.
Also, theres heaps of good code snippets on google for dealing with NSArray and table view.
Please check that if you delcare your array in #interface file as
//////.h
NSArray *personInfo;
#property(nonatomic ,retain) NSArray personInfo;
and then
in #implementation file
add this line
#synthesize personInfo;
hope it works