具有通用解码类型的网络调用
Networking Call with Generic Decoding type
我正在尝试创建一个通用网络功能 我正在寻找一个 API 处理程序,它将从网络下载 JSON 并将主题转换为符合以下条件的 Swift 结构Decodable
协议。目前我正在使用显式类型:
struct MyObject : Decodable {
let id : Int
let name : String
}
static fileprivate func makeNetworkRequest(url: URL, completionHandler: @escaping(_ error: Error?, _ myObject: MyObject?) -> ()) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(MyObject.self, from: data!)
completionHandler(nil, myNewObject)
}
catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
我希望创建一个通用函数,我可以在其中指定确认 Decodable
的任何数据类型,并在完成处理程序中返回数据对象。大致如下:
static fileprivate func makeNetworkRequest<T>(url: URL, type: <<<Decodable Type>>>, completionHandler: @escaping(_ error: Error?, _ myObject: <<<Deocable Object>>>?) -> ()) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(<<<Decodable Type>>>.self, from: data!)
completionHandler(nil, myNewObject)
}
catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
但是,我似乎无法正确获取函数参数。我没有太多使用泛型的经验。任何帮助将不胜感激
你可以模仿JSONDecoder
的decode
方法的声明:
open func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable
将上面的模式应用到您的代码中,定义应该是这样的:
static fileprivate func makeNetworkRequest<T>(url: URL, type: T.Type, completionHandler: @escaping (_ error: Error?, _ myObject: T?) -> ())
where T: Decodable
{
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(T.self, from: data!)
completionHandler(nil, myNewObject)
} catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
或者你可以这样写:
static fileprivate func makeNetworkRequest<T: Decodable>(url: URL, type: T.Type, completionHandler: @escaping (_ error: Error?, _ myObject: T?) -> ()) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(T.self, from: data!)
completionHandler(nil, myNewObject)
} catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
我正在尝试创建一个通用网络功能 我正在寻找一个 API 处理程序,它将从网络下载 JSON 并将主题转换为符合以下条件的 Swift 结构Decodable
协议。目前我正在使用显式类型:
struct MyObject : Decodable {
let id : Int
let name : String
}
static fileprivate func makeNetworkRequest(url: URL, completionHandler: @escaping(_ error: Error?, _ myObject: MyObject?) -> ()) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(MyObject.self, from: data!)
completionHandler(nil, myNewObject)
}
catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
我希望创建一个通用函数,我可以在其中指定确认 Decodable
的任何数据类型,并在完成处理程序中返回数据对象。大致如下:
static fileprivate func makeNetworkRequest<T>(url: URL, type: <<<Decodable Type>>>, completionHandler: @escaping(_ error: Error?, _ myObject: <<<Deocable Object>>>?) -> ()) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(<<<Decodable Type>>>.self, from: data!)
completionHandler(nil, myNewObject)
}
catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
但是,我似乎无法正确获取函数参数。我没有太多使用泛型的经验。任何帮助将不胜感激
你可以模仿JSONDecoder
的decode
方法的声明:
open func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable
将上面的模式应用到您的代码中,定义应该是这样的:
static fileprivate func makeNetworkRequest<T>(url: URL, type: T.Type, completionHandler: @escaping (_ error: Error?, _ myObject: T?) -> ())
where T: Decodable
{
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(T.self, from: data!)
completionHandler(nil, myNewObject)
} catch let error {
completionHandler(error, nil)
return
}
}.resume()
}
或者你可以这样写:
static fileprivate func makeNetworkRequest<T: Decodable>(url: URL, type: T.Type, completionHandler: @escaping (_ error: Error?, _ myObject: T?) -> ()) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
// handle error
do {
let myNewObject = try JSONDecoder().decode(T.self, from: data!)
completionHandler(nil, myNewObject)
} catch let error {
completionHandler(error, nil)
return
}
}.resume()
}