在Swift中将JSON转换为NSData,以及将NSData转换为JSON

31

我遇到了将JSON元素转换为NSData和将NSData变量转换回JSON的问题,希望能得到帮助。

首先,我想提取以下JSON数据的encryptedData元素:

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

我希望将数据存储在一个名为encryptedData的NSData变量中,但似乎无法实现。 我正在使用SwiftyJSON解析JSON,如下所示:

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

但这给了我一个ScalarNumber数组,我不知道如何将其存储到NSData对象中。

其次,我想从同一NSData对象生成JSON

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

但是 NSData 的 encryptedData 对象并没有被转换成 [-67,51,-38,61,-72,102,48],它似乎只是将 JSON 字符串置空了。

有什么想法吗?

7个回答

27

这是在Swift 2.0中转换JSON和NSData的代码(改编自Shuo的答案)

// 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;
}

2
@SunilTarge 如果你遵循警告,Xcode会为你做出公平的转换,这样你也会很快地掌握Swift 2和3之间的区别。 - Leon
但是每当我解决警告时,它就会出现错误。@Leon - Bhumesh Purohit
@Bhumesh-Purohit 嗯,我们现在使用的是Swift 4,你想从2迁移到4吗?你需要发布一些代码和随后出现的错误。 - Leon
非常有用!这个链接 https://developer.apple.com/swift/blog/?id=37 解释了如何探索创建的 JSON 对象。 - Andrea Gorrieri

18

在 SwiftyJSON 中,您可以使用 rawData 方法获取 NSData:

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

为了按照你的要求生成JSON,你应该将数据转换成数组对象:

if let encryptedDataArray = JSON(data: encryptedData).arrayObject {
    let jsonObject:JSON = [
        "transactionID" : 12345,
        "encryptedData" : encryptedDataArray
    ]
    NSLog(NSString(data: jsonObject.rawData()!, encoding: NSUTF8StringEncoding)!)
}

嗨Tish,非常感谢您的回复。不幸的是,SwiftyJSON不支持'rawValue()'。我本来期望SwiftyJSON会支持类似这样的功能。 - John Smith
它按照文档所述进行操作。但是rawValue不是一个方法,而是一个属性。与您在我的响应中看到的rawData()方法不同。您可以在GitHub文档中找到示例:https://github.com/SwiftyJSON/SwiftyJSON#raw-object - Tish

13

我对SwiftyJSON一无所知。我使用以下代码片段在JSON数据和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,我不确定如何使用您的解决方案,即如何传递密钥“encryptedData”以标识我想要获取的数据?感谢您的帮助! - John Smith

8

适合我使用的Swift 4:

// 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;
}

8

@Sunil Targe这里是Swift3版本,希望能对你有所帮助。(改编自Ciprian Rarau的答案)

将数据转换为JSON格式

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

将JSON转换为数据

func jsonToData(json: Any) -> Data? {
    do {
        return try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil;
}

1
感谢您。请注意,这可以通过返回“try?”(对于那些不需要打印“myJSONError”的人)的一行代码来完成。 - frouo

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()

    }
}

我讨厌人们对这样的帖子进行贬低。我一直在寻找,但没有找到任何人能够展示如何在不解码/编码的情况下解析数据。谢谢! - J A S K I E R

1
"使用SwiftyJSON的Swift 5对我有效:"
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
    }
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接