我想從我的方法 getAllPoints() 中回傳 var 點
struct tempPoint: Decodable {
let idPoint:Int
let ptName:String
let ptLat:Double
let ptLong:Double
}
func getAllPoints(){
if let url = URL(string: "[MyWebService.com]") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
if let jsonString = String(data: data, encoding: .utf8) {
let jsonData = Data(jsonString.utf8)
do {
let points = try JSONDecoder().decode([tempPoint].self, from: jsonData)
} catch let error {
print(error)
}
print(jsonString)
}
}
}.resume()
}
}
我列印時得到的結果(點)
[
{"idPoint":6,"ptName":"Maison","ptLat":43.72623997050257,"ptLong":2.202591651830584},
{"idPoint":7,"ptName":"Wheelin","ptLat":42.75754326128173,"ptLong":8.137330631668685},
{"idPoint":8,"ptName":"Animoz","ptLat":45.76321863196126,"ptLong":7.137186047202841},
{"idPoint":9,"ptName":"Hesias","ptLat":45.767222865412144,"ptLong":6.132352002277385},
{"idPoint":10,"ptName":"Marcombes","ptLat":45.76018235160473,"ptLong":4.085466264251463},
{"idPoint":11,"ptName":"Leclan","ptLat":48.80950120948317,"ptLong":2.110623123039061},
{"idPoint":12,"ptName":"Cournon Skatepark","ptLat":39.74138613175866,"ptLong":4.2154977334348906}
]
我想知道這是否可以在我的方法結束時回傳這些。我將在 pickerView 中使用它并執行 CRUD,這就是我想存盤它們的原因。
謝謝
uj5u.com熱心網友回復:
使用完成關閉來“回傳”您的積分。嘗試這樣的事情:
func getAllPoints(completion: @escaping([tempPoint]) -> ()) { // <-- here
if let url = URL(string: "[MyWebService.com]") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
do {
let points = try JSONDecoder().decode([tempPoint].self, from: data)
completion(points) // <-- here return the results when done
return
} catch let error {
print(error) // <-- here todo deal with errors
}
}
completion([]) // <-- here todo deal with errors
}.resume()
} else {
completion([]) // <-- here todo deal with errors
}
}
并像這樣呼叫函式:
getAllPoints() { results in
print("array of points: \(results)")
}
uj5u.com熱心網友回復:
我的理解是,您希望在呼叫函式的位置獲得 api 回應。您可以使用閉包回傳您的回應。
您在以下代碼中看到的型別別名是自定義資料型別。你可以直接在你的函式中添加閉包,但為了讓你更簡單,我將那些帶有 typealias 的閉包宣告為資料型別。您可以在此處閱讀有關型別別名和閉包的更多資訊。
在宣告了我們自己的閉包型別之后。我們需要在我們的函式中使用它們作為引數。
struct TempPoint: Decodable {
let idPoint:Int
let ptName:String
let ptLat:Double
let ptLong:Double
}
typealias ApiResponse = ([TempPoint]) -> Void
typealias ApiError = (Error) -> Void
func getAllPoints(_ completion: @escaping ApiResponse, apiError: @escaping ApiError){
if let url = URL(string: "[MyWebService.com]") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
if let jsonString = String(data: data, encoding: .utf8) {
let jsonData = Data(jsonString.utf8)
do {
let points = try JSONDecoder().decode([TempPoint].self, from: jsonData)
completion(points)
} catch let error {
print(error)
apiError(error)
}
print(jsonString)
}
}
}.resume()
}
}
我們更改后的功能將如下所示。
下面是我們如何使用這個函式。
override func viewDidLoad() {
super.viewDidLoad()
getAllPoints { [weak self] (points) in
// you update you UI here, be sure to call in main thread when you are doing UI updates in closures.
print(points)
} apiError: { (error) in
print(error)
}
}
uj5u.com熱心網友回復:
如果事情是松散耦合的,這將是有效的,這可以用委托模式來完成。
protocol TempPointDelegate {
func didUpdatePoints(_ tempPoints: [tempPoint])
func didFailWithError(error: Error)
}
并在 tempPoint 結構中
struct tempPoint: Decodable {
let idPoint:Int
let ptName:String
let ptLat:Double
let ptLong:Double
}
var delegate: TempPointDelegate?
func getAllPoints(){
if let url = URL(string: "[MyWebService.com]") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
if let jsonString = String(data: data, encoding: .utf8) {
let jsonData = Data(jsonString.utf8)
do {
let points = try JSONDecoder().decode([tempPoint].self, from: jsonData)
self.delegate?.didUpdatePoints(points)
return
} catch let error {
self.delegate?.didFailWithError(error)
return
}
}
}
}.resume()
}
}
最后在你的 ViewController 中實作 tempPointDelegate 委托
class MainViewController: tempPointDelegate{
override func viewDidLoad() {
super.viewDidLoad()
tempPoint.getAllPoints()
}
func didUpdatePoints(_ tempPoints: [tempPoint]) {
DispatchQueue.main.async {
//process the tempPoints here / call the func to handle tempPoints
}
}
func didFailWithError(error: Error) {
//process the error returned here.
}
}
uj5u.com熱心網友回復:
首先,請以大寫字母 ( TempPoint)命名結構。
其次,轉換為String和回傳Data是毫無意義的
在 Swift 5.5 中你可以使用 async/await
enum URLError : Error { case badURL }
func getAllPoints() async throws -> [TempPoint] {
guard let url = URL(string: "[MyWebService.com]") else { throw URLError.badURL }
let (data, _) = try await URLSession.shared.data(from : url)
return try JSONDecoder().decode([TempPoint].self, from: data)
}
并稱之為
Task {
do {
let points = try await getAllPoints()
} catch {
print(error)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/399722.html
