JSONKit (in RestKit) converting JSON into NSArray - ios

I'm using RestKit for HTTP requests, and with some request, I get JSON response with some busses:
[{"bus_number":"1","created_at":"2011-08-15T23:07:52Z","id":1,"model":"Setra","registar_number":"123456","seats":50,"tour_id":1,"updated_at":"2011-08-15T23:07:52Z"},{"bus_number":"2","created_at":"2011-08-15T23:07:52Z","id":2,"model":"Mercedes","registar_number":"2234","seats":60,"tour_id":1,"updated_at":"2011-08-15T23:07:52Z"}]
I'm getting it into method:
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
NSLog(#"%#", [response bodyAsString]);
}
Becouse, I have multiple busses in this JSON, how can I easily parse/decode or whathever do to convert this into NSArray or something for easily accesing into elements?
EDIT: I need code sample how to do this with JSONKit, who is already implemented in RESTKit.

json-framework is one of many third-party libraries you can use to parse JSON.

Related

Woo-Commerce REST API response correct on Postman not in Xcode

I am implementing a "POST" api for creating an order through woo-commerce:
POST http://www.url.in/wp-json/wc/v1/orders
I am also using external library Oauth1 for it which uses one-legged authentication for it. Now when I run the API on Postman, it gives me correct response, but in the code it gives me error:
{
"code":"woocommerce_rest_cannot_create",
"message":"Sorry, you are not allowed to create resources.",
"data":{"status":401}
}
In my code I am creating a NSDictionary , I change it to NSData through NSJSONSerialization and sending it as HTTPBody along with the request.
Check the attached screen shot of Postman and Xcode.
[
The problem lied in the JSON data I was posting. Instead of posting NSDictionary , I had to post it as NSString. It worked like a charm after that.

NSURLConnection retrieving JSON

I am using PromiseKit and I want to retrieve a JSON file.
[NSURLConnection GET:#"http://127.0.0.1/pack01.json"].then(^(NSDictionary *json) {
NSArray *questions = json[#"questions"];
Everything is fine on localhost but when I try it from another source (same file) it gives me an error:
[NSURLConnection GET:#"https://dl.dropboxusercontent.com/u/11377305/resources/pack01.json"].then(^(NSDictionary *json) {
NSArray *questions = json[#"questions"];
Error
[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0xb07c880
JSON file:
https://dl.dropboxusercontent.com/u/11377305/resources/pack01.json
Why is it working on localhost?
I would appreciate any suggestions or even any thoughts on what questions I should be asking.
The error indicates that you're being passed an NSData rather than an NSDictionary from the remote URL.
The PromiseKit documentation states:
PromiseKit reads the response headers and decodes the result you actually wanted (in a background thread):
Therefore it's a safe bet that your remote server (which is DropBox in this case) isn't indicating that the returned data is formatted as JSON. So PromiseKit isn't parsing it.
EDIT: confirmed. DropBox is returning:
Content-Type text/plain; charset=utf-8
So PromiseKit has no way of knowing that the included data is meant to be JSON. You need a server that will return an application/json Content-Type. Or else you can force the JSON parse yourself, but then you're missing out on a large part of the PromiseKit benefit as you end up writing the same boilerplate code as the rest of us.

Sailsjs SocketIO in iOS

I'm having a hard time wrapping my mind around a socket based chat app that I'm trying to do. I'm using sailsjs for my server side framework and trying to create a chat based app in iOS using SocketIO-Obj!
I have a successful handshake with the sailsjs framework, and the onConnect method in the sailsjs config/sockets.js file runs. but then after it's open how can I route to the controllers and actions I've created and still be able to access the request socket and subscribe them to my models
Assuming you use the latest version of sails(0.10.0 and later), the protocol that sails uses on socket.io is not public, but you can read the source on the part how it's made, and how it is interpreted.
Basically it will emit an event, with the http verb as the event name and an object method, data, urls and headers. Something like this in Javascript:
var request = {
data: data,
url: url,
headers: headers
};
socket.emit(method, request, callback);
method must be something like 'head', 'get', 'post' and etc.
data should be an object sending the request body. Optional.
url must be a string with no trailing slashes or spaces, like '/buy-a-cat' or '/cat/1/pat'.
headers should be an object, map of header names and values. Header names are lower-cased. Like { accept: '*/*' }. Optional.
I don't know much of objective-C and haven't tested this code, but you can do something like this, I think:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:#"/cats" forKey:#"url"];
SocketIOCallback cb = ^(id argsData) {
NSDictionary *response = argsData;
// do something with response
};
[socketIO sendEvent:#"get" withData:dict andAcknowledge:cb];
Which in http request notation it would be equal to: GET /cats
Note that if you are using sails 0.9.x or lower the protocol is slightly different. Also do note that since sails isn't stable yet(not 1.x.x) this could change again, since this is not documented anywhere.
I have also found a project making sails http calls with SocketIO-Obj. It looks to be using 0.9.x protocol, but should be compatible with 1.x.x.
It looks like you can do this in it:
#import "SocketIO+SailsIO.h"
_socket = [[SocketIO alloc] initWithDelegate:self];
[_socket connectToHost:#"localhost" onPort:1337];
[_socket get:#"/user" withData:nil callback:^(id response) {
NSLog(#"Records: %#", response);
}];

How to send a XML formatted POST request with RestKit 0.20.1

I have an iOS app that is using RestKit 0.20.1 to pull data from a server. The server at this time can send JSON formatted data but is not able to receive JSON formatted data.
This is where my problem is. POST requests require HTTP Body and the server is set up to receive XML. I have implemented the RKXMLReaderSerialization add on so I can receive XML but I can't find any current way of sending an XML formatted HTTP Body with RestKit.
This question "Send post request in XML format using RestKit " is what I was looking for but the answer from Imran Raheem is now (as far as I can tell) obsolete due to changes in RestKit.
I am using this method for the POST
[[RKObjectManager sharedManager] postObject:nil path:#"/rest/search?ip=255.255.255.0" parameters:search success:nil failure:nil];
Here is what the RestKit objectManager says about the postObject method
/**
Creates an `RKObjectRequestOperation` with a `POST` request for the given object, and enqueues it to the manager's operation queue.
#param object The object with which to construct the object request operation. If `nil`, then the path must be provided.
#param path The path to be appended to the HTTP client's base URL and used as the request URL. If nil, the request URL will be obtained by consulting the router for a route registered for the given object's class and the `RKRequestMethodPOST` method.
#param parameters The parameters to be reverse merged with the parameterization of the given object and set as the request body.
#param success A block object to be executed when the object request operation finishes successfully. This block has no return value and takes two arguments: the created object request operation and the `RKMappingResult` object created by object mapping the response data of request.
#param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred.
If I have the MIMEType set to JSON the Trace shows my request.body is being populated like so request.body={"Search":"Trending"}.
However if I set the MIMEType to XML the Trace shows the request.body=(null)
Here is the line I use to change the MIMEType
[RKObjectManager sharedManager].requestSerializationMIMEType = RKMIMETypeJSON;
I am pretty new to iOS and Objective-C so I may be setting up the NSDictionary that is used in the parameters of the `postObject' method wrong. Here it is just in case....
NSArray *objects =[NSArray arrayWithObjects:#"trending", nil];
NSArray *keys =[NSArray arrayWithObjects: #"Search",nil];
NSDictionary *params = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
self.search=params;
Any help would be greatly appreciated! Given that I am new Snippets are especially helpful!
Oh and BTW if anyone can point me to REST method that accepts JSON input I would gladly pass it on to my server guy so I can just avoid XML all together.
As feared and suggested in other posts on this topic writing XML is not supported in version of RestKit 0.20.1. Here is a link to my conversation with Blake Watters on the subject.
https://github.com/RestKit/RestKit/issues/1430#issuecomment-19150316
I never did clear up why the request.body= (null) when the MIMEType is set to XML.
The manager of the server has agreed to set it up to receive JSON. That is how I plan to work around this.

Serialize JSON without wrapping in [ ]

I am trying to make an HTTP PUT request to a CouchDB server. I am converting an NSString instance to NSData. I then convert this NSData instance to an NSArray and attempt to PUT this to CouchDB. So something like this:
//convert string to NSData
NSData *docData = [#"{\"name\":\"nick\"}" dataUsingEncoding:NSUTF8StringEncoding];
//NSData to NSArray
NSArray *arrayJson = [NSArray arrayWithObjects:[NSJSONSerialization JSONObjectWithData:docData options:kNilOptions error:nil],nil];
I am then creating an HTTP PUT request using AFNetworking (which is rad btw ;))
The problem is that this creates a json string which looks like:
[{"name":"nick"}]
This is valid JSON but Couch complains with 400 Bad JSON. Removing the [ ]s fixes the problem. I'm sure these brackets are the result of converting NSData to NSArray but I'm not sure how else to accomplish this using NSJSONSerialization. Can anyone help?
Thanks!
Edit
For clarity sake let me explain the problem I was having further. I am creating a document using the CouchDB HTTP API using a PUT HTTP request. The document could be hand coded JSON and that is why I have this parsing challenge. Couch expects a single document to create. Therefore it expects a single JSON object. NOT an array of them. That seems to be why [{"key":"value"}] returns a 400 HTTP response from Couch. Even if the array contains a single object. Seems a bit picky that the API wouldn't just infer correctly based on the array length.. but I guess you could argue either way. See the selected answer below. This is what I was looking for. Thanks to all those who responded!
You can let NSJSONSerialization do the conversion from Foundation object to string. This guarantees proper escaping and makes the code more readable.
If you have a key-value pair as in your sample above, you could do:
NSError* error = nil;
NSDictionary* jsonDict = #{#"name": #"nick"};
NSData* putData = [NSJSONSerialization dataWithJSONObject:jsonDict options:kNilOptions error:&error];
You should be able to directly put that into the content of your PUT request, without wrapping it in an additional array. If the endpoint that handles the request requires you to send an array, you should create the array as an Foundation object (NSArray) and serialize that as JSON before sending it to the server:
NSArray* jsonArray = #[#{#"name": #"nick"}];
The title of your question is "Deserialize JSON without wrapping in [ ]" - Shouldn't that be "Serialize JSON without wrapping in [ ]"?
I changed it, please change it back if I misunderstood your question.

Resources