我需要“复制”从JSON中的远程Web API服务返回的entiry。它看起来像这样:
{
"field1": "some_id",
"entity_name" = "Entity1"
"field2": "some name",
"details1": [{
"field1": 11,
"field2": "some value",
"data": {
"key1": "value1",
"key2": "value2",
"key3": "value3",
// any other, unknown at compile time keys
}
}],
"details2": {
"field1": 13,
"field2": "some value2"
}
}
这是我的尝试:
struct Entity1 {
struct Details1 {
let field1: UInt32
let field2: String
let data: [String: String]
}
struct Details2 {
let field1: UInt32
let field2: String
}
let field1: String
static let entityName = "Entity1"
let field2: String
let details1: [Details1]
let details2: Details2
}
像这样:
//doesn't compile
struct Entity1 {
let details1: [Details1 {
let field1: UInt32
let field2: String
let data: [String: String]
}]
答案 0 :(得分:18)
如果以下优秀的开源库可用于处理Swift中JSON到Object的映射,可以使用任何一个,看看:
每个人都有一个很好的初学者教程。
关于struct
或class
的主题,您可以考虑The Swift Programming Language文档中的以下文字:
结构实例总是按值和类传递 实例总是通过引用传递。这意味着他们是 适合不同类型的任务。在考虑数据时 您决定项目所需的构造和功能 是否应将每个数据结构定义为类或类 结构
作为一般准则,请考虑在一个或多个时创建结构 这些条件适用:
- 该结构的主要目的是封装一些相对简单的数据值。
- 可以合理地预期在分配或传递时,将复制封装的值而不是引用 该结构的一个例子。
- 结构存储的任何属性本身都是值类型,也可以复制而不是引用它们。
- 该结构不需要从另一个现有类型继承属性或行为。
结构的良好候选者的例子包括:
- 几何形状的大小,可能封装了width属性和height属性,两者都是Double。
- 一种引用系列中范围的方法,可能封装了一个类型为Int的起始属性和长度属性。
- 3D坐标系中的一个点,可能包含x,y和z属性,每个属性为Double。
在所有其他情况下,定义一个类,并创建该类的实例 通过引用进行管理和传递。在实践中,这意味着 大多数自定义数据结构应该是类,而不是结构。
我希望这对你有所帮助。
答案 1 :(得分:5)
HandyJSON
正是您所需要的。参见代码示例:
struct Animal: HandyJSON { var name: String? var id: String? var num: Int? } let jsonString = "{\"name\":\"cat\",\"id\":\"12345\",\"num\":180}" if let animal = JSONDeserializer.deserializeFrom(json: jsonString) { print(animal) }
答案 2 :(得分:3)
荚:
更多信息:
使用简单请求iTunes Search API
,使用https://itunes.apple.com/search?term=jack+johnson获取itunes搜索结果import UIKit
import Alamofire
// Itunce api doc: https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api/#searching
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
private func loadData() {
let urlString = "https://itunes.apple.com/search?term=jack+johnson"
Alamofire.request(urlString).response { response in
guard let data = response.data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(ItunceItems.self, from: data)
print(result)
} catch let error {
print("\(error.localizedDescription)")
}
}
}
}
struct ItunceItems: Codable {
let resultCount: Int
let results: [ItunceItem]
}
struct ItunceItem: Codable {
var wrapperType: String?
var artistId: Int?
var trackName: String?
var trackPrice: Double?
var currency: String?
}
答案 3 :(得分:0)
您可以使用SwiftyJson和let json = JSONValue(dataFromNetworking)
if let userName = json[0]["user"]["name"].string{
//Now you got your value
}
答案 4 :(得分:0)
看看这个非常适合您需求的精彩库Argo on GitHub。
在你的情况下,结构是可以的。您可以阅读有关如何在结构和类here之间进行选择的更多信息。
答案 5 :(得分:0)
您可以使用Alamofire https://github.com/sua8051/AlamofireMapper的扩展名
声明一个类或结构:
class UserResponse: Decodable {
var page: Int!
var per_page: Int!
var total: Int!
var total_pages: Int!
var data: [User]?
}
class User: Decodable {
var id: Double!
var first_name: String!
var last_name: String!
var avatar: String!
}
使用:
import Alamofire
import AlamofireMapper
let url1 = "https://raw.githubusercontent.com/sua8051/AlamofireMapper/master/user1.json"
Alamofire.request(url1, method: .get
, parameters: nil, encoding: URLEncoding.default, headers: nil).responseObject { (response: DataResponse<UserResponse>) in
switch response.result {
case let .success(data):
dump(data)
case let .failure(error):
dump(error)
}
}