How to load a JSON onto a NSArray - ios

I need to pass to a Object a NSArray. In order it can show that array as Tags on the Interface, It works properly when using a manually added NSArray, But not i need to load a NSArray With a JSON Array Called Subjects I've done some code but it's not working out.
Also gives an error:
/Users/eddwinpaz/Documents/iOS-apps/mobile-app/mobile-app/UserDetailViewController.m:86:26: No visible #interface for 'NSArray' declares the selector 'insertObject:atIndex:'
This is the Code I'm Using
NSArray *subject_tag;
for (NSString* subject in [responseObject valueForKey:#"subjects"]) {
[subject_tag insertObject:subject];
}
CGRect frame = Scroller.frame;
frame.origin.y = 100;
frame.origin.x = 5;
frame.size.height = 150;
UIPillsView *pillsView = [[UIPillsView alloc] initWithFrame:frame];
[pillsView generatePillsFromStringsArray:subject_tag];
[Scroller addSubview:pillsView];

You have 3 problems here.
You never initialize your array, you only declare it. (This one is not actually causing the error and would just cause the code to fail silently once you fixed the next 2)
NSArrays are immutable. Elements cannot be added or removed after initialization. You need to use an NSMutableArray for this.
The method you are using does not exist in NSMutableArray anyway.
Here is what you should be doing:
NSMutableArray *subject_tag = [NSMutableArray new];
for (NSString* subject in [responseObject valueForKey:#"subjects"]) {
[subject_tag addObject:subject];
}

Related

Not using NSMutableArray correctly

Im trying to inset data in to the array (temp) but for some reason it saves the same data over an over. I all ready checked the _singleSeismicInfo to verify that it was handling different data(you can see it in the double "/" printData method). So i know the problem is with the MutableArray.
Im new to iOS so if theres something Im not doing right let me know.
NSMutableArray *temp = [[NSMutableArray alloc] init];
[_httpContent getTextFromHTTP];
for (int index = 0; index < 10; index++) {
NSString *line = _httpContent.lines[index];
[_singleSeismicInfo fillSeismicInfo:line];
//[_singleSeismicInfo printData];
[temp addObject:_singleSeismicInfo];
}
You're adding _singleSeismicInfo over and over without ever reassigning a new object to the variable as far as I can see. So it's the same object over and over because that's what you add.

Passing a Class as parameter and instantiating an object using this class

Is this possible, I searched the net and found no answer to this. My senior also said that this is not possible.
I'm trying to add this as a category, so I want to extract 4 types of objects out of it, all of them uses the same code, it's just the classes that differ so I thought of this:
- (NSDictionary *) getObjectsOfClass:(Class)class
{
NSMutableDictionary *objDict = [NSMutableDictionary dictionary];
[self.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:class]) {
/*
Is there a way to do this?
class *label = (class *)obj;
*/
}
}];
return objDict;
}
So is there a way to make this work? It's ugly to see 4 functions with almost the same codes, you agree right?
What about passing class name as string & creating object out of it. May be like this
-(NSArray *)arrayOfObjectsForClass:(NSString *)className{
NSMutableArray *objectArray = [[NSMutableArray alloc]init];
CGFloat yAxis = 10;
for(int i =0; i<5; i++){
id object = [[NSClassFromString(className) alloc]initWithFrame:CGRectMake(0, yAxis, 100, 50)];
[object setTitle:[NSString stringWithFormat:#"Button %d", i+1]];
[objectArray addObject:object];
yAxis+= 60;
}
return objectArray;
}
Because of you said "But I'm adding it to uiview, to get the textfields, labels, pickerviews etc, so that I can just call [self.view getObjectsOfClass:[UILabel class]"
For this code
[self.view getObjectsOfClass:[UILabel class]];
it will return all its UILabel immediate children of it.
- (NSMutableArray *) getObjectsOfClass:(Class)class
{
NSMutableArray *objArray = [NSMutableArray array];
[self.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
// All visible things are inherited from UIView. Tag property is belongs to UIView
// UILabel are inherited from UIView
if ([self isKindOfClass:[UIView class]] && [obj isKindOfClass:class]) {
UIView *aView = (UIView*)obj;
if (aView.tag == 100) {
//This is the view with tag 100
}
[objArray addObject:obj];
}
}];
return objArray;
}
If all of them are derived from a common base class, you can cast them into that common base class. If few functions are not available then create a category of that common base class and add those common functions into it. This will allow you to have single code block rather than 4 different one.
You can instantiate your class argument like this:
id newInstance = [class new];
What you cannot syntactically do is using class * as a way to tell the compiler which type your local variable is. But this is also not required, thanks to Objective C dynamics typing capabilities.
In other words, there is not reason to cast to class (and you cannot do that; class is only known at runtime, casting has effect at compile time).
EDIT:
If you know a base class common to all of your classes, e.g. UIView, then you could do:
UIView* newInstance = obj;
then access its properties, e.g.:
if (newInstance.tag ==…)
Or you could use message sending instead of properties and do:
if ([obj tag] == ...)

NSMutableArray Allocate then replaceObjectAtIndex

I have a NSMutableArray that i define in the header file as:
#property (strong, nonatomic) NSMutableArray *tempPhotosArray;
Then i allocate as:
_tempPhotosArray = [[NSMutableArray alloc] init];
What i'd like to know is if i then go to replaceObjectAtIndex the program will complain on an out of bounds. I want to keep only a set number of items in that array, so is it possible to do a insert or replace? i.e. if at index 0 it is empty do an insert, if there is an object already replace it?
Thanks
i think i agree with Hani Ibrahim. Since you said you only want to keep a set number of objects in the array. So how many you want?
// add these code when you initialize the array
int aSetNumber = 5;
_tempPhotosArray = [[NSMutableArray alloc] init];
for (int i = 0; i < aSetNumber; i++)
{
[_tempPhotosArray addobject: [NSNull null]];
}
i guess then you can do whatever you want, i don't know what exactly you want to do in this case, but i would check if the object in that position is NSNUll, if so, replace that, if not, i don't know what you want them
//use these code when you trying to insert the real object
if([[_tempPhotoArray objectAtIndex:anIndex] isKindOfClass: [NSNull class]])
{
//replace it here
}
As to why you are getting an error, what everyone else wrote is accurate, but....
The description of what you want doesn't match what an NSArray is. It sounds like you want a list of up to 5 items and never more than 5. It might be that if you try to add a 6th item the "oldest" goes away. Like a "recently opened" file history. You can make this type of functionality with an NSArray, but that's not what it is out of the box.
I would suggest making your own object class. I'm not going to write all the code for you, because this sounds suspiciously like programming homework, but I will point you in the correct direction.
FivePack <-- our class
NSArray *storage; <-- where we house the data
// a public method which lets you add things.
- (void)addItem:(id)item {
int indexOfLastItemInArrayToSave = 4;
if (storage.length < 4)
indexOfLastItemInArrayToSave = length-1;
NSRange range = NSMakeRange(0, indexOfLastItemInArrayToSave);
NSArray *temp = [storage subArrayWithRange:range];
// now create a new array with the first item being "item" that
// was passed in and the rest of the array being the contents of temp.
// Then save that to storage.
}
What you want to do with the data and writing something to get it from your new object is up to you, because I'm not sure how you want to do it.
There are no objects in the array when you initially created it, so there is nothing to replace.
Like this?
if([_tempPhotosArray count] > 0)
//replace object
else
//add object to array

data not being written to NSMutableArray

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.

insertObject:AtIndex:0 does not work properly

I have this function in which the function insertObject:AtIndex:0 behaves weird . After inserting all objects to the NSMutableArray cardViewControllers, the final element is always nil.I did alloc init the cardViewControllers at the beginning in the init method.
- (void)reloadCardViews;
{
// Add the restaurants onto view
[self removeAllCards];
for (int i = 0; i < NO_OF_CARDS; i++) {
SHCCardVC *vc = [[SHCCardVC alloc] initWithAppearanceIndex:i];
vc.delegate = self;
[cardViewControllers insertObject:vc atIndex:0];//it's behaving weird here
[self addChildViewController:vc];
// set card position to center of the container
vc.view.center = CGPointMake(_cardContainer.frame.size.width / 2, _cardContainer.frame.size.height / 2);
[_cardContainer addSubview:vc.view];
}
_currentCardViewIndex = 0;
_currentCardIndex = 0;
}
What does [self removeAllCards] do? I suspect that you call [cardViewControllers removeAllObjects]? Have you tried using [cardViewControllers addObject:vc]? If this works and the order is important, walk trough your for loop from behind with i--.
Also make sure your objects are not nil and your array is mutable and also initialized. I had a similar problem with an uninitialized mutable array.
You can't add nil objects to arrays, it's a runtime error. So something must be going weird with the retain count, that's all I can think at the moment. NSArray retains objects that are within it, so the object is being released one too many times somewhere.
Is this a possibility?

Resources