31

I'm having problems converting a JSON element into NSData, and an NSData variable back into JSON in Swift.

Firstly, I'd like to extract the encryptedData element of the following JSON data:

{
    "transactionID" : 12345,
    "encryptedData" : [-67,51,-38,61,-72,102,48]
}

into an NSData encryptedData variable but can't seem to be able to do it. I'm using SwiftyJSON to parse the JSON as follows:

let list: Array<JSON> = json["encryptedData"].arrayValue!

But this gives me an array of ScalarNumber which I don't know how to store into an NSData object.

Secondly, I'd like to generate JSON back from the same NSData object:

let jsonObject = [
    "transactionID" : 12345,
    "encryptedData" : encryptedData
]

But the NSData encryptedData object doesn't get converted into [-67,51,-38,61,-72,102,48], it just seems to nullify the JSON string.

Any ideas?

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
John Smith
  • 415
  • 1
  • 6
  • 11

7 Answers7

27

Here is code to convert between JSON and NSData in swift 2.0 (adapted from Shuo's answer)

// Convert from NSData to json object
func nsdataToJSON(data: NSData) -> AnyObject? {
    do {
        return try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil
}

// Convert from JSON to nsdata
func jsonToNSData(json: AnyObject) -> NSData?{
    do {
        return try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil;
}
Ciprian Rarau
  • 3,040
  • 1
  • 30
  • 27
  • 2
    @SunilTarge Xcode does a fair job of converting it for you if you follow the warnings, that way you'll also quickly pick up the differences between Swift 2 and 3. – Leon Feb 24 '17 at 09:26
  • but Its gives error whenever I resolve Warnings. @Leon – Bhumesh Purohit Jan 23 '18 at 08:53
  • @Bhumesh-Purohit Well we're now onto Swift 4, are you trying to migrate from 2 to 4? You'd need to post some code and the subsequent errors. – Leon Jan 23 '18 at 16:21
  • Really useful! This link https://developer.apple.com/swift/blog/?id=37 explains how to explore the created JSON object – Andrea Gorrieri Jan 25 '18 at 13:27
18

In SwiftyJSON you can use rawData method to get NSData:

if let encryptedData:NSData = json["encryptedData"].rawData() {
    NSLog(NSString(data: encryptedData, encoding: NSUTF8StringEncoding)!)
}

To generate JSON as you want you should convert data to array object:

if let encryptedDataArray = JSON(data: encryptedData).arrayObject {
    let jsonObject:JSON = [
        "transactionID" : 12345,
        "encryptedData" : encryptedDataArray
    ]
    NSLog(NSString(data: jsonObject.rawData()!, encoding: NSUTF8StringEncoding)!)
}
Tish
  • 497
  • 3
  • 9
  • Hi Tish, thank you very much for your response. Unfortunately SwiftyJSON does not support 'rawValue()'. I would had expected SwiftyJSON to support something like this. – John Smith Nov 10 '14 at 16:18
  • It does according to documentation. But rawValue is not a method, it is a property. Unlike a rawData() method which you can see in my response. You can find examples at GitHub documentation: https://github.com/SwiftyJSON/SwiftyJSON#raw-object – Tish Nov 10 '14 at 17:18
13

I have no idea on SwiftyJSON. I use following code snippet to convert between json and nsdata

// Convert from NSData to json object
public class func nsdataToJSON(data: NSData) -> AnyObject? {
    return NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil)
}

// Convert from JSON to nsdata
public class func jsonToNSData(json: AnyObject) -> NSData?{
    return NSJSONSerialization.dataWithJSONObject(json, options: .allZeros, error: nil)
}
Shuo
  • 8,447
  • 4
  • 30
  • 36
  • Thanks for your response Shuo, I'm not sure how to use your solution, ie how do I pass in the key 'encryptedData' to identify the data I want to get back? Thanks for your help! – John Smith Nov 10 '14 at 16:28
8

@Sunil Targe here is the Swift3 version. Hope this helps. (Adapted from Ciprian Rarau's answer)

Convert data to JSON

func dataToJSON(data: Data) -> Any? {
   do {
       return try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
   } catch let myJSONError {
       print(myJSONError)
   }
   return nil
}

Convert from JSON to data

func jsonToData(json: Any) -> Data? {
    do {
        return try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil;
}
FromTheStix
  • 429
  • 5
  • 10
  • 1
    Thanks you. Note, this can be done in one single line of code, by returning `try?` (for those who don't need to print `myJSONError`). – frouo Mar 09 '17 at 16:58
8

Swift 4 that works for me:

// Convert from JSON to nsdata
func jsonToNSData(json: AnyObject) -> NSData?{
    do {
        return try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil;
}
eddieespinal
  • 91
  • 1
  • 2
3
class ViewController: UIViewController {

    let requestURL : NSURL = NSURL(string: "http://www.learnswiftonline.com/Samples/subway.json")!
    let session = URLSession.shared

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchData()
    }

    func fetchData()
    {
        let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL)
        let task = session.dataTask(with: urlRequest as URLRequest) { (data, response, error) -> Void in

            let httpResponse = response as! HTTPURLResponse
            let statusCode = httpResponse.statusCode

            if(statusCode == 200)
            {
                do {
                    let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
                    print(jsonResponse as! NSDictionary)
                }
                catch let error
                {
                    print(error)
                }
            }
        }
        task.resume()

    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Ekambaram E
  • 1,184
  • 1
  • 11
  • 9
  • I hate when people downcasts such posts. I've been searching and didn't find anyone who will show how to parse the data without decoding/encoding. Thank you! – J A S K I E R Jul 16 '18 at 16:36
1

Swift 5 with SwiftyJSON that works for me:

import SwiftyJSON

func getDataFrom(JSON json: JSON) -> Data? {
    do {
        return try json.rawData(options: .prettyPrinted)
    } catch _ {
        return nil
    }
}

func getJSONFrom(Data data: Data) -> JSON? {
    do {
        return try JSON(data: data, options: .mutableContainers)
    } catch _ {
        return nil
    }
    
}