Doug Smith
Doug Smith

Reputation: 29314

How do I store serialize an NSDictionary with NSJSONSerialization when one of the values is NSData?

Take this simplified example:

let dict: [String: AnyObject] = ["foo": ("bar" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!9]

let json = try! NSJSONSerialization.dataWithJSONObject(dict, options: [])

I cannot get that to run, it crashes with:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (NSConcreteMutableData)'

I need to send a block of JSON to my server, where some values are strings and some are NSData. What am I doing wrong?

Upvotes: 1

Views: 271

Answers (2)

Duyen-Hoa
Duyen-Hoa

Reputation: 15784

You can also convert your NSData into Base64 Encoded string in order to set to your json content.

let base64String = rawData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)

and decoding:

let rawData = NSData(base64EncodedString: base64String, options: .IgnoreUnknownCharacters)

Upvotes: 0

Aaron Brager
Aaron Brager

Reputation: 66242

It's worth your time to read through the JSON RFC. Note:

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

JSON can't represent raw data, so you'll need to convert the NSData to one of those other types (typically a string). One common approach is:

let stringFromData = NSString(data: data, encoding: NSUTF8StringEncoding)

Just make sure you and your server agree on which encoding you'll use.

If you have a lot of these, you can map through your dictionary and convert them at once. There are a few possible implementations depending on your structure; here's one approach:

let dictWithString = dict.map { (key, value) -> (String, NSObject) in
    if let value = value as? NSData {
        return (key, NSString(data: value, encoding: NSUTF8StringEncoding)!)
    }

    return (key, value)
}

Upvotes: 2

Related Questions