所以我尝试使用一些普通的 HTTP 请求和 Swift 的新 Decodable
来检索一些数据。协议(protocol)。
问题是我发现我一次又一次地编写非常相似的代码(创建 URL session 、解码数据、完成处理程序等)。
我正在考虑使用泛型或继承进行简化,但不确定如何初始化“泛型对象”。
当前代码:
var response = TypeAResponse()
if let url = URL(string: urlName) {
let session = URLSession.shared
var request = URLRequest(url: url)
let task = session.dataTask(with: request){ (data, response, error) in
if let data = data {
do {
response = try JSONDecoder().decode(TypeAResponse.self, from: data)
completion(true, TypeAResponse.items)
} catch let parseError {
print("parseError: \(parseError.localizedDescription)")
completion(false, TypeAResponse.items)
}
} else {
print("Error: Data not found")
completion(false, TypeAResponse.items)
}
}
task.resume()
} else {
print("Invalid URL")
completion(false, TypeAResponse.items)
}
但是 TypeAResponse 的结构与 TypeBResponse 不同——它们共享的只是“items”属性。
可以做类似的事情
func get<T>(generalType: T, completion: GeneralRequest){
//but how would you initialise generalType?
//cannot do something like
var response = T()
}
作为引用,TypeAResponse 和 TypeBResponse 可能类似于:
struct TypeAResponse: Decodable {
items: [Track]?
}
struct Track: Decodable {
//for example
var name: String?
}
struct TypeBResponse: Decodable {
items: [Playlist]?
}
struct Playlist: Decodable {
var name, id, description: String?
}
API 响应:
请参阅 Spotify Web API 引用 - https://developer.spotify.com/documentation/web-api/reference/playlists/get-playlist/
(特别是“获取用户的播放列表”和“获取播放列表的轨道”)
最佳答案
你在这里肯定走在一个很好的轨道上。从具体代码开始总是好的,然后看看如何使它更通用。对于您的具体情况,当您问“您将如何初始化 generalType?”时这正是协议(protocol)允许您做的事情。因此,按照您的方法,您可以编写类似的内容(我尚未对此进行测试;它可能有一些语法错误):
func get<T: Decodable>(generalType: T, completion: @escaping (Result<T, Error>) -> Void {
let task = session.dataTask(with: request){ (data, response, error) in
guard let data = data else {
let err = error ?? ... some default error ...
completion(.failure(err))
return
}
let result = Result {
// You know you can call `decode` with it because it's Decodable
try JSONDecoder().decode(T.self, from: data)
}
completion(result)
}
task.resume()
}
系列 Start With A Protocol可能会有所帮助(感谢那些提到它的人)。它在这个问题上更深入。但是对于简单的应用程序,这个函数可能就是你所需要的,你应该避免增加更多的复杂性,直到它对你有用。
关于Swift - 编写一个通用的 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59777612/