I've been having trouble finding out how to convert a JSON array into an NSArray.
I have a php script that creates an array that is converted into JSON which is then sent and stored into an NSString that looks like:
[1,2,3,4]
My problem is that I need to make that into an NSArray of ints. How would one do that?
Thanks!
You should look at the documentation of the NSJSONSerialization class.
You can hand it the NSData received from a remote call that is a string in JSON format and receive the array or dictionary it contains.
NSObject *o =[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
// other useful "options":
// 0
// NSJSONReadingMutableLeaves
// NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers
you should then check that o is of the type you expect for sanity purposes
If I wanted to quickly break that into an array I would do it like this:
NSString * jstring = #"[1,2,3,4]"; //your json string
jstring = [jstring stringByReplacingOccurrencesOfString:#"[" withString:#""];
jstring = [jstring stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSArray * intArray = [string componentsSeparatedByString:#","];
//you could create your int from the array like this
int x = [[intArray objectAtIndex:0]intValue];
Import the SBJson in your project (drag and drop it)
#import "SBJson.h"
Then where you receive the JSON response from the php file
NSArray *array = [responseString JSONValue];
Related
I want to save float values stored in an array into a text file and read the file directly on Mac. This is how I create the array:
dataArray = [[NSMutableArray alloc] init];
NSNumber *numObj = [NSNumber numberWithFloat:3.14];
[dataArray insertObject:numObj atIndex:0];
NSNumber *numObj = [NSNumber numberWithFloat:2.3];
[dataArray insertObject:numObj atIndex:1];
...
This is how I save the array:
NSData *savedData = [NSKeyedArchiver archivedDataWithRootObject:dataArray];
NSString *filePath = #"/Users/smith/Desktop/dataArray.txt";
[savedData writeToFile:filePath options:NSDataWritingAtomic error:nil];
When I open the file, the contents are just garbled letters. Instead, I want to make it something like this:
3.14
2.3
1.4
...
the program you've written saves the object representation as an array of NSNumbers, while
the result you want/expect is a text file separated by newlines.
to save those float values into a text file of that format, you could to this:
...
NSMutableString * string = [NSMutableString new];
[string appendFormat:#"%f\n", 3.14];
[string appendFormat:#"%f\n", 2.3];
NSError * error = nil;
BOOL written = [string writeToURL:url atomically:YES encoding:someEncoding error:&error];
...
You can use componentsJoinedByString: to make an in-memory representation first, and then write that representation into a file, like this:
NSString *fileRep = [dataArray componentsJoinedByString:#"\n"];
NSString *filePath = #"/Users/smith/Desktop/dataArray.txt";
[fileRep writeToFile:filePath options:NSDataWritingAtomic error:nil];
This assumes that the number of items is relatively small, because the string representation is created entirely in memory.
Reading back is not as nice as writing out, though: you start by reading back a string, theb split it to components using [fileRep componentsSeparatedByString:#"\n"], and then go through components in a loop or with a block, adding [NSNumber numberWithDouble:[element doubleValue]] for each element of your split.
You probably want to create an XML plist from it to make it human-readable:
[dataArray writeToFile:filePath atomically:YES];
This creates a property list, which is human-readable XML (except if the file already exists AND it's a binary plist, in this case the new plist will also be binary).
I have a simple JSON string that looks like
(
{
ID = 1;
response = Yes;
}
)
And my NSDictionary is not pulling the objectForKey. The jsonArray is displaying correctly. My code:
hostStr = [[hostStr stringByAppendingString:post] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostStr];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
self.jsonArray = [jsonString JSONValue];
[jsonString release];
NSLog(#"%#", jsonArray);
NSDictionary *infoDictionary = [self.jsonArray objectForKey:#"ID"];
NSLog(infoDictionary);
This is probably the case since you have completely invalid JSON (test it out at http://jsonlint.com/). Because you are missing the quotation marks in your JSON the elements won't match the id ID. All object names/keys need to be in quotation marks.
You're lucky that your framework interprets your invalid JSON (somehow) correctly so that you actually get an array or a dictionary. Because of this the result of NSLog will be correct.
Rewrite your JSON like this to get it working:
{
"ID": 1,
"response": "YES"
}
(Also be sure that jsonArray is a NSDictionary)
I have a string array as such:
NSArray *names;
names = [NSArray arrayWithObjects:
#"FirstList",
#"SecondList",
#"ThirdList",
nil];
I'm trying to assign an element of this string array to a string variable as such:
NSString *fileName = names[0]; // "Incompatible types in initialization"
or with casting
NSString *fileName = (NSString)names[0]; // "Conversion to non-scalar type requested"
I'm trying to do this, so I can use the string in a method that takes a string as an argument, such as:
NSString *plistPath = [bundle pathForResource:filetName ofType:#"plist"];
Is there no way to assign an element of a string array to a string variable?
Update from 2014: The code in this post actually would work these days since special syntactic support has been added to the framework and compiler for indexing NSArrays like names[0]. But at the time this question was asked, it gave the error mentioned in this question.
You don't use C array notation to access NSArray objects. Use the -objectAtIndex: method for your first example:
NSString *fileName = [names objectAtIndex:0];
The reason for this is that NSArray is not "part of Objective-C". It's just a class provided by Cocoa much like any that you could write, and doesn't get special syntax privileges.
NSArray is a specialized array class unlike C arrays. To reference its contents you send it an objectAtIndex: message:
NSString *fileName = [names objectAtIndex:0];
If you want to perform an explicit cast, you need to cast to an NSString * pointer, not an NSString:
NSString *fileName = (NSString *)[names objectAtIndex:0];
With the new Objective-C literals is possible to use:
NSString *fileName = names[0];
So your code could look like this:
- (void)test5518658
{
NSArray *names = #[
#"FirstList",
#"SecondList",
#"ThirdList"];
NSString *fileName = names[0];
XCTAssertEqual(#"FirstList", fileName, #"Names doesn't match ");
}
Check Object Subscripting for more information.
I could not find out how to insert a boolean value (to appear as key:true in the JSON string) in my NSDictionary:
NSMutableDictionary* jsonDict = [NSMutableDictionary dictionary];
[jsonDict setValue: YES forKey: #"key"];
The code above does not run (obviously because YES is not an object).
How can I accomplish this?
You insert booleans into a dictionary using NSNumber. In this case, you can use the literal expression #YES directly, together with a dictionary literal, to make this a one-liner:
NSDictionary *jsonDict = #{#"key" : #YES};
To encode it to JSON, use +[NSJSONSerialization dataWithJSONObject:options:error]:
NSError *serializationError;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject:jsonDict
options:0 error:&serializationError];
if (!jsonData) {
NSLog(#"%s: error serializing to JSON: object %# - error %#",
__func__, jsonDict, serializationError];
}
+[NSNumber numberWithBool:] is the typical way to add a boolean to a NSDictionary.
With Objective-C literals, [NSNumber numberWithBool:YES] can be represented with just #YES,
You can create your dictionary like so:
NSDictionary *jsonDict = #{#"key":#YES};
I have a problem with parsing a JSON result. This is what I get from my HTTP request:
{"subscriptions": [
{"id":"A", "title":"A title"},
{"id":"B", "title":"B title"},
]}
And this is what I'm doing in my code:
// Getting the result<br>
NSString *str = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
// Creating the JSON parser<br>
SBJSON *parser = [[SBJSON alloc] init];
// Parse result in an object<br>
NSDictionary *result = [parser objectWithString:str];
So far everything works fine. I have one key/value pair in my result object which I think is the subscriptions object. But the problem is now: How can I access the inner objects of it like the id and title?
Thanks for help.
The JSON parser will create nested NSArray and NSDictionary objects for you. To get to the array use:
NSArray *array = [result objectForKey:#"subscriptions"];
Then access the objects in the array like so:
NSDictionary *arrayObject = [array objectForIndex:0];
And finally, to get one of the inner objects do:
NSString *stringObject = [arrayObject objectForKey:#"id"];