2014年7月11日 星期五

Core Data programmatically using Swift language(Update data)

【說明】

此份筆記是根據ISBN:978-986-201-900-9這本書的第19章節所紀錄的。

專案範例延續著這篇,新增更新資料的動作。

【專案開發步驟】

更新一個託管物件:

在TableView與NavigationController之間在新增一個Segue,從Cell到Controller,並設定Identifier為UpdateRecipe,如下圖所示。

新增Segue
在RecipeStoreTableViewController.swift檔案內加入prepareForSugue:方法,如下所示。

override func prepareForSegue(_segue: UIStoryboardSegue!, sender: AnyObject!) {
        
    if (_segue.identifier == "UpdateRecipe") {
        var selectRecipe: NSManagedObject = recipes.objectAtIndex(tableView.indexPathForSelectedRow().row) as NSManagedObject
        var destViewController: UINavigationController = _segue.destinationViewController as UINavigationController
        var recipeViewController: AddRecipeViewController = destViewController.topViewController as AddRecipeViewController
        recipeViewController.recipe = selectRecipe
    }

}
當使用者按下Cell時會觸發這個方法傳送Segue給目的地的ViewController,首先先確認所觸發的Segue是不是Identifier名為UpdateRecipe,如果是的話進迴圈裡面。建立一個NSManagedObject,名為selectRecipe,儲存使用者所選擇的資料。建立一個UINavigationController,名為destViewController,儲存Segue目的地端的ViewController。建立一個名為recipeViewController的AddRecipeViewController,利用topViewController的屬性得到Navigation的堆疊(Stack)中最上層的ViewController。透過recipeViewController將AddRecipeViewController的recipe設為selectRecipe。

修改AddRecipeViewController.swift,如下所示。

var recipe: NSManagedObject!
新增一個名為recipe的全域變數,資料型態為NSManagedObject。

override func viewDidLoad() {
    super.viewDidLoad()

    if (recipe) {
        nameTextField.text = recipe.valueForKey("name") as String
        imageTextField.text = recipe.valueForKey("image") as String
        prepTimeTextField.text = recipe.valueForKey("prepTime") as String
    }

}
recipe只有在Cell被按下時才會有值,其餘時間只是個空的變數而已,所以我們利用if去判斷當AddRecipeViewController出現的時候TextField需不需要顯示文字,若if成立將會把使用者所點選的Cell的資料顯示在TextField內。

修改AddRecipeViewController.swift內的save函式,如下所示。

@IBAction func save(sender: UIBarButtonItem) {
        
    var context: NSManagedObjectContext = self.managedObjectContext()
        
    if (recipe) {
            
        recipe.setValue(nameTextField.text, forKey: "name")
        recipe.setValue(imageTextField.text, forKey: "image")
        recipe.setValue(prepTimeTextField.text, forKey: "prepTime")
    } else {
            
        var newRecipe: NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Recipe", inManagedObjectContext: context) as NSManagedObject
        newRecipe.setValue(nameTextField.text, forKey: "name")
        newRecipe.setValue(imageTextField.text, forKey: "image")
        newRecipe.setValue(prepTimeTextField.text, forKey: "prepTime")
    }
        
    self.dismissViewControllerAnimated(true, completion: nil)

}
差別在於我們要知道NSManagedObject是否要新建立一個,所以用if來做判斷資料是否存在。若是已有的資料,則託管物件就不需要在被建立,用舊的託管物件去設定資料的值即可將舊的覆蓋過去。若是新建立的資料則必須新建一個託管物件,使用新的託管文件將資料儲存。最後讓ViewCotroller離開即可。


【執行結果】

    



【專案範例】

沒有留言:

張貼留言