Saving int values to Array when app closes - objective-c

I have an Iphone app that uses alot of int values that will increment on IBActions, I want to save the int values to an array when the app closes so that these values are stores and used when the app is reopened. I am not sure how to write int values into an array. Functionally, I am getting this to wort with text field but not integers i.e.
int count;
code used:
NSArray *values = [[NSArray alloc] initWithObjects:fieldOne.text,fieldTwo.text,count, nil];
This gives an "Assignment makes integer from pointer without cast" message.
Is there anyway to write already stored int values into and array?
code I used is as follows:
I thinks its ok until the calling the data into the array. I have commented out some failed efforts
-(NSString *) saveFilePath{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[path objectAtIndex:0] stringByAppendingPathComponent:#"savefile.plist"];
}
-(void) applicationDidEnterBackground: (UIApplication *) application{
//NSNumber *num = [[NSNumber alloc]initWithInt:count];
NSArray *values = [[NSArray alloc] initWithObjects:fieldOne.text,fieldTwo.text,[NSNumber numberWithInt:count],nil];
[values writeToFile:[self saveFilePath] atomically:YES];
[values release];
}
- (void)viewDidLoad {
//NSNumber *num = [[NSNumber alloc]initWithInt:count];
NSString *myPath = [self saveFilePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists) {
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
fieldOne.text = [values objectAtIndex:0];
fieldTwo.text = [values objectAtIndex:1];
//[NSNumber count intValue] = [values objectAtIndex:2];
[values release];
}
UIApplication *myApp = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (applicationDidEnterBackground:)name:UIApplicationDidEnterBackgroundNotification object:myApp];
[super viewDidLoad];
}
Thank you for your help.

You should use NSNumber so something like:
NSNumber *num = [NSNumber numberWithInt:int];
which will give you an object containing your int. To read back from it, use [num intValue]

Create a NSNumber object with your count as its value and put the object into your array. NSArrays need to be arrays of objects.

Container classes work with Objects not fundamental types. You have to wrap fundamental types in NSNumber (numbers) , NSData etc.

Related

NSMutableDictionary returns empty NSMutableArray

At mouseDown and mouseDragged:
locll = [self convertPoint: [event locationInWindow] fromView:nil];
NSValue *locationValuell = [NSValue valueWithPoint:locll];
[vertices addObject:locationValuell];
at mouseUp
NSString *index = [NSString stringWithFormat:#"%d", aIndex++];
[aDict setObject:vertices forKey:index];
NSArray *allKeys = [aDict allKeys];
NSLog(#"dict count: %ld", [allKeys count]);
NSString *index1 = [NSString stringWithFormat:#"%d", aIndex];
NSMutableArray *a = [aDict objectForKey:index1];
NSLog(#"a count:%li", [a count]);
at initWithCoder
int aIndex = 0;
dict count returns how many objects are stored in dictionary. And it works. But later when I try to get array back from dictionary, I check how much objects array has ([a count]) and it returns 0. So i guess NSMutableDictionary empties my NSMutableArray, or I am taking it back in wrong way.
Here
NSString *index = [NSString stringWithFormat:#"%d", aIndex++];
you increment aIndex after using it (post-increment). So if index is "0" then index1 will be "1". Therefore
NSMutableArray *a = [aDict objectForKey:index1];
returns nil.
You are increasing your aIndex by 1 after using it for saving vertices in aDict. And you access this key after it(aIndex) is increased by 1. Naturally your aDict doesn't contain any array for that key.
Just try out this:
NSMutableArray *a=[NSMutableArray arrayWithObjects:[aDict objectForKey:index1], nil];
It should be work.

JSON text and variable count

I am reading like this...
NSString *fileContent = [[NSString alloc] initWithContentsOfFile:path];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *data = (NSDictionary *) [parser objectWithString:fileContent error:nil];
// getting the data from inside of "menu"
NSString *message = (NSString *) [data objectForKey:#"message"];
NSString *name = (NSString *) [data objectForKey:#"name"];
NSArray *messagearray = [data objectForKey:#"message"];
NSArray *namearray = [data objectForKey:#"name"];
NSDictionary* Dictionary = [NSDictionary dictionaryWithObjects:message forKeys:name];
for (NSString* Key in [Dictionary allKeys]){
NSLog(#"%# %#",Key,[Dictionary objectForKey:Key]);
}
...this JSON file...
{"message":["Untitled1a","Untitled2a","Untitled3a"],"name": ["Untitled1b","Untitled2b","Untitled3b"]}
...this is the result...
Untitled3b Untitled3a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled1b Untitled1a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled2b Untitled2a
...but for each pair (Untitled 1b 2b) I would like to alloc two UITextFields, witch display the correspondent text...
I tried using this method:
for (NSString *string in messagearray){
}do{
NSLog(#"happt = %i", b);
b++;
}
while(b == b);
//While loop
while (b == b ) {
NSLog(#"x = %i", b);
b++;
}
}
I would like to count the objects in the array in order to repeat an alloc code for UITextField that number of times, and display the text accordingly, but I am not able. Please help!!
Why can't you use -count?
b = [messagearray count]
To directly answer your question:
b = 0;
for (id item in messagearray)
b++;

How to put in array a different types of field in objective-c

I'm writing an app for iPhone in objective-c. I want to declare an array that will hold different type of fields , like: int, NSString, bool.
Can I do it?
You can put whatever items in an NSArray as long as they are objects. So you have to wrap items that are not objects (such as BOOL, int and CGPoint) in some kind of objects such as NSNumber or NSValue.
NSMutableArray *array = [[NSMutableArray] alloc] init];
[array addObject:myString];
[array addObject:[NSNumber numberWithInt:1]];
[array addObject:[NSNumber numberWithFloat:1.0]];
[array addObject:[NSValue valueWithPoint:myPoint]]; // myPoint is a CGPoint
[array addObject:[NSValue valueWithRect:myRect]]; // myRect is a CGRect
Yes, you can
NSMutableArray *array = [NSMutableArray array];
NSString *string = #"str";
[array addObject:string]; //string
NSNumber *num = [NSNumber numberWithInt:1];
[array addObject:num]; //int
NSNumber *boolNum = [NSNumber numberWithBool:YES];
[array addObject:boolNum]; //bool
Use NSMutableArray.
NSMutableArray *array = [[NSMutableArray alloc]init];
Now use addObject: method to add objects. for adding int, bool value create NSNumber object.
It is possible. Just create the array and add the objects you want added.

EXC_BAD_ACESS error

I get that error EXC_BAD_ACESS at the following line:
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionTitle",i];
Here is the for loop where the above code line is located:
for (i=0; i < count; ++i)
{
//Save the occasionS details to NSUserDefaults
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionTitle",i];
NSString *dateVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionDate",i];
NSString *imageVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionImage",i];
[[NSUserDefaults standardUserDefaults] setValue:[[[self displayedObjects] objectAtIndex:i]
title] forKey:titleVarName];
[[NSUserDefaults standardUserDefaults] setValue:[[[self displayedObjects] objectAtIndex:i]
date] forKey:dateVarName];
[[NSUserDefaults standardUserDefaults] setValue:[[[self displayedObjects] objectAtIndex:i]
imagePath] forKey:imageVarName];
//release
[titleVarName release];
[dateVarName release];
[imageVarName release];
[self dismissModalViewControllerAnimated:YES];
}
Isn't ok to alloc objects and release them inside a for loop?
You need to use %d or %i specifier instead of %# to specify an integer. If %# is used with int then it will try to access the object at the address specified by the int. For example, if the value of i is one then it is trying to access the object at address one which will cause a bad access.
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%d",#"occasionTitle",i];
And also you don't need alloc and release here, though that is not the reason of bad access. You can use a convenience constructor.
NSString *titleVarName = [NSString stringWithFormat:#"occasionTitle%d", i];
// release not required
Do the same for dateVarName and imageVarName too.
Assuming i is an int, that line should be
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%i",#"occasionTitle",i];
%# is used for Cocoa objects, not primitives like an int, float or bool;
Use the %# format specifier only for NSObject objects.
As i is an integer in your code, you have to use %d or %i for integers.
Moreover, there is no need to include the string using %#, you can use the static string directly in your format string:
NSString *titleVarName = [[NSString alloc] initWithFormat:#"occasionTitle%i",i];

Method Creates an Array with 11 objects, All Out of Scope, Unrecognized Selector Results

Okay, so, I'm doing a simple lookup. I have an array of NSString objects and a string to search for in the array's elements.
It all seems to work up until I try to add a match to a new mutable array made to hold the search results. The stringHolder variable gets the string, and resultsCollectorArray even get the right number of new elements, but each element is empty and "out of range". Here's the method:
#implementation NSArray (checkForString)
-(NSMutableArray *) checkForString: (NSString *) matchSought
{
long unsigned numberofArrayElements;
long unsigned loop = 0;
NSRange searchResults;
NSMutableArray * resultCollectorArray = [[NSMutableSet alloc] init];
id stringHolder;
numberofArrayElements = [self count];
while (loop < numberofArrayElements) {
searchResults.length = 0;
searchResults = [[self objectAtIndex: loop] rangeOfString: matchSought options:NSCaseInsensitiveSearch];
if (searchResults.length > 0) {
stringHolder = [self objectAtIndex: loop];
[resultCollectorArray addObject: stringHolder];
}
loop++;
}
return [resultCollectorArray autorelease];
}
Once we get back to the main portion of the program, I get an unrecognized selector sent to the mutable array that was supposed to receive the result of the method. Here's the main section:
#import <Foundation/Foundation.h>
#import "LookupInArray.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *testString = [[NSString alloc] initWithString: #"ab"];
NSMutableString * resultString = [[NSString alloc] init];
NSArray * theArray = [[NSArray alloc] initWithObjects: ..., nil]; // Actual code has the objects
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSUInteger arrayCount = 0;
unsigned long loops = 0;
resultArray = [theArray checkForString: testString];
arrayCount = [resultArray count];
while (loops < arrayCount){
resultString = [resultArray objectAtIndex: loops]; // Here's where we get the unrecognized selector.
NSLog(#"%#", resultString);
loops++;
}
[pool drain]; // Also, I'll release the objects later. I just want to get what's above working first.
return 0;
}
I've searched the other answers (for hours now), but didn't seen anything that solved the issue.
Any and all help would be really appreciated.
And thanks beforehand.
NSMutableArray * resultCollectorArray = [[NSMutableSet alloc] init]; is so incorrect. You are creating a mutable set and assigning it to a mutable array.
You are getting unrecognized selector because objectAtIndex: is not a valid selector for NSMutableSet. Make that statement,
NSMutableArray * resultCollectorArray = [[NSMutableArray alloc] init];
A Better way
NSArray * filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchString]];
You can directly filter the array using predicates. This way you do this in a single step. :)