Swift 如何从alamofire响应中获取任何类型的数组字段?

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

我的json响应中有这样的字段:

"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,以便可以更改。至于我的需要-我只需要获取不带整数的字符串数据implement
init(从解码器
,将
标题
解码为
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
}