[英]Swift 4 @escaping type as parameter
我具有以下向服務器發出GET
請求的功能。 問題是,我需要提供特定的struct
類型Codable
為類型@escaping
。 然后,我對JSONDecoder使用相同的類型,以將從JSON接收的數據解碼為Video
類型。
如何為該函數提供類型作為參數。 我想提供。 例如USER
類型或CAR
類型
struct Video: Codable {
var title: String
var pretty_artists: String
var yt_id: String
var views: String
var video_name: String
var published: Published
var result: Bool
init(title: String = "", pretty_artists: String = "", yt_id: String = "", views: String = "", video_name: String = "", published: String = "", result: Bool = true) {
self.title = title
self.pretty_artists = pretty_artists
self.yt_id = yt_id
self.views = views
self.video_name = video_name
self.published = Published()
self.result = result
}
}
//另一個文件
class XHR {
// Video to be Dynamic
func makeGetCall(todoEndpoint: String, completionHandler: @escaping (Video?, Error?) -> Void) {
// code
let decoder = JSONDecoder()
do {
let todo = try decoder.decode(Video.self, from: responseData)
completionHandler(todo, nil)
} catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(nil, error)
}
}
}
//在這里,我將函數稱為“ ViewController.swift”
// Initial request
xhr.makeGetCall<XHR>(todoEndpoint: "https://kida.al/search/uh/onajr", { result, err in
if(result != nil) {
self.ytPlayer.load(withVideoId: result!.yt_id, playerVars: self.playerVars)
self.updateVideo(data: result!)
}
})
您應該使用泛型。 只需將Video
替換為符合Codable
協議的通用參數Codable
。 就是這樣。
func makeGetCall<T>(todoEndpoint: String, completionHandler: @escaping (T?, Error?) -> Void) where T: Codable {
// As step one, you need to do networking to fetch `responseData`
// code
let decoder = JSONDecoder()
do {
let todo = try decoder.decode(T.self, from: responseData)
completionHandler(todo, nil)
} catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(nil, error)
}
}
用法
在第一個參數之后聲明類型。
makeGetCall(todoEndpoint: "/path/to/resource") { (video: Video?, error) in
}
您的用法
class XHR {
enum Result<T> {
case success(T)
case failure(Error)
}
func makeGetCall<T>(todoEndpoint: String, completionHandler: @escaping (Result<T>) -> Void) where T: Codable {
// code
let decoder = JSONDecoder()
do {
let todo = try decoder.decode(T.self, from: responseData)
completionHandler(.success(todo))
} catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(.failure(error))
}
}
}
// Initial request
let xhr = XHR()
xhr.makeGetCall(todoEndpoint: "https://kida.al/search/uh/onajr") { (result: XHR.Result<Video>) in
switch result {
case .failure(let error):
// Ups, there is something wrong
print(error)
case .success(let video):
// Sal goodman
self.ytPlayer.load(withVideoId: video.yt_id, playerVars: self.playerVars)
self.updateVideo(data: video)
}
}
您可以從此json為所需的任何對象創建模型類:
class User {
let userId: String?
let userName: String?
init(jsondata: JSON?) {
self.userId = jsondata?["user_id"].stringValue
self.userName = jsondata?["user_name"].stringValue
}
}
然后創建此模型的對象:
func makeGetCall(todoEndpoint: String, completionHandler: @escaping (User?, Error?) -> Void) {
// code
let decoder = JSONDecoder()
do {
let todo = User(responsedata)
} catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(nil, error)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.