我想做一個通用的 HTTP 請求函式。我看到的代碼不會將資料回傳給呼叫者。相反,它會在函式中列印出錯誤代碼或決議的 JSON 物件。就我而言,我想將(資料、回應、錯誤)回傳給呼叫者。
func performHTTPRequest(urlString: String) -> (Data, URLResponse, Error) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) {(data, response, error) in
// some logic
}
task.resume()
}
}
問題是三個變數(資料、回應、錯誤)在閉包之外不可用。如果我將它們分配給閉包內的全域變數,編譯器會抱怨全域變數不在范圍內。
另外,我應該把回傳(資料、回應、錯誤)陳述句放在哪里?在 task.resume() 之前還是之后?謝謝
uj5u.com熱心網友回復:
簡短的回答是,你不能。您可以使用 Swift 5.5 中新的 async/await 語法來模擬同步網路呼叫。(我還沒有機會在我自己的專案中使用 async/await,所以我必須查一下以指導你。)
如果沒有 async/await,您將需要重構您的函式以獲取完成處理程式。一旦資料任務完成,您將使用結果呼叫完成處理程式。
這個問題一直出現在SO上。您應該能夠找到許多為異步網路撰寫基于完成處理程式的函式的示例。
uj5u.com熱心網友回復:
例如你可以這樣做
struct Message: Decodable {
var username: String
var message: String
}
enum RequestError: Error {
case invalidURL
case missingData
}
func performHTTPRequest(urlString: String) async throws -> Message{
guard let url = URL(string: urlString) else {throw RequestError.invalidURL}
guard let (data, response) = try? await URLSession.shared.data(from: url) else{throw RequestError.invalidURL}
guard (response as? HTTPURLResponse)?.statusCode == 200 else {throw RequestError.invalidURL}
let decoder = JSONDecoder()
guard let jsonResponse = try? decoder.decode(Message.self, from: data) else {throw RequestError.missingData}
return jsonResponse
}
并呼叫函式
do {
try await performHTTPRequest(urlString: "wwww.url.com")
} catch RequestError.invalidURL{
print("invalid URL")
} catch RequestError.missingData{
print("missing data")
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/420343.html
標籤:
上一篇:如何在主配置中更新當前時區?
下一篇:如果使用ajax,表單不顯示錯誤
