我可以将动态 @escapeing(Result<[CLASS], APIError>) 参数传递给我的函数以重用我的代码吗?
Can I pass in a dynamic @escapeing(Result<[CLASS], APIError>) argument to my function to reuse my code?
我是 swift 的新手,有点挣扎。我有几个 GET 查询,它们最终只使用另一个 class(目标 iOS 10.3,Swift 5)做同样的事情。
此方法接收大量数据集,并通过完成处理程序 returns 接收它们。目前我对每种类型多次使用此代码,但我可以想象没有更有效的方法。
CLASS标记唯一的区别:
func getMultiple (completion: @escaping(Result<[CLASS], APIError>) -> Void) {
let data = try JSONDecoder().decode([CLASS].self, from: data!)
这是我的方法:
func getMultiple (completion: @escaping(Result<[CLASS], APIError>) -> Void) {
do {
urlRequest.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in
if let error = error {
print("error: \(error)")
}
else {
if let httpResponse = response as? HTTPURLResponse {
switch httpResponse.statusCode {
case 200:
do {
let data = try JSONDecoder().decode([CLASS].self, from: data!)
completion(.success(data))
return
} catch {
print("caught: \(error)")
}
default:
do {
let data = try JSONDecoder().decode(ServerMessage.self, from: data!)
completion(.failure(
APIError(
code: httpResponse.statusCode,
msg: data)
))
} catch {
print("caught: \(error)")
}
return
}
}
}
}
task.resume()
}
}
这正是泛型旨在解决的问题。在您的函数中将“CLASS”替换为通用参数“Item”,其余的应该完全按照您的意愿工作。
func getMultiple<Item: Decodable>(completion: @escaping(Result<[Item], APIError>) -> Void) {
^^^^^^^^^^^^^^^^^ ^^^^
有关更多信息,请参阅 Swift 编程语言中的 Generic Parameters and Arguments。
我经常建议在你的函数签名中添加一个额外的参数,以便更容易地传递类型(这类似于 JSONDecoder 的工作方式):
func getMultiple<Item: Decodable>(of: Item.Type = Item.self, completion: @escaping(Result<[Item], APIError>) -> Void) {
^^^^^^^^^^^^^^^^^^^^^^^^^^
此 of
参数未在任何地方使用;这只是意味着您可以更轻松地直接在调用中包含类型:
.getMultiple(of: User.self) { user in ... }
添加= Item.self
只是意味着如果从上下文中知道类型,则不必传递它,这很方便。
我是 swift 的新手,有点挣扎。我有几个 GET 查询,它们最终只使用另一个 class(目标 iOS 10.3,Swift 5)做同样的事情。
此方法接收大量数据集,并通过完成处理程序 returns 接收它们。目前我对每种类型多次使用此代码,但我可以想象没有更有效的方法。
CLASS标记唯一的区别:
func getMultiple (completion: @escaping(Result<[CLASS], APIError>) -> Void) {
let data = try JSONDecoder().decode([CLASS].self, from: data!)
这是我的方法:
func getMultiple (completion: @escaping(Result<[CLASS], APIError>) -> Void) {
do {
urlRequest.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in
if let error = error {
print("error: \(error)")
}
else {
if let httpResponse = response as? HTTPURLResponse {
switch httpResponse.statusCode {
case 200:
do {
let data = try JSONDecoder().decode([CLASS].self, from: data!)
completion(.success(data))
return
} catch {
print("caught: \(error)")
}
default:
do {
let data = try JSONDecoder().decode(ServerMessage.self, from: data!)
completion(.failure(
APIError(
code: httpResponse.statusCode,
msg: data)
))
} catch {
print("caught: \(error)")
}
return
}
}
}
}
task.resume()
}
}
这正是泛型旨在解决的问题。在您的函数中将“CLASS”替换为通用参数“Item”,其余的应该完全按照您的意愿工作。
func getMultiple<Item: Decodable>(completion: @escaping(Result<[Item], APIError>) -> Void) {
^^^^^^^^^^^^^^^^^ ^^^^
有关更多信息,请参阅 Swift 编程语言中的 Generic Parameters and Arguments。
我经常建议在你的函数签名中添加一个额外的参数,以便更容易地传递类型(这类似于 JSONDecoder 的工作方式):
func getMultiple<Item: Decodable>(of: Item.Type = Item.self, completion: @escaping(Result<[Item], APIError>) -> Void) {
^^^^^^^^^^^^^^^^^^^^^^^^^^
此 of
参数未在任何地方使用;这只是意味着您可以更轻松地直接在调用中包含类型:
.getMultiple(of: User.self) { user in ... }
添加= Item.self
只是意味着如果从上下文中知道类型,则不必传递它,这很方便。