Generate JSON string from NSDictionary in iOS
Here are categories for NSArray and NSDictionary to make this super-easy. I've added an option for pretty-print (newlines and tabs to make easier to read).
@interface NSDictionary (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint;
@end
.
@implementation NSDictionary (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
error:&error];
if (! jsonData) {
NSLog(@"%s: error: %@", __func__, error.localizedDescription);
return @"{}";
} else {
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
@end
.
@interface NSArray (BVJSONString)
- (NSString *)bv_jsonStringWithPrettyPrint:(BOOL)prettyPrint;
@end
.
@implementation NSArray (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
error:&error];
if (! jsonData) {
NSLog(@"%s: error: %@", __func__, error.localizedDescription);
return @"[]";
} else {
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
@end
Issue in converting NSDictionary to json string, replacing / with \/
Converting JSON object to String will escape the forward slash. That is why the back slash is added in your result.
If you convert the string back to JSON object and logged the object, you can see the result as expected. Thus you can verify, there is nothing wrong with the string.
How to convert an NSDictionary to a JSON object?
Use the category that SBJSON adds to NSDictionary:
NSString *jsonString = [dictionary JSONRepresentation];
Just name the keys and values appropriately in the dictionary and SBJSON will do the work for you
How to generate JSON data from NSDictionary in Swift
Try below code, it may help to solve your problem.
var jsonResult = NSJSONSerialization.JSONObjectWithData(metricsData, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSArray
for var i = 0; i<jsonResult.count; ++i {
var dictResult = jsonResult.objectAtIndex(i) as! NSDictionary
// your code...
}
Post method nsdictionary to json object iOS objective c
Frankly, looking at your NSLog
results, it looks like the server code is erroneously returning some extra HTML (starting at the <script>
line) after the JSON result. Looking at the body of the $response
, it's reporting success, but it looks like some extra text is included in the response, either as a result of push_order
, or some HTML after after the %>
, or some web service error that is inserting some extra HTML.
Focusing on your client request code, it should set the Content-Type
and Accept
headers, though that’s not critical. But well designed requests should do that. The key issue is that the PHP should be outputting nothing else before or after the outputting of the JSON.
For what it's worth, if your web service was expecting a true JSON request, I would suggest a series of simplifications to your client code (in addition to setting those two additional headers). For example, just send the output of NSJSONSerialization
as the httpBody
; don't take that NSData
, convert it to a NSString
and then convert it back to a NSData
. Just send jsonData
as httpBody
:
NSDictionary *tvarns = @{@"order_cart": _order_cart};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tvarns
options:0
error:&error];
// if you want to see the JSON, you can do this, but this is not needed
//
// NSString *order_cart = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// NSLog(@"%@",order_cart);
// none of this stuff is needed; at worst, it can introduce encoding problems; at best, it's inefficient to do all that stuff
//
// NSString *post = [NSString stringWithFormat:@"%@",order_cart];
// NSLog(@"the data Details is %@", post);
// NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// // Next up, we read the postData's length, so we can pass it along in the request.
// NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
// Now that we have what we'd like to post, we can create an NSMutableURLRequest, and include our jsonData
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://test.kre8tives.com/barebon/add_cartapi.php"]];
[request setHTTPMethod:@"POST"];
// you don't need this, because NSURLSession sets the length for you
//
// [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
// use the original jsonData here
[request setHTTPBody:jsonData];
// you should, if you're a good web-service citizen, set the header; it's not always needed, but it's advisable
// tell the server that you're sending JSON request
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// tell the server that you're expecting JSON response
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
// Unless you need a new session for some reason, it's better to use the shared session
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"error: %@", error);
}
if (!data) {
return;
}
NSError *parseError;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; // you need to convert to dictionary object
if (jsonDict) {
NSLog(@"requestReply: %@", jsonDict);
} else {
NSLog(@"parseError: %@", parseError);
NSLog(@"response: %@", response); // when you have failure, it's sometimes useful to see what this says
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // this is json string
NSLog(@"requestReply: %@", requestReply);
}
}] resume];
Again, having suggested these simplifications, I really suspect that there's a bug in the server code, including all that junk after the <script>...
. I bet your Android code is ignoring all of this erroneous data at the end of the response, whereas NSJSONSerialization
is correctly pointing out that the response is not, technically, well-formed JSON. (By the way, my code above will correctly log the JSON error.)
Looking at your PHP code that you've added to your revised question, it's grabbing $order_cart=$_POST['order_cart'];
, which means that your web service is expecting a x-www-form-urlencoded
request. The PHP code then proceeds to define $items
as json_decode($order_cart,true)
and then iterate with foreach
through $items['order_cart']
. That means that the web service is expecting x-www-form-urlencoded
request whose value associated with order_cart
key is, itself, a JSON dictionary keyed by order_cart
(again), i.e., the request body will look like order_cart={"order_cart":[...]}
.
That's not a very elegant design, but if you're stuck with that, you're going to have to create x-www-form-urlencoded
request whose key is order_cart
and whose value is a percent-encoded representation of a JSON dictionary of the form {"content-type":[...]}
.
NSDictionary *tvarns = @{@"order_cart": _order_cart};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tvarns
options:0
error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *bodyString = [NSString stringWithFormat:@"order_cart=%@", [jsonString stringByAddingPercentEncodingQueryValue]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://test.kre8tives.com/barebon/add_cartapi.php"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
// Unless you need a new session for some reason, it's better to use the shared session
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"error: %@", error);
}
if (!data) {
return;
}
NSError *parseError;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; // you need to convert to dictionary object
if (jsonDict) {
NSLog(@"requestReply: %@", jsonDict);
} else {
NSLog(@"parseError: %@", parseError);
NSLog(@"response: %@", response); // when you have failure, it's sometimes useful to see what this says
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // this is json string
NSLog(@"requestReply: %@", requestReply);
}
}] resume];
Where:
@interface NSCharacterSet (URLQueryValue)
/**
Character set of characters allowed within value (or a key) in a application/x-www-form-urlencode key/value pair.
@return NSCharacterSet of allowed characters.
*/
+ (NSCharacterSet *) URLQueryValueAllowedCharacterSet;
@end
@implementation NSCharacterSet (URLQueryValue)
+ (NSCharacterSet *) URLQueryValueAllowedCharacterSet {
static NSString * const generalDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
static NSString * const subDelimitersToEncode = @"!$&'()*+,;=";
NSString * const characterToEncode = [generalDelimitersToEncode stringByAppendingString:subDelimitersToEncode];
NSMutableCharacterSet *cs = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[cs removeCharactersInString:characterToEncode];
return cs;
}
@end
And
@interface NSString (URLQueryValue)
/**
String percent encoding for key or value in key/value pair within an application/x-www-form-urlencoded request.
@return Percent encoded string.
*/
- (NSString *)stringByAddingPercentEncodingQueryValue;
@end
@implementation NSString (URLQueryValue)
- (NSString *)stringByAddingPercentEncodingQueryValue {
return [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
}
@end
Frankly, I'd suggest changing the web service to process a true JSON request, not JSON within a x-www-form-urlencoded
request. If you did that, the client code would look more like my original answer above. But for your existing web service code, you'd create something like my second code sample.
how can i parse a json string into nsdictionary?
Example data:
NSString *strData = @"{\"1\": {\"name\": \"Jerry\",\"age\": \"12\"}, \"2\": {\"name\": \"Bob\",\"age\": \"16\"}}";
NSData *webData = [strData dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:webData options:0 error:&error];
NSLog(@"JSON DIct: %@", jsonDict);
NSLog output:
JSON DIct: {
1 = {
age = 12;
name = Jerry;
};
2 = {
age = 16;
name = Bob;
};
}
Converting NSDictionary to Json String causes re-ordering of elements
You cannot and should not rely on the ordering of elements within a JSON object.
JSON Object is a key-value pair, there is no order, and you can't order it and last the order won't matter
For more detail check json.org
JSON string from NSDictionary having file path
The path separators shouldn't be a problem when converting your dictionary to a JSON string.
Your sample doesn't show the type & initialization of your json
variable but you can obtain a JSON representation from your dict the following way:
NSDictionary* jsonDict = @{ @"background": @"file://localhost/var/mobile/Applications/6118A03F-345B-42D5-AC19-25F6D9AC4484/Documents/background.caf",
@"bgMusic": @"file://localhost/var/mobile/Applications/6118A03F-345B-42D5-AC19-25F6D9AC4484/Documents/bgMusic.caf"};
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:nil];
NSString* jsonString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
NSLog(@"Dict:%@", jsonString);
This works fine here (including proper escaping for the path separators in the log line)
NSDictionary to json string to json object using SwiftyJSON
According to the docs, this should be all you need.
var data = [Dictionary<String, String>]()
//append items
var jsonObj = JSON(data)
println(jsonObj)
println(jsonObj[0])
Are you having a problem with converting an array directly into a JSON
object?
Related Topics
Why Is the Tab Bar Disappearing
Swift - Json Error: the Data Couldn'T Be Read Because It Isn'T in the Correct Format
Redirect to Application If Installed, Otherwise to App Store
How to Add Spacing Between Uitableviewcell
Update Badge With Push Notification While App in Background
Force View Controller to Reload to Refresh Uiappearance Changes
React-Native, How to Get File-Asset Image Absolute Path
Ios: How to Make a Shadow for Uiview on 4 Side (Top,Right,Bottom and Left)
Download Array of Images as Byte Array and Convert to Images
Firebase Custom Event Parameters Not Visible in Console
How to Display 3 Cells Per Row in Uicollectionview
Nsdictionary to Nsdata and Nsdata to Nsdictionary in Swift
How to Prevent Tableview Section Head from Sticking While Scrolling
Wkwebview Origin Null Is Not Allowed by Access-Control-Allow-Origin
Swift Parse Json - the Data Couldn'T Be Read Because It Isn'T in the Correct Format