我们可以在 Swift 上重用结构吗?或者还有其他办法吗?
Can we reuse struct on Swift? Or is there any other way?
所以我有一个用户 JSON 结构是这样的:
- results: {
meta: {}
users: []
},
- status:
我想获取用户,所以我为获取 JSON 而实施的 User
模型如下所示:
struct Response: Decodable {
let results: Result
let status: Int
}
struct Result: Decodable {
let meta: Meta
let users: [User]
}
struct Meta: Decodable {
let total_data: Int
let total_page: Int
}
struct User: Decodable {
let avatar_url: String
let created_at: String
let updated_at: String
let email: String
let id: Int
let name: String
let username: String
}
它正在工作,但是当我有另一个JSON结构相似时,可以这样说
- results: {
meta: {}
rooms: []
},
- status:
当我创建 Room
模型时,上面还有另一个 struct Response
,它会导致错误,因为它是重复声明。
是否可以在 Swift 中重用结构?或者有什么方便的方法吗?
谢谢
您可以使用泛型。
struct Response<T: Decodable>: Decodable {
let results: Result<T>
let status: Int
}
struct Result<T: Decodable>: Decodable {
let meta: Meta
let objects: [T]
}
struct Meta: Decodable {
let total_data: Int
let total_page: Int
}
struct User: Decodable {
let avatar_url: String
let created_at: String
let updated_at: String
let email: String
let id: Int
let name: String
let username: String
}
let userResponse: Response<User>?
您可以尝试通过以下方式使用泛型:
struct Response<ResultType> : Decodable where ResultType : Decodable {
let results: ResultType
let status: Int
}
然后通过以下方式使用该结构:
struct Result: Decodable {
let something: String
}
let decoder = JSONDecoder()
let data = "{\"status\":123,\"results\":{\"something\":\"hi\"}}".data(using: .utf8)!
let value = try! decoder.decode(Response<Result>.self, from: data) // will be of type Response<Result>
您有一个选择是重复使用 Meta
和 Status
如果你使用 sm
对于用户您可以替换名称
struct UserResult: Decodable {
let meta: Meta
let users: [User]
}
struct UserResponse: Decodable {
let results: UserResult
let status: Int
}
和房间
struct RoomResult: Decodable {
let meta: Meta
let users: [Room]
}
struct RoomResponse: Decodable {
let results: RoomResult
let status: Int
}
根据您的需要,您可以使用泛型来组合整个结构。
从您的数据模型开始
struct User: Decodable {
let avatar_url: String
let created_at: String
let updated_at: String
let email: String
let id: Int
let name: String
let username: String
}
struct Room: Decodable {
let id: Int
let name: String
}
目标是获得漂亮的组合类型。
typealias UserResponse = Response<Result<User, Meta>>
typealias RoomResponse = Response<Result<Room, Meta>>
要构建的泛型类型
struct Response<ResultType: Decodable>: Decodable {
let results: ResultType
let status: Int
}
struct Result<ItemType: Decodable, MetaType: Decodable>: Decodable {
let meta: MetaType
let items: [ItemType]
}
甚至Meta
也是作文的一个单独部分。
struct Meta: Decodable {
let total_data: Int
let total_page: Int
}
现在假设我们需要一个自定义 Meta
作为 Room
响应
struct PagedMeta: Decodable {
let current_page: Int
let page_count: Int
}
这是新类型
typealias RoomPagedResponse = Response<Result<Room, PagedMeta>>
所以我有一个用户 JSON 结构是这样的:
- results: {
meta: {}
users: []
},
- status:
我想获取用户,所以我为获取 JSON 而实施的 User
模型如下所示:
struct Response: Decodable {
let results: Result
let status: Int
}
struct Result: Decodable {
let meta: Meta
let users: [User]
}
struct Meta: Decodable {
let total_data: Int
let total_page: Int
}
struct User: Decodable {
let avatar_url: String
let created_at: String
let updated_at: String
let email: String
let id: Int
let name: String
let username: String
}
它正在工作,但是当我有另一个JSON结构相似时,可以这样说
- results: {
meta: {}
rooms: []
},
- status:
当我创建 Room
模型时,上面还有另一个 struct Response
,它会导致错误,因为它是重复声明。
是否可以在 Swift 中重用结构?或者有什么方便的方法吗?
谢谢
您可以使用泛型。
struct Response<T: Decodable>: Decodable {
let results: Result<T>
let status: Int
}
struct Result<T: Decodable>: Decodable {
let meta: Meta
let objects: [T]
}
struct Meta: Decodable {
let total_data: Int
let total_page: Int
}
struct User: Decodable {
let avatar_url: String
let created_at: String
let updated_at: String
let email: String
let id: Int
let name: String
let username: String
}
let userResponse: Response<User>?
您可以尝试通过以下方式使用泛型:
struct Response<ResultType> : Decodable where ResultType : Decodable {
let results: ResultType
let status: Int
}
然后通过以下方式使用该结构:
struct Result: Decodable {
let something: String
}
let decoder = JSONDecoder()
let data = "{\"status\":123,\"results\":{\"something\":\"hi\"}}".data(using: .utf8)!
let value = try! decoder.decode(Response<Result>.self, from: data) // will be of type Response<Result>
您有一个选择是重复使用 Meta
和 Status
如果你使用 sm
对于用户您可以替换名称
struct UserResult: Decodable {
let meta: Meta
let users: [User]
}
struct UserResponse: Decodable {
let results: UserResult
let status: Int
}
和房间
struct RoomResult: Decodable {
let meta: Meta
let users: [Room]
}
struct RoomResponse: Decodable {
let results: RoomResult
let status: Int
}
根据您的需要,您可以使用泛型来组合整个结构。
从您的数据模型开始
struct User: Decodable {
let avatar_url: String
let created_at: String
let updated_at: String
let email: String
let id: Int
let name: String
let username: String
}
struct Room: Decodable {
let id: Int
let name: String
}
目标是获得漂亮的组合类型。
typealias UserResponse = Response<Result<User, Meta>>
typealias RoomResponse = Response<Result<Room, Meta>>
要构建的泛型类型
struct Response<ResultType: Decodable>: Decodable {
let results: ResultType
let status: Int
}
struct Result<ItemType: Decodable, MetaType: Decodable>: Decodable {
let meta: MetaType
let items: [ItemType]
}
甚至Meta
也是作文的一个单独部分。
struct Meta: Decodable {
let total_data: Int
let total_page: Int
}
现在假设我们需要一个自定义 Meta
作为 Room
响应
struct PagedMeta: Decodable {
let current_page: Int
let page_count: Int
}
这是新类型
typealias RoomPagedResponse = Response<Result<Room, PagedMeta>>