Convert NSString to NSDictionary and NSDictionary to NSString
ios, nsdata, nsdictionary, nsstring
Solution
Apple provides a Dictionary -> String method that has no inverse
Huh? False. And no, you are not supposed to rely on `description`. Use property lists instead.
Forwards:
NSData *plist = [NSPropertyListSerialization
dataWithPropertyList:theDict
format:NSPropertyListXMLFormat_v1_0
options:kNilOptions
error:NULL];
NSString *str = [[NSString alloc] initWithData:plist encoding:NSUTF8StringEncoding];
Backwards:
NSDictionary *dict = [NSPropertyListSerialization
propertyListWithData:[str dataUsingEncoding:NSUTF8StringEncoding]
options:kNilOptions
format:NULL
error:NULL];
Sidenote:
and works perfectly so long as your Dictionary is only basic datatypes
those are called "property list objects".
Problem
There are many questions on this already, but the answers given are situation-specific, answering the poster's personal problem rather than the question title. I would like to know if there is a general, universal, easy way to convert an `NSString` to an `NSDictionary`, and vice versa? I've got difficult/complex/non-cross-platform approaches, but surely there must be an easier way? Here's what I know / have tested: - Apple provides a `Dictionary` -> `String` method that has no inverse, and works perfectly so long as your Dictionary is only basic datatypes, arrays, and dictionaries. This covers most real-world cases, but Apple doesn't give an inverse :(. - `[myDictionary description];` - // no way back ? Why not? - Apple has an intermediate approach using `NSData` that fails silently, so that it only works in a LIMITED set of real-world cases: - `[myString dataUsingEncoding:NSUTF8StringEncoding];` - `[[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];` // NB: silently fails in many cases, returns nil string - Apple has MULTIPLE, INCOMPATIBLE ways of converting `NSDictionary` -> `NSData` -> `NSDicitonary` that work well - but they are using `NSData`, so they are not a straight conversion, and they are harder to work with - KeyedArchiver: - `[NSKeyedArchiver archivedDataWithRootObject:myDictionary];` - `[NSKeyedUnarchiver unarchiveObjectWithData:myData];` - PropertyListSerialization: - `[NSPropertyListSerialization dataFromPropertyList:plist format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];` - `[NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];` - NSJSONSerialization: - `[NSJSONSerialization JSONObjectWithData:myData options:0 error:nil];` - `[dataWithJSONObject:myDictionary options:0 error:nil];` As it stands, the only route that is GUARANTEED to work appears to be: Write lots of code to output a verbose `XML` or `JSON`, converting it to `NSData`, then converting back into `NSString`, and send that on the wire. Anything else has a slightly-less-than-100% success rate. Unfortunately, this technique turns a very common problem (string -> dictionary -> string) into a multiline chunk of silly boilerplate code we shouldn't be writing. Also ... the `XML`-or-`JSON` approach is the only one that correctly reports failures (if they occur) - both the encoding systems take `NSError` pointers.