30 天下來其實中間受到不少人幫忙
因為第一次寫 iOS 程式,對於 iOS 的基本運作流程還是詢問了不少同事
包含在隔壁棚用 Cocos2d 寫 2D 遊戲的 Andy
還有同事 Henry 和 Felix 都給予了很大的幫忙
最後這隻小 app 其實 code 的品質並沒有很好
主要還是因為寫來 demo 用的,以及老實講也沒什麼時間寫…
報兩個組別真的是很鐵人哪
還看到隔壁棚一次報三四個主題的大大
真是太厲害了
假設明年還會參賽的話,應該還是會以單一技術來鑽研吧!
Swift 有蠻多特性是 Objective-C 所沒有的
如果有想在新專案嘗試的話
最好還是先多看看網路上的比較
避免踩到雷
像有一點是我們同事曾經踩到的雷
就是 NSDictionary V.S. Dictionary
兩者的速度可以差到 5, 6 倍以上
網路上搜尋也會發現有人在討論 Swift Dictionary 的效能差異
若要在新專案使用還是要查詢一下避免掉一些問題
另外還有就是 Swift on Xcode 的穩定度還是有待加強…
總而言之, 30 天結束了,ya!
Github link
今天要處理刪除
其實超簡單的
只是想偷懶一下 XD
一樣將下列程式碼新增到 RestApi class:
func deleteTodoList(completionHandler: ((NSDictionary!, NSError!) -> Void)!, todoId: String) { var session = NSURLSession.sharedSession() var request = NSMutableURLRequest(URL: NSURL(string: "http://192.168.1.158:3000/user/kerkerj/todos/\(todoId)")!) request.HTTPMethod = "DELETE" var err: NSError? 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 println(json) if (error !
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.
Github link
(某一天把兩天份的 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 !
接下來是要串 隔壁棚的 API XD
從前幾天的 APP 組成
我們所需要的資料大概會是以下幾種:
GET todo list GET http://192.168.1.158:3000/user/kerkerj/todos return: [ { "_id": "54441f64d84f1ea412db855c", "updated_at": "2014-10-19T20:30:28.797Z", "created_at": "2014-10-19T20:30:28.797Z", "content": "task11syy", "user_id": "kerkerj", "__v": 0 }, { "_id": "54441f6fd84f1ea412db855e", "updated_at": "2014-10-19T20:30:39.957Z", "created_at": "2014-10-19T20:30:39.957Z", "content": "task13", "user_id": "kerkerj", "__v": 0 } ] Get a todo task GET http://192.168.1.158:3000/user/kerkerj/todos/54441f64d84f1ea412db855c return: { "_id": "54441f64d84f1ea412db855c", "updated_at": "2014-10-19T20:30:28.797Z", "created_at": "2014-10-19T20:30:28.797Z", "content": "task11syy", "user_id": "kerkerj", "__v": 0 } Add a todo task POST http://192.
Github link
(忘了是放在哪個 branch 了 Orz)
接下來就要進到最後一個 Update View 了!
什麼時候會進到 Update View 呢?
是在顯示單筆 TODO 的時候的右上方按鈕:
我們今天只會實作 view 的部分, fakeData 就不實作了
因為接下來就要直接接 API 啦
也不需要更新 fakeData 了 :P
要加入 Edit 這個按鈕
要到 ShowViewController, 加入 UIBarButtonItem
並且讓其吃到一個方法,可以讓 Navigation 往下一個 View 前進:
var id: String! override func viewDidLoad() { super.viewDidLoad() indexLabel.text = "\(index)" contentLabel.text = content self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: UIBarButtonItemStyle.Bordered, target: self, action: Selector("editTodo")) } p.s. 先前忘記加了 id, 現在補回來 XD
Github link
今天要來建立 “新增資料” 的頁面
不過這個頁面我們也會拿來給 “更新資料” 的頁面使用
原因其實很簡單
兩邊要建立或編輯的資料是一樣的
差別只在於,當今天是編輯資料的 view call 該頁面時,
該頁面除了顯示編輯框外,編輯框內的文字也會預先 load 好舊的資料了
除此之外兩個 view 的排版一模一樣
所以在這邊我們就只建立一個 UpdateViewController 就可以了
那我們一樣建立一組 UpdateViewController.swift + UpdateViewController.xib
也一樣為元件建立關聯
回到主頁
我們幫 Add 新增一個按鈕吧
在 viewDidLoad 中
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: UIBarButtonItemStyle.Done, target: self, action: Selector("pushToAddTODO")) 設定 Navigation 的右邊鍵的功能
並且根據 pushToAddTODO 的方法做事情
因此繼續下去將 pushToAddTODO 方法做一下
func pushToAddTODO(){ var addViewController = UpdateViewController(nibName: "UpdateViewController", bundle: nil) addViewController.from = "add" self.navigationController?.pushViewController(addViewController, animated: true) } 這樣寫完後就可以執行看看了!
Github link
延續昨天,接下來要做換頁
因此我們必須先新建立一個 ShowViewController, 以及他的 xib
接著我們在 xib 拉幾個元件: 兩個 label, 一個用來顯示目前的 index, 另一個則是顯示內容
拉好後,將這兩個元件設定連結到 ShowViewController.swift
另外多在 ShowViewController 中放兩個變數
var index: Int! var content: String! 回到 ViewController, 到 tableView didSelectRowAtIndexPath 中
因為 didSelectRowAtIndexPath 的意思就是當 cell 被選取時要做什麼事情
因此當 cell 被選取時,我們就要讓他跳到下一頁,並且是使用 ShowViewController 來顯示資料
因此修改此方法:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { var showViewController = ShowViewController(nibName: "ShowViewController", bundle: nil) showViewController.index = indexPath.row showViewController.content = fakeData[indexPath.row]["content"] // 回復非選取狀態 tableView.deselectRowAtIndexPath(indexPath, animated: true) self.
Github link
接著我們要讓主頁顯示一些假資料:
由於我們未來接的 api 的資料會是 todo_id + content
因此我們先產生一個 dictionary array 來存放我們的假資料
var fakeData = [[String:String]]() fakeData = [ ["id": "1", "content": "A"], ["id": "2", "content": "B"], ["id": "3", "content": "C"], ] 再來對主頁的 controller 新增 tableView 上去
並且對 UITableView 加入 delegate 以及 datasource
import UIKit class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { var fakeData = [[String:String]]() var tableView: UITableView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib.
Github link
首先在開始寫這隻 app 前,
我們要先定義好程式大致上的流程
基本上接下來的程式碼都不會用到 storyboard
只會用到程式 + xib
程式的流程大致上是使用 Navigation controller 來控制 view 的轉換
第一頁 - tableView 顯示 todo items list
點進子項目可以觀看內容,進到子頁後可以編輯,
編輯後就即可存檔
新增項目則在主頁的右上角 “Add” 可以新增
我們會先從建立假的資料開始,也就是我會先刻出程式的流程
先不接 API
實際寫出運作流程後,再加上 API 操作的部分
因此今天的進度就先開一個新專案,將基本的 Navigation + tableView 建立起來吧:
首先建立一個新專案
再來到 project settings
將 Main Interface 及 Launch Screen file 拿掉
並將 deploy target 設成 7.1 (反正用到的程式碼都一樣~ 沒有特別使用 8.0 的 lib)
設定 device orientation - 只限定直的
接著就來編輯 AppDelegate.swift
建立一個 NavigationController + ViewController