iT邦幫忙

DAY 28
1

Swift - 從菜菜鳥到菜鳥的 30 天系列 第 28

[Swift-d28] - 實戰開發 - TODOList - API 3 新增與更新

小弟的規劃表 - http://blog.kerkerj.in/blog/2014/11/01/planning/

好讀版 - http://blog.kerkerj.in/blog/2014/10/28/swift-d28/

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

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

就發現可以編輯成功囉!

快結束啦!


上一篇
[Swift-d27] - 實戰開發 - TODOList - API 2 讀取清單資料
下一篇
[Swift-d29] - 實戰開發 - TODOList - API 4 刪除
系列文
Swift - 從菜菜鳥到菜鳥的 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言