今天寫了一個小功能,讓app可以送user打的分數出去。細節不談。
主要想記錄一下的是關於URLSession data task的實作部份。
Swift UI採用的是MVVM概念,其中model是負責處理所有和data相關的handling。以我實作的這個部份來說,model有一個struct他負責和server間的溝通,另外有viewmodel class負責將結果和真正的view介面之間做聯繫。
其中一個很常用到的東西是URLSession.shared.DataTask,我們會做一個URLRequest給他,然後用URLSession.shared.dataTask(with: request, completionHandler: {<Completion handler code>}這個function把request送出去,completion handler code裡面經常要針對網路請求送出後的結果做一些處理,例如說如果是有error的話我們要去改一些變數讓view可以反應,或者收到回傳的結果對回傳資料做一些處理。如果說需要改變數的話,在struct裡面通常都是很麻煩的,因為通常這個completion handler是不能mutate在struct裡的變數,而且其實completion handler應該是要escaping。
所以比較簡便的作法是把這個常作的動作寫成一個function,然後把escaping handler傳進來。
private func resumeDataTask(withRequest request: URLRequest, completion: @escaping (Result<Data, Error>) -> Void) {
let task = URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) -> Void in
if let error = error {
completion(.failure(error))
print(error)
return
}
else if let data = data {
completion(.success(data))
}
})
task.resume()
}
這段code包括把URL task做出來一直到送出去的部份。我們可以他take兩個input,一個是做好的URLRequest,另外completion handler也做為一個參數傳進來。在結果回來之後我們才call completion handler把結果還給他。這樣做就是一個callback的概念,通常completion handler是可以從initiate整個動作(最後連結到送URLRequest的某個function trigger)的function那裡傳進來,而這個function通常是來自ViewModel,也就是一個class,所以就可以省掉我們很多data handling上的問題。
謝謝你看完這篇文章。如果你喜歡我的文章,請追蹤Facebook粉專、Twitter、IG。