Swift 如何从alamofire响应中获取任何类型的数组字段?
我的json响应中有这样的字段:Swift 如何从alamofire响应中获取任何类型的数组字段?,swift,alamofire,decodable,Swift,Alamofire,Decodable,我的json响应中有这样的字段: "title": [2402, "Dr.", "Prof.", "Prof. Dr.", "HM"] 我想解析它。我有我的模型课: struct AppDataModel:Decodable { ... let title = Dictionary<String,Any>() enum CodingKeys
"title": [2402, "Dr.", "Prof.", "Prof. Dr.", "HM"]
我想解析它。我有我的模型课:
struct AppDataModel:Decodable {
...
let title = Dictionary<String,Any>()
enum CodingKeys: String,CodingKey{
case title
...
}
...
}
我认为我必须像处理普通json一样处理它。但我并没有在Swift中找到这样的数据类型,只有字典。所以,也许有人知道如何处理这些响应字段?这是一个将单个键解码为异构数组的示例
let jsonString = """
{"title": [2402, "Dr.", "Prof.", "Prof. Dr.", "HM"], "name":"Foo"}
"""
struct AppDataModel : Decodable {
let titles : [String]
let name : String
private enum CodingKeys: String, CodingKey { case title, name }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var titlesContainer = try container.nestedUnkeyedContainer(forKey: .title)
var titleArray = [String]()
let _ = try titlesContainer.decode(Int.self) // decode and drop the leading integer
while !titlesContainer.isAtEnd { // decode all following strings
titleArray.append(try titlesContainer.decode(String.self))
}
titles = titleArray
self.name = try container.decode(String.self, forKey: .name)
}
}
let data = Data(jsonString.utf8)
do {
let result = try JSONDecoder().decode(AppDataModel.self, from: data)
print(result)
} catch {
print(error)
}
这是一个将单个密钥解码为异构数组的示例
let jsonString = """
{"title": [2402, "Dr.", "Prof.", "Prof. Dr.", "HM"], "name":"Foo"}
"""
struct AppDataModel : Decodable {
let titles : [String]
let name : String
private enum CodingKeys: String, CodingKey { case title, name }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var titlesContainer = try container.nestedUnkeyedContainer(forKey: .title)
var titleArray = [String]()
let _ = try titlesContainer.decode(Int.self) // decode and drop the leading integer
while !titlesContainer.isAtEnd { // decode all following strings
titleArray.append(try titlesContainer.decode(String.self))
}
titles = titleArray
self.name = try container.decode(String.self, forKey: .name)
}
}
let data = Data(jsonString.utf8)
do {
let result = try JSONDecoder().decode(AppDataModel.self, from: data)
print(result)
} catch {
print(error)
}
除非用代码对异类数组进行解码并正确处理不同类型的数组,否则无法对其进行解码。@vadian,那么我如何解决这个问题呢?我考虑过json处理,但这是不可能的,因为我看到有多种方法,解决方案取决于您的需要。例如,前导整数是否相关?此整数是这些字符串的翻译字符串id,因此可以更改。至于我的需要-我只需要获取不带integer numberImplement
init的字符串数据(从解码器
,将标题
解码为UnkeyeedContainer
,取出值,删除第一个值,并将其余值分配给[string]
type除非用代码对异类数组进行解码并正确处理不同类型的数组,否则无法对其进行解码。@vadian,那么我如何解决这个问题呢?我考虑过json处理,但这是不可能的,因为有多种方法,解决方案取决于您的需要。例如,前导整数是否相关?这个整数是trans为这些字符串设置字符串id,以便可以更改。至于我的需要-我只需要获取不带整数的字符串数据implementinit(从解码器
,将标题
解码为unkeyedContainer
,取出值,删除第一个值,并将其余值分配给[string]
键入在我的初始作用域中,我看到这样的错误从初始值设定项返回,而没有初始化所有存储的属性
,我必须向您展示什么,也许您会帮助我?也许这与此模型中我有一些其他键有关?我的示例仅包含一个键。如果有更多键,您必须在单独的行中解码每个键。我用第二个键更新了答案。在我的init作用域中,我看到这样的错误从初始化器返回,而没有初始化所有存储的属性
,我必须向您展示什么,也许您会帮助我?也许这与此模型中我有一些其他键有关?我的示例只包含一个键。如果有更多的键,您必须解码每个k我用第二个键更新了答案。
struct AppDataModel: Codable {
let title: [Title]?
}
extension AppDataModel {
init(data: Data) throws {
self = try newJSONDecoder().decode(AppDataModel.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}
func with(
title: [Title]?? = nil
) -> AppDataModel {
return AppDataModel(
title: title ?? self.title
)
}
func jsonData() throws -> Data {
return try newJSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
enum Title: Codable {
case integer(Int)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Int.self) {
self = .integer(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Title.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Title"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
func newJSONDecoder() -> JSONDecoder {
let decoder = JSONDecoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
decoder.dateDecodingStrategy = .iso8601
}
return decoder
}
func newJSONEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
encoder.dateEncodingStrategy = .iso8601
}
return encoder
}
//use
do {
let appDataModel = try AppDataModel(json)
}
catch{
//handle error
}