[Swift-d28] - 實戰開發 - TODOList - API 3 新增與更新
2014-10-28 00:00
3 minutes read

Github link

昨天做了 get list

今天就來做 新增和儲存吧!

可能有人會問說,那讀取一筆 todo 的 API 呢?

因為在這邊資料量少,所有的東西都可以從最外層的 list 拿到

所以雖然有換頁的動作,但是節省流量可以不需要實做這件事

在實際開發中也會如此,case by case,有些情況一次拿完回來處理最好

不過有些則不是~

離題了,

以下是新增 todo 的程式碼:

先到 RestApi.swift 新增 post function

func addTodoList(completionHandler: ((NSDictionary!, NSError!) -> Void)!, content: String) {
        var session = NSURLSession.sharedSession()
        
        var request = NSMutableURLRequest(URL: self.addTodoUrl!)
        request.HTTPMethod = "POST"
        
        var params = ["content": content] as Dictionary<String, String>
        
        var err: NSError?
        request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
        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 NSDictionary
            
            if (error != nil) {
                return completionHandler(nil, error)
            } else {
                return completionHandler(json, nil)
            }
        })
        
        task.resume()
    }

再來就是在程式中呼叫這隻 API 囉! 我們會在 UpdateViewController 中做這件事

因為這隻 controler 處理了 “Add” 和 “Update” 兩件事

在 save() 這個 function 裡面修改成:

// 記得 class 中先產生一個 api 物件
var api = RestApi()

func save() {
        if from == "add" {
            api.addTodoList({data, error -> Void in
                if data == nil {
                    println(error)
                }
                
                dispatch_async(dispatch_get_main_queue(), {
                    println("done")
                    self.navigationController?.popToRootViewControllerAnimated(true)
                })
            }, content: self.textField.text)

        } else if from == "edit" {
            println("Save edited data")
        }
    }

打開執行就可以新增 todo 了!

“Update” 的行為和新增一樣

先到 RestApi class 加入 update 的方法:

func updateTodoList(completionHandler: ((NSDictionary!, NSError!) -> Void)!, content: String, todoId: String) {
        var session = NSURLSession.sharedSession()
        
        var request = NSMutableURLRequest(URL: NSURL(string: "http://192.168.1.158:3000/user/kerkerj/todos/\(todoId)")!)
        request.HTTPMethod = "PUT"
        
        var params = ["content": content] as Dictionary<String, String>
        
        var err: NSError?
        request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
        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 NSDictionary
            
            if (error != nil) {
                return completionHandler(nil, error)
            } else {
                return completionHandler(json, nil)
            }
        })
        
        task.resume()
    }

再到剛剛的 UpdateViewController ,把 save() 的另外一個 “edit” 的區塊改成下面的程式碼

else if from == "edit" {
            println("Save edited data")
            api.updateTodoList({data, error -> Void in
                if data == nil {
                    println(error)
                }
                
                dispatch_async(dispatch_get_main_queue(), {
                    println("done")
                    self.navigationController!.popToRootViewControllerAnimated(true)
                })
                
            }, content: self.textField.text, todoId: self.index)
        }

所以整個 save() 會長這樣:

func save() {
        if from == "add" {
            api.addTodoList({data, error -> Void in
                if data == nil {
                    println(error)
                }
                
                dispatch_async(dispatch_get_main_queue(), {
                    println("done")
                    self.navigationController?.popToRootViewControllerAnimated(true)
                })
            }, content: self.textField.text)

        } else if from == "edit" {
            println("Save edited data")
            api.updateTodoList({data, error -> Void in
                if data == nil {
                    println(error)
                }
                
                dispatch_async(dispatch_get_main_queue(), {
                    println("done")
                    self.navigationController!.popToRootViewControllerAnimated(true)
                })
                
            }, content: self.textField.text, todoId: self.id
        }
    }

在這邊要再修改一個之前的 bug Orz

由於我們要更新的時候,必須要使用到該筆資料的 object id

我們之前在 view 中傳遞的都是 content,都沒有 id,因此要加進去

首先要先改的地方是

ViewController 中的

showViewController.id = fakeData[indexPath.row]["id"]

// 改成:
showViewController.id = fakeData[indexPath.row]["_id"]

因為在 mongodb 中 object id 的名字是 _id

再來要在 ShowViewController 中加入一個把 id 傳到 UpdateViewController

在 ShowViewController 中的 editTODO() 加入:

(因為之前 showView 就已經有拿到 id 了,只是先前的欄位寫錯,加上沒有將 id pass 到 UpdateViewControler 才會發生這種事 XD)

editViewContronller.id = self.id

應該只有改這樣,最後執行看看

就發現可以編輯成功囉!

快結束啦!


Back to posts


comments powered by Disqus