using iphone sdk 4.0. The callback for an http request gives data as an NSData object
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the data received to our data
[theData appendData:data];
}
In my php script on the server i am returning an array as follows
var_dump($array).
How do i get my array back from the NSMutableData object 'theData' obove on my iphone.
Thanks
You have a string describing your array (or maybe several arrays?) stored as a sequence of bytes in your NSMutableData object. In order to turn it back into an array you're going to need to parse the var_dump output, which is likely to be arduous.
If you can find a library (or roll your own code) to return your data in Apple plist format, your task will be much easier: you can use
[NSPropertyListSerialization propertyListFromData:mutabilityOption:format:errorDescription:]
which takes an NSData (or NSMutableData) pointer as its first argument. Try http://code.google.com/p/cfpropertylist/ for a starting point.
From the example code at the cfpropertylist page:
$plist = new CFPropertyList();
$td = new CFTypeDetector();
$guessedStructure = $td->toCFType( $array );
$plist->add( $guessedStructure );
// and then return the plist content with
$plist->toXML()
and in your iOS code:
NSString *errorString = nil;
NSArray *array = [[NSPropertyListSerialization
propertyListFromData:theData
mutabilityOption:NSPropertyListImmutable
format:nil
errorDescription:&errorString] retain];
I would likely use YAJL on iOS, and $var = json_encode($array); in the PHP. Then in the iOS, I would parse that content from the NSData input like:
YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments | YAJLParserOptionsCheckUTF8];
parser.delegate = [[[MyArrayParserDelegate alloc] init] autorelease];
[parser parse:data];
NSArray *thePhpArrayReceived = parser.delegate.resultantArray;
Please check out how to structure the delegate, and get YAJL here : Get YAJL + Readme
PHP outputs text so you will have to read that NSData as NSString and then parse out the array data according to the format specified by var_dump. As a starting point, the following code snippet should print out the array (as text) to your console:
NSString * dump = [[NSString alloc] initWithData:theData
encoding:NSUTF8StringEncoding];
NSLog(#"%#", dump);
[dump release];
As Seamus Campbell points out, there are better ways of doing this. Another option would be to output XML from your PHP script, and then use Cocoa's XML parsing methods to retreive the array.
Related
Hey every one i am programming an iphone app to get google search results into my app ,,, i have used the JSON Class to get the result ... when i parsed it in JSON Parser and store it in NSDictionary i got 3 keys :
responseData
responseDetails
responseStatus
the important one is the first one responseData which is has the search results ...
the problem that there is (i think) another key within responseData which is "results" which contains the urls and other stuffs which is the most important part for my app... how to access this one and put it into NSDictionary .....
this is the request :
http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=Paris%20Hilton
and to make things clear please consider to put that request into your browser and when you get the results copy it and put it in this website at the left side to see what the keys and other things:
http://json.parser.online.fr/
thnx
You could use JSON parser - SB Json to convert json string into ObjectiveC objects. Note that there are a number of JSON parsers available in ObjectiveC but I chose SB Json for it's ease of usage. But according to some benchmarks JSONKit is faster than SBJson.
Once you have your json string use this like so -
#import "JSON.h"
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming json_string is a NSString of JSON data
NSDictionary *object = [parser objectWithString:json_string error:nil];
NSLog(#"JSON data: %#", object);
Here's what you would do if you needed to parse public timeline from Twitter as JSON.The same logic could be applied to your Google Search results. You need to carefully inspect your json structure that's all...
// Create new SBJSON parser object
SBJSON *parser = [[SBJSON alloc] init];
// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://twitter.com/statuses/public_timeline.json"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
NSArray *statuses = [parser objectWithString:json_string error:nil];
// Each element in statuses is a single status
// represented as a NSDictionary
for (NSDictionary *status in statuses)
{
// You can retrieve individual values using objectForKey on the status NSDictionary
// This will print the tweet and username to the console
NSLog(#"%# - %#", [status objectForKey:#"text"], [[status objectForKey:#"user"] objectForKey:#"screen_name"]);
}
Il me semble que vous savez déjà comment analyser JSON en forme NSDictionary, alors voici quelques suggestions sur la façon de forer vers le bas pour vos résultats détaillés en cascade. En anglais pour tout le monde.
responseData itself is an NSDictionary and results is an object within it. Results happens to be an array for the case you gave.
After you convert the JSON to NSDictionary form, you will have recursively converted all of the objects inside.
You might try something like this to get at what you are looking for:
Lets assume the the fully converted JSON is in a NSDictionary called response
NSDictionary *responseDate = [response objectForKey:#"responseData"];
NSArray *resultsArray = [responseData objectForKey:#"results"];
Now you can use an iterator or a for-loop to go through each result.
One word of caution is that if there is only one result, you should first test to see if the class of the object is NSArray. Also, if there are no results, you should test for that too.
So you may want to code it this way to handle these cases:
NSDictionary *responseDate = [response objectForKey:#"responseData"];
If ([[responseData objectForKey:#"results"] isKindOfClass [NSArray class]]) {
NSArray *resultsArray = [responseData objectForKey:#"results"];
... do other things to get to each result in the array ...
}
else if ([[responseData objectForKey:#"results"] isKindOfClass [NSDictionary class]]) {
// it looks like each individual result in returned in a NSDictionary in your example
... do the things to handle the single result ...
}
else {
// handle no results returned
}
The first thing you should do, if you do not understand exactly what's going on, is to NSLog the description of the JSON parser output. This will be a "nest" of NSDictionary and NSArray, and when you see the description output you will understand that there is a one-to-one mapping of JSON "object" to NSDictionary and JSON "array" to NSArray. So you "understand" the parser output the same way you "understand" the JSON source.
In your case you'd likely extract the "responseData" object, cast it to an NSDictionary, extract "results" from that, cast it (guessing here) to an NSArray, then iterate through that array to extract your individual results.
I am some NSStrings, and I am just joining them and making a single NSString, then I am converting that single NSString to NSData and sending via bluetooth to other iphone
but now I have to send image with above data,
how can I achieve such concept ?
but I want to send single NSData (UIImage+NSString), how can I ????
a tutorial on how to program Bluetooth data transfer on the iPhone is here:
http://www.devx.com/wireless/Article/43502/1954
The essential part you're looking for is here:
-(IBAction) btnSend:(id) sender
{
//---convert an NSString object to NSData---
NSData* data;
NSString *str = [NSString stringWithString:txtMessage.text];
data = [str dataUsingEncoding: NSASCIIStringEncoding];
[self mySendDataToPeers:data];
}
- (void) mySendDataToPeers:(NSData *) data
{
if (currentSession)
[self.currentSession sendDataToAllPeers:data
withDataMode:GKSendDataReliable
error:nil];
}
Good luck with it!
I would recommend sending them in separate packets since an image could be quite large (send the image itself in multiple packets). But if you really want to do it all at once, try wrapping them in an NSDictionary. Encode the dictionary into NSData, and send it off.
Something like the following would work.
NSDictionary *myDict = //whatever your dict should hold here...
NSMutableData *packet = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:packet];
[archiver encodeObject:myDict forKey:#"SomeKey"];
[archiver finishEncoding];
I'm working with facebook connect and trying to handle the JSON object that i'm receiving.
I invoked the requstWithGraphPath method and need to get back a JSON object,
tried to parse it and getting an error:
SBJSON *parser = [[SBJSON new] autorelease];
NSData *data = [[NSData alloc] initWithData:result];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -> in this line - "[__NSCFDictionary length]: unrecognized selector sent to instance"
NSArray *events = [parser objectWithString:jsonString];
What's the problem?
Can I get the string in an other way or parse the object differently?
Thanks.
If you are working with the delegate callback
- (void)request:(FBRequest *)request didLoad:(id)result;
the parsing work has been done for you. Traverse the NSDictionary or NSArray to find the data you are looking for. If you are working with the delegate callback
- (void)request:(FBRequest *)request didLoadRawResponse:(NSData *)data;
you should initialize an NSString with the data, and use the category method that SBJSON adds to NSString for creating an id. That is assuming the data is data that constructs a string.
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
id result = [jsonString JSONValue];
Are you sure the error happens on that line, or does it happen on the line above?
If result is an NSDictionary (or CFDictionary, same thing), then it is already parsed and you do not need to do that yourself — and it could cause that error message too, on the line above.
The line:
data = [[NSData alloc] initWithData:result];
is almost certainly not what you want to do, as it is equivalent to
data = [result copy];
assuming that result is an NSData object (or NSMutableData), which I'm guessing it isn't.
I want to know to parse a json object in objective C. I got the JSON object by loading a url. Can u please tell me how to do it or any samples or any reference.
The following is the sample json.
{
"name":"WFNX",
"now":
{
"id":"17749528",
"song":"Back Down South",
"artist":"Kings Of Leon"
},
"desc":"101.7 - True Alternative",
"audiostream":"http:\/\/www.streamaudio.com\/stations \/asx\/wfnx_fm.asx",
"genre":"Rock",
"tz":"EST",
"id":"17880",
"yes":"station"
}
Checkout this JSON framework for Objective-C on code.google.com or on Github.
It is pretty straightforward to use. You instantiate your SBJSON object then call objectWithString with your buffer:
SBJSON * parser = [[SBJSON alloc] init];
NSString * buffer = #"{"name":"WFNX"}";
NSError* error = NULL;
// the type of json will depend on the JSON data in buffer, in this case, it will be
// and NSDictionary with one key/value pair "name"->"WFNX"
id json = [parser objectWithString:buffer error:&error];
There are a few out there, see:
http://code.google.com/p/json-framework/
http://github.com/schwa/TouchJSON
for a big list:
http://www.json.org/
is a great reference site for JSON
I'm using YAJLiOS parser,not bad and compatable with ARC, here's documentation
http://gabriel.github.com/yajl-objc/
and parser itself on github
https://github.com/gabriel/yajl-objc
ex.
NSData *JSONData = [NSData dataWithContentsOfFile:#"someJson.json"];
NSDictionary *JSONDictionary = [tempContainer yajl_JSON];
and getting objects by objectForKey method or valueFoKey method if you need an array
I access a RESTFUL url and get back results. The results are in JSON. I turn the response into a string via:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *json = [[NSString alloc] initWithBytes:[self.receivedData mutableBytes] length:[self.receivedData length] encoding:NSUTF8StringEncoding];
The json variable has a value of 0x0. When I mouse over it, I see <Invalid CFStringRef>. How can I debug this to tell why it is invalid? I render the JSON given back through the browser in A JSON parser. That checks out fine.
Results are given back by entering an ID in the URL. Other IDs return results without issue. The result set is fairly large.
First I would use initWithData:encoding: to setup the NSString. Small difference, but that method is there for a reason.
Then, I would do a hexdump of self.receivedData to see what is actually in there. If that data is not properly UTF8 encoded then the initWithData:encoding: will fail.
(Google for NSData hex dump to find other people's utility functions to do this)
I have found that sometimes web services are sloppy with their encoding. So I usually implement a fallback like this:
NSString* html = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
if (html == nil) {
html = [[NSString alloc] initWithData: data encoding: NSISOLatin1StringEncoding];
if (html == nil) {
html = [[NSString alloc] initWithData: data encoding: NSMacOSRomanStringEncoding];
}
}
It is kind of sad that this is required but many web services are not written or configured properly.
Use NSLog to look at the bytes.