[Swift-d27] - 實戰開發 - TODOList - API 2 讀取清單資料
(某一天把兩天份的 commit 在一起了忘了開 branch 了…)
接下來就要來寫 api utility 了
我們先開一個 swift 檔案 RestApi.swift
import Foundation
class RestApi {
var API_key = "55665566"
var getListUrl = NSURL(string: "http://192.168.1.158:3000/user/kerkerj/todos")
}
先做好前置設定,因為 API 有上簡單的小鎖,因此要先寫起來
還有 request 的網址
以下是 get list 的範例:
func getTodoList(completionHandler: ((NSArray!, NSError!) -> Void)!) {
var session = NSURLSession.sharedSession()
var request = NSMutableURLRequest(URL: self.getListUrl!)
request.HTTPMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue(self.API_key, forHTTPHeaderField: "API-Key")
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if (error != nil) {
return completionHandler(nil, error)
}
var error: NSError?
let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSArray
if (error != nil) {
return completionHandler(nil, error)
} else {
return completionHandler(json, nil)
}
})
task.resume()
}
我們使用內建的 NSURLSession.sharedSession 以及 NSMutableURLRequest 來建立 request
裡面就是設定一些 header 以及 API-Key
另外在資料回來後,return callback
在這邊有 async,寫隔壁棚的 api 回過頭來看這個感覺很熟悉 XD
設定好 API 後
回到顯示 todo 清單的主頁程式碼
由於我們希望能夠在 view 每次被呼叫時,都可以對 API server 做存取
因此必須要將 getTodoList 寫在該方法裏
該方法為 override func viewWillAppear(animated: Bool) {}
先建立一個 api 物件
var api: RestApi = RestApi()
將原本的假資料刪除或註解, 不過資料物件名稱就繼續用 fakeData XD
// fakeData = [
// ["id": "1", "content": "A"],
// ["id": "2", "content": "B"],
// ["id": "3", "content": "C"],
// ]
接著在 ViewController override 一個 viewWillAppear 的方法
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
api.getTodoList({data, error -> Void in
if error != nil {
dispatch_async(dispatch_get_main_queue(), {
let alert = UIAlertView()
alert.title = "Yoooooooooooooooo"
alert.message = "Get list faild, maybe check your network: \(error)"
alert.addButtonWithTitle("ok")
alert.delegate = self
alert.show()
println(error)
})
}
if (data != nil) {
var tmpArr = [[String: String]]()
for item in data {
var _id = item["_id"] as String
var content = item["content"] as String
var dic = [String: String]()
dic["_id"] = _id
dic["content"] = content
tmpArr.append(dic)
}
self.arr = tmpArr
println(self.arr)
dispatch_async(dispatch_get_main_queue(), {
// must be "tableView!" not "tableView?"
self.tableView!.reloadData()
})
}
})
dispatch_async(dispatch_get_main_queue(), {
// must be "tableView!" not "tableView?"
self.tableView!.reloadData()
})
}
以上方法都是 async 的方式
只要網路錯誤,就會直接跳一個 alert
若有資料的話就 parse
一併轉換成原本定義的 [[String: String]] 中
執行看看吧!
很明顯每次切回主頁時 api console 都會跳一行 request~
如果使用 sync 的方式就會卡很久! 而且更新 UI 還會 crash XD
我覺得這部分是需要好好去做處理的,在這邊的程式碼只是簡單 demo
並沒有考慮到太多 :P
明天繼續!