NSMutableDictionary initWithContentsOfFile - null - iphone

I'm trying to create a NSMutableDictionary with the contents of a .plist. I have the following code:
NSString *myFile = [[NSBundle mainBundle] pathForResource:#"words" ofType:#"plist"];
NSMutableDictionary* myDict = [[NSMutableDictionary alloc]initWithContentsOfFile:myFile];
NSObject *randomWord = [myDict objectForKey:#"Item 6"];
NSLog(#"%#", randomWord);
myFile and myDict are filled (not null), but when want to print randomWord (or myDict for that matter), it prints "(null)".
I've looked everywhere. What am I doing wrong?
Edit:
self MainViewController *const 0x068c0d60
myDict NSMutableDictionary * 0x0000586c
myFile NSString * 0x068c31f0
and the NSLog:
2012-05-10 12:26:22.302 project2[681:f803] (null)
So it seems myFile and myDict are filled, but randomWord isn't?
Edit #2:
NSLog(#"%#", myDict) prints:
2012-05-10 14:15:17.016 project2[2641:f803] (null)
So you're right, myDict is empty.

remove space here in item 6
[myDict objectForKey:#"Item6"];
and if this not works try this one
NSString *path = [[NSBundle mainBundle] pathForResource:#"words" ofType:#"plist"];
NSData* data = [NSData dataWithContentsOfFile:path];
NSMutableArray* array = [NSPropertyListSerialization propertyListFromData:data
mutabilityOption:NSPropertyListImmutable
format:NSPropertyListXMLFormat_v1_0
errorDescription:NULL];
if (array) {
NSMutableDictionary* myDict = [NSMutableDictionary dictionaryWithCapacity:[array count]];
for (NSDictionary* dict in array) {
State* state = [[State alloc] initWithDictionary:dict];
[myDict setObject:state forKey:state.name;
[state release];
}
NSLog(#"The count: %i", [myDic count]);
} else {
NSLog(#"Plist does not exist");
}

Related

Getting crashed when NSdictionary or NSString values into UILABEL

-(void) httpDataDidFinishLoadingWithData:(NSData *)theData
{
m_activityLoaded=NO;
temp=[[NSString alloc] initWithData:[dataLoader httpData]
encoding:NSUTF8StringEncoding];
NSLog(#"TEMP IS TEMP %#", temp);
NSDictionary *dict = [[NSDictionary alloc]init];
dict = [[temp JSONValue] objectForKey:#"location"];
NSDictionary *dict1 = [[NSDictionary alloc]init];
dict1 = [[temp JSONValue] objectForKey:#"wind"];
NSDictionary *dict2 = [[NSDictionary alloc]init];
dict2 = [dict1 objectForKey:#"direction"];
NSDictionary *dict3 = [[NSDictionary alloc]init];
dict3 = [[temp JSONValue] objectForKey:#"atmosphere"];
NSDictionary *dict4 = [[NSDictionary alloc]init];
dict4 = [[temp JSONValue] objectForKey:#"condition"];
NSDictionary *dict5 = [[NSDictionary alloc]init];
dict5 = [dict4 objectForKey:#"text"];
NSDictionary *dict6 = [[NSDictionary alloc]init];
dict6 = [dict4 objectForKey:#"code"];
NSDictionary *dict7 = [[NSDictionary alloc]init];
dict7 = [dict4 objectForKey:#"temperature"];
temperatureLabel.text = [dict4 objectForKey:#"temperature"];
}
Crash occurs at temperatureLabel.text = [dict4 objectForKey:#"temperature"];
I dont know man, Data is exactly printed in the console, but crashing at UILABEL(temperatureLabel). Help me out, thanks in advance
if you look at the error you are getting it is telling you that the object return for the key temperature is not a NSString or NSDictionary but a NSNumber.
Give this a try:
-(void) httpDataDidFinishLoadingWithData:(NSData *)theData {
m_activityLoaded=NO;
temp=[[NSString alloc] initWithData:[dataLoader httpData]
encoding:NSUTF8StringEncoding];
NSLog(#"TEMP IS TEMP %#", temp);
NSDictionary *dict = [[temp JSONValue] objectForKey:#"location"];
NSDictionary *dict1 = [[temp JSONValue] objectForKey:#"wind"];
NSDictionary *dict2 = [dict1 objectForKey:#"direction"];
NSDictionary *dict3 = [[temp JSONValue] objectForKey:#"atmosphere"];
NSDictionary *dict4 = [[temp JSONValue] objectForKey:#"condition"];
NSDictionary *dict5 = [dict4 objectForKey:#"text"];
NSDictionary *dict6 = [dict4 objectForKey:#"code"];
NSNumber *temperature = [dict4 objectForKey:#"temperature"];
temperatureLabel.text = [NSString stringWithFormat:#"%#", temperature];
}
You might want to look at NSNumberFormatter for formatter the temperature with something like: °F or °C.
Are you sure that your object is of NSString class?
Try putting in something like:
if([[dict4 objectForKey:#"temperature"] isKindOfClass:[NSString class]])
NSLog(#"lalala");
If it does not get logged to the console it means that your object is not an NSString and you could try something like:
temperatureLabel.text = [NSString stringWithFormat:#"%#", [dict4 objectForKey:#"temperature"]];
You should change the %# according to the kind of object you have stored in your dictionnary.
Your dictionary contains an NSNumber instance and you are assigning that to a property of type NSString. The crash message is your tip off there. Use stringValue or some other way to get the number's data into string form.

can any one help me in appending the data to the plist file?

I have tried this code to copy my data to plist but its not working in the case of appending .can any one suggest me a good method for appending the data?
NSMutableDictionary *nameDictionary = [NSMutableDictionary dictionary];
NSString *plistPath=[[NSBundle mainBundle] pathForResource:#"listNew" ofType:#"plist"];
[nameDictionary setValue:nameEntered.text forKey:#"name"];
[nameDictionary setValue:company.text forKey:#"company"];
[nameDictionary setValue:designation.text forKey:#"designation"];
// create dictionary with values in UITextFields
NSMutableArray *plist = [NSMutableArray arrayWithContentsOfFile:plistPath];
if (plist == nil) plist = [NSMutableArray array];
[plist addObject:nameDictionary];
[plist writeToFile:plistPath atomically:YES];
UIAlertView *tellErr = [[UIAlertView alloc] initWithTitle:title message:#"succsefully created" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[tellErr show];
nameEntered.text=#"";
company.text=#"";
designation.text=#"";
You should use +[NSKeyedArchiver archiveRootObject:toFile:] to archive the Array object to file. And use +[NSKeyedUnarchiver unarchiveObjectWithFile:] to unarchive it.
You can't write to the application main bundle in iOS. You must copy the property list file to a writable directory; then you can read it, modify it, and rewrite it.
Ok dude, here is the code that you need. I am using this in an existing iOS program
first check to see if there is any info in the dictionary to begin with
static BOOL dicIsNULL = YES;
....
//initialize the variable
dicIsNULL = YES;
//READ FILE
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"listNew.plist"];
dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:stringsPlistPath];
//Check if this dic has values
for (id key in dictionary)
{
//NSLog(#"listNew.plist file has values");
dicIsNULL = NO;
break;
}
Now do the following depending upon the dictonary had already been created or not. Add your values in the dictionary, this is just a sample code.
if (dicIsNULL == YES)
{
//NSLog(#"dictionary is NULL");
dictionary = [[NSMutableDictionary alloc] init];
dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:tempArray, infoKeyStr, textTitleField1.text, titleKeyStr, userSelectedCatStr, catKeyStr, nil];
}
if (dicIsNULL == NO)
{
//NSLog(#"dictionary is NOT null");
dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:stringsPlistPath];
[dictionary setObject: tempArray forKey: infoKeyStr];
[dictionary setObject: textTitleField1.text forKey: titleKeyStr];
[dictionary setObject: userSelectedCatStr forKey: catKeyStr];
}
hope this helps you out.
I would go for:
NSString *plistPath=[[NSBundle mainBundle] pathForResource:#"listNew" ofType:#"plist"];
NSMutableDictionary *plist = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
if (plist == nil) plist = [[NSMutableDictionary alloc] init];
[plist setObject:nameEntered.text forKey:#"name"];
[plist setObject:company.text forKey:#"company"];
[plist setObject:designation.text forKey:#"designation"];
[plist writeToFile:plistPath atomically:YES];
... etc ...
Of course, this depends on what exactly you want to achieve.

how to capture the required values from a URL

I need to extract a variable's value from a string, which happens to be a URL. The string/url is loaded as part of a separate php query, not the url in the browser.
The url's will look like:
http://gmail.com?access_token=ab8w4azq2xv3dr4ab37vvzmh&token_type=bearer&expires_in=3600
How can I capture the value of the access_token which in this example is ab8w4azq2xv3dr4ab37vvzmh?
This code should do it:
- (NSString *)extractToken:(NSURL *)URL
{
NSString *urlString = [URL absoluteString];
NSRange start = [urlString rangeOfString:#"access_token="];
if (start.location != NSNotFound)
{
NSString *token = [urlString substringFromIndex:start.location+start.length];
NSRange end = [token rangeOfString:#"&"];
if (end.location != NSNotFound)
{
//trim off other parameters
token = [token substringToIndex:end.location];
}
return token;
}
//not found
return nil;
}
Alternatively, here is a more general solution that will extract all the query parameters into a dictionary:
- (NSDictionary *)URLQueryParameters:(NSURL *)URL
{
NSString *queryString = [URL query];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
NSArray *parameters = [queryString componentsSeparatedByString:#"&"];
for (NSString *parameter in parameters)
{
NSArray *parts = [parameter componentsSeparatedByString:#"="];
NSString *key = [[parts objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([parts count] > 1)
{
id value = [[parts objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[result setObject:value forKey:key];
}
}
return result;
}
Good Category for NSDictionary:
#import "NSDictionary+URL.h"
#implementation NSDictionary (URL)
+ (NSDictionary *)dictionaryWithUrlString:(NSString *)urlString{
NSRange urlRange = [urlString rangeOfString:#"?"];
if(urlRange.length>0){
urlString = [urlString substringFromIndex:urlRange.length+urlRange.location];
}
NSArray *pairsArray = [urlString componentsSeparatedByString:#"&"];
NSMutableDictionary *parametersDictionary = [[NSMutableDictionary alloc] initWithCapacity:[pairsArray count]];
for(NSString *pairString in pairsArray){
NSArray *valuesArray = [pairString componentsSeparatedByString:#"="];
if([valuesArray count]==2){
[parametersDictionary setValue:[valuesArray objectAtIndex:1] forKey:[valuesArray objectAtIndex:0]];
}
}
return [parametersDictionary autorelease];
}
#end
NSMutableDictionary *querycomponent = [[NSMutableDictionary alloc] init];
if (![query isEqualToString:#""]){
NSArray *queryArray = [query componentsSeparatedByString:#"&"];
for (NSString *subquery in queryArray){
NSArray *subqueryArray = [subquery componentsSeparatedByString:#"="];
NSString *key = [subqueryArray objectAtIndex:0];
NSString *val = [subqueryArray objectAtIndex:1];
[querycomponent setObject:val forKey:key];
}
NSLog(#"querycomponent %#",querycomponent);
}

sending NSDictionary with openURL

I want to open an other application using
[[UIApplication sharedApplication]openURL:[[NSURL alloc]initWithString:myString]];
as log as myString is like
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",#"123"];
it works fine but if I try to use an NSDictionary like
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",userInfo];
it fails without an error
Hope you can help me.
Try enumerating all the elements in your dictionary and appending those to your URL.
NSMutableString *params = [[[NSMutableString alloc] init] autorelease];
NSEnumerator *keys = [userInfo keyEnumerator];
NSString *name = [keys nextObject];
while (nil != name) {
[params appendString: name];
[params appendString: #"="];
[params appendString: [userInfo objectForKey:name]];
name = [keys nextObject];
if (nil != name) {
[params appendString: #"&"];
}
}
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",params];
When you use an NSDictionary in the format string, you get a URL that looks like this:
testHandleOpenUrl://?{
bar = foo;
}
The result of calling -description on userInfo is simply substituted for the %#. Presumably, you want to pass parameters contained in the dictionary in the URL. Probably something like this:
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:#"bar", #"foo", nil];
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?foo=%#", [userInfo objectForKey:#"foo"]];
NSLog(#"myString: %#", myString); // prints "myString: testHandleOpenUrl://?foo=bar"
NSString * paramString = #"";
int i = 0;
for(NSString * key in [userInfo allKeys]){
NSString * value = (NSString*)[userInfo objectForKey:key];
NSString * valueParam = [NSString stringWithFormat:#"%#%#=%#",(i==0)?#"?":#"&",key,value];
paramString = [paramString stringByAppendingString:valueParam];
i++;
}
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://%#", paramString];

How to iterate through an NSArray containing NSDictionaries?

I have an NSArray of NSDictionaries each of which has 4 key values.
I'm creating objects for each NSDictionary and assigning the keys accordingly.
How can I iterate through the array of dictionaries and set each key as an attribute for the object?
I created the array seen in the picture below with this code:
if (muscleArray == nil)
{
NSString *path = [[NSBundle mainBundle]pathForResource:#"data" ofType:#"plist"];
NSMutableArray *rootLevel = [[NSMutableArray alloc]initWithContentsOfFile:path];
self.muscleArray = rootLevel;
}
NSMutableArray *arrayForSearching = [NSMutableArray array];
for (NSDictionary *muscleDict in self.muscleArray)
for (NSDictionary *excerciseDict in [muscleDict objectForKey:#"exercises"])
[arrayForSearching addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[excerciseDict objectForKey:#"exerciseName"], #"exerciseName",
[muscleDict objectForKey:#"muscleName"], #"muscleName",
[muscleDict objectForKey:#"musclePicture"], #"musclePicture", nil]];
self.exerciseArray = arrayForSearching;
NSString *path = [[NSBundle mainBundle] pathForResource:#"ExerciseDescriptions"
ofType:#"plist"];
NSDictionary *descriptions = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableArray *exercises = self.exerciseArray;
for (NSInteger i = 0; i < [exercises count]; i++) {
NSDictionary *dict = [[exercises objectAtIndex:i] mutableCopy];
NSString *exerciseName = [dict valueForKey:#"exerciseName"];
NSString *description = [descriptions valueForKey:exerciseName];
[dict setValue:description forKey:#"exerciseDescription"];
[exercises replaceObjectAtIndex:i withObject:dict];
}
The code to create one object would look like this:
PFObject *preloadedExercises = [[PFObject alloc] initWithClassName:#"preloadedExercises"];
[preloadedExercises setObject:exerciseName forKey:#"exerciseName"];
[preloadedExercises saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
NSLog(#"Success");
} else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
The array of dictionaries looks like this:
// Assuming you want to do something with all of these objects you're creating
// We'll start by creating an NSMutableArray
NSMutableArray *newObjects = [NSMutableArray arrayWithCapacity:arrayOfDictionaries.count];
for (NSDictionary *dictionary in arrayOfDictionaries)
{
PFObject *object = [PFObject objectWithClassName:#"preloadedExercises"];
object.exerciseDescription = [dictionary objectForKey:#"exerciseDescription"];
object.exerciseName = [dictionary objectForKey:#"exerciseName"];
object.muscleName = [dictionary objectForKey:#"muscleName"];
object.musclePicture = [dictionary objectForKey:#"musclePicture"];
// Add object to mutable array
[newObjects addObject:object];
}
After a quick glance at the Parse SDK that you mentioned in the comments, I think what you are looking for is this:
NSMutableArray *exercisesArray = [[NSMutableArray alloc] init];
PFObject *preloadedExercises;
id value;
// Iterate through your array of dictionaries
for (NSDictionary *muscleDict in self.muscleArray) {
// Create our object
preloadedExercises = [PFObject objectWithClassName:#"preloadedExercises"];
// For each dictionary, iterate through its keys
for (id key in muscleDict) {
// Grab the value
value = [muscleDict objectForKey:key];
// And assign each attribute of the object to the corresponding values
[preloadedExercises setObject:value forKey:key];
}
// Finally, add this newly created object to your array
[exercisesArray addObject: preloadedExercises];
}
for(NSDictionary* dictionary in yourArray){
// here you can iterate through. and assign every dictionary as you wish to.
}