簡體   English   中英

Swift 4 @轉義類型作為參數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM