简单而干净的方法来将JSONstring转换为Swift中的Object
我一直在寻找几天来转换一个相当简单的JSONstring在Swift中的对象types,但没有用。
以下是Web服务调用的代码:
func GetAllBusiness() { Alamofire.request(.GET, "http://MyWebService/").responseString { (request, response, string, error) in println(string) } }
我有一个Swift结构Business.swift:
struct Business { var Id : Int = 0 var Name = "" var Latitude = "" var Longitude = "" var Address = "" }
这里是我的testing服务部署:
[ { "Id": 1, "Name": "A", "Latitude": "-35.243256", "Longitude": "149.110701", "Address": null }, { "Id": 2, "Name": "B", "Latitude": "-35.240592", "Longitude": "149.104843", "Address": null } ... ]
如果有人指导我做这件事,那将是一件乐事。
谢谢。
这里有一些提示如何从简单的例子开始。
考虑你有以下JSON数组string(类似于你的),如:
var list:Array<Business> = [] // left only 2 fields for demo struct Business { var id : Int = 0 var name = "" } var jsonStringAsArray = "[\n" + "{\n" + "\"id\":72,\n" + "\"name\":\"Batata Cremosa\",\n" + "},\n" + "{\n" + "\"id\":183,\n" + "\"name\":\"Caldeirada de Peixes\",\n" + "},\n" + "{\n" + "\"id\":76,\n" + "\"name\":\"Batata com Cebola e Ervas\",\n" + "},\n" + "{\n" + "\"id\":56,\n" + "\"name\":\"Arroz de forma\",\n" + "}]" // convert String to NSData var data: NSData = jsonStringAsArray.dataUsingEncoding(NSUTF8StringEncoding)! var error: NSError? // convert NSData to 'AnyObject' let anyObj: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &error) println("Error: \(error)") // convert 'AnyObject' to Array<Business> list = self.parseJson(anyObj!) //=============== func parseJson(anyObj:AnyObject) -> Array<Business>{ var list:Array<Business> = [] if anyObj is Array<AnyObject> { var b:Business = Business() for json in anyObj as Array<AnyObject>{ b.name = (json["name"] as AnyObject? as? String) ?? "" // to get rid of null b.id = (json["id"] as AnyObject? as? Int) ?? 0 list.append(b) }// for } // if return list }//func
[编辑]
为了摆脱null更改为:
b.name = (json["name"] as AnyObject? as? String) ?? "" b.id = (json["id"] as AnyObject? as? Int) ?? 0
另请参见合并操作员参考(又称??
)
希望它能帮助你把事情弄清楚,
由于简单的string扩展应该足够了:
extension String { var parseJSONString: AnyObject? { let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) if let jsonData = data { // Will return an object or nil if JSON decoding fails return NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) } else { // Lossless conversion of the string was not possible return nil } } }
然后:
var jsonString = "[\n" + "{\n" + "\"id\":72,\n" + "\"name\":\"Batata Cremosa\",\n" + "},\n" + "{\n" + "\"id\":183,\n" + "\"name\":\"Caldeirada de Peixes\",\n" + "},\n" + "{\n" + "\"id\":76,\n" + "\"name\":\"Batata com Cebola e Ervas\",\n" + "},\n" + "{\n" + "\"id\":56,\n" + "\"name\":\"Arroz de forma\",\n" + "}]" let json: AnyObject? = jsonString.parseJSONString println("Parsed JSON: \(json!)") println("json[3]: \(json![3])") /* Output: Parsed JSON: ( { id = 72; name = "Batata Cremosa"; }, { id = 183; name = "Caldeirada de Peixes"; }, { id = 76; name = "Batata com Cebola e Ervas"; }, { id = 56; name = "Arroz de forma"; } ) json[3]: { id = 56; name = "Arroz de forma"; } */
为迅速3
extension String { func toJSON(): Any? { guard let data = self.data(using: .utf8, allowLossyConversion: false) else { return nil } return try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) } }
我写了一个库,可以在Swift中轻松使用json数据和反序列化。 你可以在这里: https : //github.com/isair/JSONHelper
编辑:我更新了我的图书馆,你现在可以做到这一点:
class Business: Deserializable { var id: Int? var name = "N/A" // This one has a default value. required init(data: [String: AnyObject]) { id <-- data["id"] name <-- data["name"] } } var businesses: [Business]() Alamofire.request(.GET, "http://MyWebService/").responseString { (request, response, string, error) in businesses <-- string }
老答案:
首先,不是使用.responseString,而是使用.response来获取响应对象。 然后将您的代码更改为:
func getAllBusinesses() { Alamofire.request(.GET, "http://MyWebService/").response { (request, response, data, error) in var businesses: [Business]? businesses <-- data if businesses == nil { // Data was not structured as expected and deserialization failed, do something. } else { // Do something with your businesses array. } } }
而且你需要像这样做一个商务课:
class Business: Deserializable { var id: Int? var name = "N/A" // This one has a default value. required init(data: [String: AnyObject]) { id <-- data["id"] name <-- data["name"] } }
你可以在我的GitHub仓库中find完整的文档。 玩的开心!
对于Swift 2.2
我使用@Passkit的逻辑,但我不得不根据Swift 2进行更新
Step.1 为String类创build扩展
import UIKit extension String { var parseJSONString: AnyObject? { let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) if let jsonData = data { // Will return an object or nil if JSON decoding fails do { let message = try NSJSONSerialization.JSONObjectWithData(jsonData, options:.MutableContainers) if let jsonResult = message as? NSMutableArray { print(jsonResult) return jsonResult //Will return the json array output } else { return nil } } catch let error as NSError { print("An error occurred: \(error)") return nil } } else { // Lossless conversion of the string was not possible return nil } } }
Step.2 这是我在视图控制器中使用的方法
var jsonString = "[\n" + "{\n" + "\"id\":72,\n" + "\"name\":\"Batata Cremosa\",\n" + "},\n" + "{\n" + "\"id\":183,\n" + "\"name\":\"Caldeirada de Peixes\",\n" + "},\n" + "{\n" + "\"id\":76,\n" + "\"name\":\"Batata com Cebola e Ervas\",\n" + "},\n" + "{\n" + "\"id\":56,\n" + "\"name\":\"Arroz de forma\",\n" + "}]" //Convert jsonString to jsonArray let json: AnyObject? = jsonString.parseJSONString print("Parsed JSON: \(json!)") print("json[2]: \(json![2])")
所有功劳都归原创用户,我刚刚更新为最新的迅捷版本
对于iOS 10
和Swift 3
,使用Alamofire & Gloss :
Alamofire.request("http://localhost:8080/category/en").responseJSON { response in if let data = response.data { if let categories = [Category].from(data: response.data) { self.categories = categories self.categoryCollectionView.reloadData() } else { print("Casting error") } } else { print("Data is null") } }
这里是Category类
import Gloss struct Category: Decodable { let categoryId: Int? let name: String? let image: String? init?(json: JSON) { self.categoryId = "categoryId" <~~ json self.name = "name" <~~ json self.image = "image" <~~ json } }
海事组织,这是迄今为止最优雅的解决scheme。
let jsonString = "{\"id\":123,\"Name\":\"Munish\"}"
将string转换为NSData
var data: NSData =jsonString.dataUsingEncoding(NSUTF8StringEncoding)! var error: NSError?
将NSData转换为AnyObject
var jsonObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) println("Error: \\(error)") let id = (jsonObject as! NSDictionary)["id"] as! Int let name = (jsonObject as! NSDictionary)["name"] as! String println("Id: \\(id)") println("Name: \\(name)")
我喜欢RDC的回应,但是为什么限制返回的JSON只有顶层的数组呢? 我需要允许在顶层的字典,所以我修改它:
extension String { var parseJSONString: AnyObject? { let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) if let jsonData = data { // Will return an object or nil if JSON decoding fails do { let message = try NSJSONSerialization.JSONObjectWithData(jsonData, options:.MutableContainers) if let jsonResult = message as? NSMutableArray { return jsonResult //Will return the json array output } else if let jsonResult = message as? NSMutableDictionary { return jsonResult //Will return the json dictionary output } else { return nil } } catch let error as NSError { print("An error occurred: \(error)") return nil } } else { // Lossless conversion of the string was not possible return nil } }
您可以使用swift.quicktype.io将JSON
转换为struct
或class
。 即使你可以提到版本的迅速到genrate代码。
示例JSON:
{ "message": "Hello, World!" }
生成的代码:
import Foundation typealias Sample = OtherSample struct OtherSample: Codable { let message: String } // Serialization extensions extension OtherSample { static func from(json: String, using encoding: String.Encoding = .utf8) -> OtherSample? { guard let data = json.data(using: encoding) else { return nil } return OtherSample.from(data: data) } static func from(data: Data) -> OtherSample? { let decoder = JSONDecoder() return try? decoder.decode(OtherSample.self, from: data) } var jsonData: Data? { let encoder = JSONEncoder() return try? encoder.encode(self) } var jsonString: String? { guard let data = self.jsonData else { return nil } return String(data: data, encoding: .utf8) } } extension OtherSample { enum CodingKeys: String, CodingKey { case message } }
Swift 4更加优雅地parsingJSON。 按照这个简单的例子,只要采用可编程的协议就可以了:
struct Business: Codable { let id: Int let name: String }
为了parsingJSON数组,你告诉解码器数据数组的对象是什么
let parsedData = decoder.decode([Business].self, from: data)
这是一个完整的工作示例:
import Foundation struct Business: Codable { let id: Int let name: String } // Generating the example JSON data: let originalObjects = [Business(id: 0, name: "A"), Business(id: 1, name: "B")] let encoder = JSONEncoder() let data = try! encoder.encode(originalObjects) // Parsing the data: let decoder = JSONDecoder() let parsedData = try! decoder.decode([Business].self, from: data)
欲了解更多背景,请查看这个优秀的指南 。