What I am trying to achieve:
Convert a Dictionary to NSData which contains normal text as well as an image:
let payload: Dictionary<String, AnyObject> = [
"some_item": "some_value",
"img": UIImagePNGRepresentation(img)!
]
let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(payload)
Send this data to the server using WebSocket writeData
Parse the array of bytes to get a JSON string and save the image and send back some response.
I am using Rails4 as the backend and I have tried pack but it doesn't work. I am not sure if this is doable or not.
I know Base64 encoding will work instead of byte data, but it's a bit slower than what I would prefer.
First you need to stop using NSKeyedArchiver and instead use NSJSONSerialization.Tl his will generate actual JSON data for you that you should be able to unpack easily on the server.
When using an image you either:
don't use JSON with it
convert the image data into base64 and create the JSON including that text
use multi-part form upload with a section for the image and another for the rest of the JSON
Related
When downloading data from server JSON feed, I can't parse the data received as the data has this É . I am running in swift4. I create a copy the data file into my project locally and the parsing works, using JSONDecoder().decode with the data structure no problem.
I believe it has something to do with how I create my request object or session config but I am not too versed in this area.
I think its from charset=ISO-8859-1
don't know how to use this in my request/session to handle this character
spent a lot of time on this not sure where to look
I found the solution to my problem.
All I needed to do was convert the data from charset=ISO-8859-1 to utf8
I created a NSString out of the data returned from the response.
let responseString = NSString(data: data!, encoding:
String.EncodingConversionOptions.allowLossy.rawValue)
let s = responseString! as String
let d = Data(s.utf8)
then I was able to pass the converted Data object into the JSONDescoder()
now I am new to programming so if there is a better way I could have done this I would like feedback because String.EncodingConversionOptions.allowLossy.rawValue was just through trial and error.
thank you
Peter
I generated a json using NSJSONSerialization.This is my code:
// parameters is `Dictionary<String, AnyObject>?`
let json = try! NSJSONSerialization.dataWithJSONObject(parameters!, options: NSJSONWritingOptions.init(rawValue: 0))
request.HTTPBody = json
But my server received this:
"{login:23232432434,mobile_captcha:,password:22e233434}"=>"[FILTERED]"
It seems server takes the whole json as a key and I think this because of that ".Maybe there is other reasons,please help me!
Those aren’t brackets; they’re (double) quotes/quotation marks. In valid JSON, quotation marks inside strings must be escaped with \, e.g. "Hello \"World\"".
The Web service you’re using is returning invalid JSON.
http://jsonlint.com is a useful resource to validate JSON strings.
I have a JSON that has one field that in itself contains another JSON. I am having trouble parsing values from this embedded JSON. I am using SwiftyJSON and can extract the embedded JSON as JSON type (swiftyJSON type). But I am unable to do anything with it further to get values from the embedded JSON.
thisjson[0]["MESSAGE_JSON_BODY"] will return a JSON type.
thisjson[0]["MESSAGE_JSON_BODY"].string will convert this JSON to string.
Now I need help parsing fields from MESSAGE_JSON_BODY JSON. How to parse the fields in the embedded JSON?
I figured out one way to solve this problem myself, here I print out the field value for "fieldkey":
if let stringdata: String = thisjson[0]["MESSAGE_JSON_BODY"].string{
var data: NSData = stringdata.dataUsingEncoding(NSUTF8StringEncoding)!
let msgjson = JSON(data: data)
println(msgjson["fieldkey"])
}
I have to pass JSON dictionary as POST data to a Webservice. One key involves an Amazon S3 URL string.
The sample request json which works has the URL as....
https:\/\/myappbucket.s3.amazonaws.com\/2014230407_102323.jpg?response-content-type=image\/png&Signature=123456%3D&Expires=139756222548&AWSAccessKeyId=ABCDEF
Notice the backslashes just before the forwardslashes? I have never seen a URL like that, but thats how I'm supposed to pass it.
I tried
stringByAddingPercentEscapesUsingEncoding
and
stringByReplacingPercentEscapesUsingEncoding
while using NSASCIIStringEncoding and NSUTF8StringEncoding
Can anyone make sense of this?
if we try to convert url into legal url trough stringByAddingPercentEscapesUsingEncoding than it adds all percent escapes necessary to convert the receiver into a legal URL string.Uses the given encoding to determine the correct percent escapes.
if we use stringByReplacingPercentEscapesUsingEncoding than it replaces all percent escapes with the matching characters as determined by the given encoding.
mostly to get valid url, we can use NSUTF8StringEncoding to remove backslashes just before the forwardslashes in url.
Generally, you should use a JSON serializer library (e.g. NSJSONSerialization) in order to obtain a JSON from a JSON representation and not try to create the JSON yourself.
A JSON representation is a NSDictionary or NSArray object containing other objects which recursively represent your JSON. Your URL will be represented as a NSString.
What you need to do is simply have a valid URL as a NSString, properly encoded according RFC 3968 and assign it the JSON representation, e.g.:
NSURL* url = ...;
NSDictionary* jsonObject = #{#"url": [url path]};
Now, you can serialize the JSON representation to a JSON:
NSError* error;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonObejct
options:0
error:&error];
That's it, and you don't bother how the JSON encoded string looks like (encapsulated in the NSData object as a UTF-8 character sequence).
Purposefully, when you POST this JSON, you SHOULD specify a corresponding request header:
ContentType: application/json
which lets you just use the JSON data as body data as is:
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
request.HTTPBody = jsonData;
Side note: [url path] returns a URL as a string according RFC 1808 which is obsoleted by RFC 3968 since January 2005 already. Today, there are newer APIs since iOS 7.0, see NSURLComponents.
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.