Reading plist data - objective-c

I was wondering if one of you could help me read data from the following plist (see image)
What I want to do is create an NSArray, for example called "OriginatingKey" with the objects: {"Crew Oxygen", "EXT", "Hatch/Safety Equipment", "ALT Doors/Inhibits Switch"}
So far I am using:
NSString *plistpath = [[NSBundle mainBundle] pathForResource:#"fileName" ofType:#"plist"];
NSDictionary* DATA = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *list1 = [DATA valueForKey:#"OriginatingKey"];
Saddly enough, this produces a list the correct number of objects. When I print the description of one of these objects I get an error. When I type NSLog(#"list1[0]") I get a minor error: "Format string is not a string literal", but the log does print the corresponding string.
Thank you for your help in advance!

Try to replace this line:
NSArray *list1 = [DATA valueForKey:#"OriginatingKey"];
with:
NSArray *list1 = [DATA objectForKey:#"OriginatingKey"];
The actual problem may be in the way you use NSLog.
Do it like this:
NSLog(#"list1[0] = %#", list1[0]);

Related

How to pass the dictionary output value to the url in objective C?

I am working on a proof of concept app that scans a barcode and returns the barcode information as a UPC value(i.e. 9780596001612). I am confused on how to pass that return value to the url(I read some tutorials online but those doesn't seem to have what I am looking for). I have hardcoded the UPC value in the code and I am getting the right response but I want to be able to pass the return value from the barcode scan and pass that value to the url. I recently started working on Objective C and would greatly appreciate your help. Thank you.
- (void) onQRCodeScanned:(NSString*) result {
NSString *theJSONString = [result description];
NSError *theError = NULL;
NSDictionary *theDictionary = [NSDictionary dictionaryWithJSONString:theJSONString error:&theError];
NSArray *results = [theDictionary objectForKey:#"decodedString"];
//results returns 9780596001612
NSString *barcodeUrl = #"http://www.outpan.com/api/get_product.php?barcode=9780596001612";
NSString *resp = [self makeRestAPICall: barcodeUrl];
}
You need to format the string to include the barcode like this (I'm assuming the barcode is the first result of the results variable - it doesn't make sense in it's current format - and that first result does indeed exist):
NSArray *results = [theDictionary objectForKey:#"decodedString"];
NSString *barcode = [results firstObject];
NSString *barcodeUrl = [NSString stringWithFormat:#"http://www.outpan.com/api/get_product.php?barcode=%#",barcode];
NSString *resp = [self makeRestAPICall: barcodeUrl];
Notice how I using stringWithFormat: and then use %# to represent a 'variable' as such, followed by the actual variable I want to include?
You can include primitive types using placeholders like %d (int), %c (char). You use %# to represent an object, such as a NSString.
You can do this for any number of variables, but you'll get an error if the number of placeholders don't match the number of variables!
You may like reading this: String Format Specifiers

Having trouble taking an index of an array and making it an NSString

I get an array from a JSON and I parse it into an NSMutableArray (this part is correct and working). I now want to take that array and print the first object to a Label. Here is my code:
NSDictionary *title = [[dictionary objectForKey:#"title"] objectAtIndex:2];
arrayLabel = [title objectForKey:#"label"];
NSLog(#"arrayLabel = %#", arrayLabel); // Returns correct
//Here is where I need help
string = [arrayLabel objectAtIndex:1]; //I do not get the first label (App crashes)
NSLog(#"string = %#", string);
other things that I have already tried are as follows:
string = [NSString stringWithFormat:#"%#", [arrayImage objectAtIndex:1]];
and
string = [[NSString alloc] initWithFormat:#"%#", [arrayImage objectAtIndex:1]];
Any help is greatly appriciated!
EDIT: The app does not return a single value and crashes.
Your code doesn't match the structure of your JSON. In your comment on the deleted answer, you said you got an exception when sending objectAtIndex: to an NSString. In your case, arrayLabel isn't an array when you think it is.
If your JSON has an object, your code needs to treat it as an NSDictionary. Likewise for arrays and NSArray and strings and NSString.
In addition to whatever else was going on, you repeatedly refer to "first" but use the index 1. In most C-based programming languages (and others, as well) the convention is that indexes into arrays are 0-based. So, use index 0 to get the first element.

How can I handle this in cocoa? Retrieve an entry from a plist file?

I have this small excel file given by a brazilian government authority, it contains records for each city in Brazil, a ZIP Code range for each city and its "city code" .
I need to retrieve for a given city its "city code".
I imagine the best way would be to parse a given zip code for the city and return its "city code", based on the first two columns that display the zip code range.
I am confident that using AppleScript I can compile a plist file for the given Excel file. But can someone point me for a few lines of objectiveC code to retrieve the given entry from a plist file once I parse the ZIP code?
Please see excel file at http://www.idanfe.com/dl/codes.xls.zip
Thanks.
I have uploaded a sample plist file to http://www.idanfe.com/dl/cityCodes.plist
Further explanation:
I will parse a ZIP CODE value like: 01123010 which is in the range of 01001000 and 05895490, so my routines should return me City Code = 3550308 and City Name = São Paulo.
I have no idea how to achieve this, I might have built the sample plist wrong.
I am confident I can build a plist file using AppleScript, reading from the Excel sheet.
But retrieving the City code for a given ZIP CODE range is a puzzle.
+++ EDIT: +++
I think I have solved it, but it looks kind of clumsy, as almost everything I write.
This AppleScript reads the Excel sheet and writes the plist file : http://www.idanfe.com/dl/creating.scpt.zip
Here you find the 1 MB plist file: http://www.idanfe.com/dl/cityCodes.plist.zip
This is the code I wrote to get the City Code I need:
NSString *zipCodeString;
zipCodeString = #"99990000";
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"cityCodes" ofType:#"plist"];
NSDictionary *cityCodes_dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *allKeys = [cityCodes_dictionary allKeys];
int i = 0;
for (i = 0 ; i <= [allKeys count]; i++) {
NSString *someKey = [allKeys objectAtIndex:i];
NSRange range08 = NSMakeRange (0, 8);
NSRange range88 = NSMakeRange (8, 8);
NSString *startZipCode = [someKey substringWithRange:range08];
NSString *finalZipCode = [someKey substringWithRange:range88];
int startZipCodeInt = [startZipCode intValue];
int finalZipCodeInt = [finalZipCode intValue];
if(startZipCodeInt <= [zipCodeString intValue] && finalZipCodeInt >= [zipCodeString intValue]){
NSLog(#"we found a winner");
NSString *cityCode = [NSString stringWithFormat: #"%#",[[cityCodes_dictionary objectForKey:someKey]objectForKey:#"City Code"]];
[cityCodeIBGEField setStringValue:cityCode];
NSLog(#"cityCode = %#",cityCode);
break;
} else {
// NSLog(#"no winners");
}
}
Basically I append the start zipCode and finalZip Code into one string of 16 digits, so I create one single record in the plist file.
Then when searching for the City Code I break the long key (2 zip codes) in 2 (back to normal zipCode) and search to see which record fits the given zipCode I need a cityCode for.
Some how it doesn't look the best for me, but for my own surprise the code is very fast, although in a loop.
I would appreciate comments...
Thanks,
I would use indexOfObjectPassingTest: to do this kind of search. Something like this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"cityCodes" ofType:#"plist"];
self.cityCodes_dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
[self findCityWithZip:#"01123010"];
}
-(void)findCityWithZip:(NSString *) searchZip {
NSUInteger indx = [self.cityCodes_dictionary.allKeys indexOfObjectPassingTest:^BOOL(NSString *zip, NSUInteger idx, BOOL *stop) {
NSString *startZipCode = [zip substringWithRange:NSMakeRange(0, 8)];
NSString *finalZipCode = [zip substringWithRange:NSMakeRange(8, 8)];
return (searchZip.integerValue < finalZipCode.integerValue && searchZip.integerValue > startZipCode.integerValue);
}];
NSLog(#"%#",[self.cityCodes_dictionary valueForKey:[self.cityCodes_dictionary.allKeys objectAtIndex:indx]]);
}
Reading the plist shouldn't be a problem at all if it is structured as a dictionary:
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: #"cities.plist"];
//NSString *zipStr = [dict valueForKey: #"CityNme"]; //this was an example
That's the easy part. The harder part is parsing and structuring the plist file from an xls file.
Or did I misunderstand your question?
PS: to get a quick look at the dictionary's plist structure, create a mock dictionary and NSLog it's description to see how it's supposed to be (or writeToFile to see the file contents or of course refer to the docs)
edit
You load the supplied plist file in a dictionary using the above code. Then you retrieve another dictionary from within it using
NSDictionary *city = [dict valueForKey : #"yourZipCodeHere"];
From that dictionary you get the cityCode like this
NSString *cityCode = [city valueOrKey: #"City Code"];
As for your range problem, I'm not sure I understand it completely. But you can get an array of all the zip codes using
NSArray *zipArray = [dict allKeys];
And then you can simply iterate over that to get the correct zip code.
PS: I don't know much apple script and would be interested in how you converted the xls to plist using it.

getting NSArray length/count - Objective C

Well I've looked at similar problems over the site but haven't reached a solution thus far so I must be doing something wrong.
Essentially, I am importing a text file, then splitting each line into an element of an array. Since the text file will be updated etc.. I won't every know the exact amount of lines in the file and therefore how many elements in the array. I know in Java you can do .length() etc.. and supposedly in Objective C you can use 'count' but i'm having no luck returning the length of my array... suggestions?
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"allshows"
ofType:#"txt"];
NSString *fileString = [NSString stringWithContentsOfFile:filePath];
NSArray *lines = [fileString componentsSeparatedByString:#"\n"];
NSUInteger *elements = [lines count];
NSLog(#"Number of Shows : ", elements);
and what is being output is NOTHING. as in "Number of Shows : " - blank, like it didn't even count at all.
Thank you for any help!
You're missing the format string placeholder. It should be:
NSLog(#"Number of shows: %lu", elements);
You need to use a format specifier to print an integer (%d):
NSLog(#"Number of Shows : %d", elements);
Looking at your other post, it seems like you are a Java developer. In Java's System.out, you just append the variables. In Objective-C, I suggest you look at "print format specifiers". Objective-C uses the same format.

Reading rtf information from entity entries to NSString

I have an entity (named Song) that one of the Attributes is binary data (a rtf field) that I use to to store chord charts or notes about a song. I need to be able to print this field along with the other string fields of this entity. I have tried every permutation of this I can think of:
NSAttributedString* myDataTry = [[[NSAttributedString alloc] initWithRTF:myData documentAttributes:NULL]autorelease];
When I run this through the debuger the summary for myDataTry reads "out of scope" until the next line break and then myDataTry reads nil.
What do I need to change to make this thing go?
The reference for initWithRTF:documentAttributes: reads:
Returns an initialized object, or nil if rtfData can’t be decoded.
Are you absolutely certain that your RTF data can be decoded?
Here is what worked:
NSString *aStr = [[NSString alloc] initWithData:myData encoding:NSASCIIStringEncoding];
NSRange r = [aStr rangeOfString:#"{"];
NSString *newAStr = [aStr substringFromIndex:r.location];
NSData *newMyData;
newMyData = [newAStr dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:1];
NSAttributedString* myDataTry = [[[NSAttributedString alloc] initWithRTF:newMyData documentAttributes:NULL]autorelease];
Now to insert that into the window with everything else! Thanks for your point in the right direction #ShaggyFrog