用通用数组 属性 解码结构
Decode struct with generic array property
我有以下带有泛型的结构,用于 API 分页响应:
struct Paginable<Body> {
let data: [Body]
let meta: Meta
}
extension Paginable {
struct Meta: Codable {
let pagination: Pagination
struct Pagination: Codable {
let total: Int
let count: Int
let perPage: Int
let currentPage: Int
let totalPages: Int
}
}
}
我希望能够像这样解码它:
let response = try? response.decode(to: Paginable<Segment>.self)
所以这是我的尝试 Decodable
:
extension Paginable where Body == Data {
func decode<BodyType: Decodable>(to type: BodyType.Type) throws -> Paginable<BodyType> {
guard let decodedJSON = try? JSONDecoder().decode(BodyType.self, from: data) else {
throw APIError.decodingFailure
}
return Paginable<BodyType>(data: decodedJSON, meta: self.meta)
}
}
这给了我两个错误:
Cannot convert value of type 'Paginable.Meta' to expected argument type 'Paginable<_>.Meta'
与return
语句一致
如果我将 meta 属性 更改为 Int 等原始类型,错误就会消失。但是Meta本身就是Codable
,所以这里有什么问题?
Cannot convert value of type '[Data]' to expected argument type 'Data'
与guard
语句一致
如何解决这个问题?
你需要Paginable
符合Codable
,比如
struct Paginable<Body>: Codable where Body: Codable {
let data: [Body]
let meta: Meta
}
将 extension Paginable
中的 decode(data:to:)
方法更改为,
extension Paginable {
static func decode<BodyType: Decodable>(data: Data, to type: BodyType.Type) throws -> BodyType? {
do {
let response = try JSONDecoder().decode(BodyType.self, from: data)
return response
} catch {
throw error
}
}
}
用法:
if let data = str.data(using: .utf8) {
do {
let response = try Paginable<Segment>.decode(data: data, to: Paginable<Segment>.self)
print(response)
} catch {
print(error)
}
}
编辑:
JSON
格式:
{
"data": [
{
"name": "Name-1"
},
{
"name": "Name-2"
}
],
"meta": {
"pagination": {
"total": 100,
"count": 10,
"perPage": 5,
"currentPage": 1,
"totalPages": 10
}
}
}
我有以下带有泛型的结构,用于 API 分页响应:
struct Paginable<Body> {
let data: [Body]
let meta: Meta
}
extension Paginable {
struct Meta: Codable {
let pagination: Pagination
struct Pagination: Codable {
let total: Int
let count: Int
let perPage: Int
let currentPage: Int
let totalPages: Int
}
}
}
我希望能够像这样解码它:
let response = try? response.decode(to: Paginable<Segment>.self)
所以这是我的尝试 Decodable
:
extension Paginable where Body == Data {
func decode<BodyType: Decodable>(to type: BodyType.Type) throws -> Paginable<BodyType> {
guard let decodedJSON = try? JSONDecoder().decode(BodyType.self, from: data) else {
throw APIError.decodingFailure
}
return Paginable<BodyType>(data: decodedJSON, meta: self.meta)
}
}
这给了我两个错误:
Cannot convert value of type 'Paginable.Meta' to expected argument type 'Paginable<_>.Meta'
与return
语句一致
如果我将 meta 属性 更改为 Int 等原始类型,错误就会消失。但是Meta本身就是Codable
,所以这里有什么问题?
Cannot convert value of type '[Data]' to expected argument type 'Data'
与guard
语句一致
如何解决这个问题?
你需要Paginable
符合Codable
,比如
struct Paginable<Body>: Codable where Body: Codable {
let data: [Body]
let meta: Meta
}
将 extension Paginable
中的 decode(data:to:)
方法更改为,
extension Paginable {
static func decode<BodyType: Decodable>(data: Data, to type: BodyType.Type) throws -> BodyType? {
do {
let response = try JSONDecoder().decode(BodyType.self, from: data)
return response
} catch {
throw error
}
}
}
用法:
if let data = str.data(using: .utf8) {
do {
let response = try Paginable<Segment>.decode(data: data, to: Paginable<Segment>.self)
print(response)
} catch {
print(error)
}
}
编辑:
JSON
格式:
{
"data": [
{
"name": "Name-1"
},
{
"name": "Name-2"
}
],
"meta": {
"pagination": {
"total": 100,
"count": 10,
"perPage": 5,
"currentPage": 1,
"totalPages": 10
}
}
}