Swift教程_CoreData实例(三)_构建控制层(列表数据加载、删除数据)

Swift教程_CoreData实例(一)_构建storyboard

Swift教程_CoreData实例(二)_构建数据层

Swift教程_CoreData实例(三)_构建控制层(列表数据加载、删除数据)

Swift教程_CoreData实例(四)_构建控制层(查询、更新数据)

Swift教程_CoreData实例(五)_构建控制层(添加数据)

四、构建控制层

控制层总体结构包括列表的数据加载、数据的新增、删除、更新。这里我们先来搞定列表controller的功能(数据加载、删除),即PKOBooksTableViewController

1.列表数据加载、删除数据

我们自定义一个列表控制器PKOBooksTableViewController,并应用到storyboard的列表中。通过NSFetchedResultsController对象来查询、删除数据。

代码如下,注释非常详尽:

import UIKit
import CoreData

class PKOBooksTableViewController: UITableViewController,NSFetchedResultsControllerDelegate {
    
    var managedObjectContext: NSManagedObjectContext?
    //获取数据的控制器
    var fetchedResultsController: NSFetchedResultsController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //为导航栏左边按钮设置编辑按钮
        self.navigationItem.leftBarButtonItem = self.editButtonItem()
        
        //执行获取数据,并处理异常
        var error: NSError? = nil
        if !self.initFetchedResultsController().performFetch(&error){
            NSLog("Unresolved error \(error), \(error!.userInfo)")
            abort()
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    //设置单元格的信息
    func setCellInfo(cell: UITableViewCell, indexPath: NSIndexPath) {
        var book = self.fetchedResultsController?.objectAtIndexPath(indexPath) as Book
        NSLog("======\(book.title)")
        cell.textLabel.text = book.title
    }
    
    // MARK: - Table view data source
    
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        //分组数量
        return self.fetchedResultsController!.sections!.count
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //每个分组的数据数量
        var section = self.fetchedResultsController!.sections![section] as NSFetchedResultsSectionInfo
        return section.numberOfObjects
    }
    
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        // 为列表Cell赋值
        self.setCellInfo(cell, indexPath: indexPath)
        return cell
    }
    
    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        //分组表头显示
        return self.fetchedResultsController!.sections![section].name
    }
    
    /*
    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return NO if you do not want the specified item to be editable.
    return true
    }
    */
    
    // 自定义编辑单元格时的动作,可编辑样式包括UITableViewCellEditingStyleInsert(插入)、UITableViewCellEditingStyleDelete(删除)。
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            //删除sqlite库中对应的数据
            var context = self.fetchedResultsController?.managedObjectContext
            context!.deleteObject(self.fetchedResultsController?.objectAtIndexPath(indexPath) as NSManagedObject)
            //删除后要进行保存
            var error: NSError? = nil
            if context?.save(&error) == nil {
                NSLog("Unresolved error \(error), \(error!.userInfo)")
                abort()
            }
        } else if editingStyle == .Insert {
        }
    }
    
    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
    
    }
    */
    
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // 移动单元格时不要重新排序
        return false
    }
    
    // MARK: - NSFetchedResultsController delegate methods to respond to additions, removals and so on.
    
    //初始化获取数据的控制器
    func initFetchedResultsController() ->NSFetchedResultsController
    {
        if self.fetchedResultsController != nil {
            return self.fetchedResultsController!
        }
        // 创建一个获取数据的实例,用来查询实体
        var fetchRequest = NSFetchRequest()
        var entity = NSEntityDescription.entityForName("Book", inManagedObjectContext: self.managedObjectContext!)
        fetchRequest.entity = entity
        
        // 创建排序规则
        var authorDescriptor = NSSortDescriptor(key: "author", ascending: true)
        var titleDescriptor = NSSortDescriptor(key: "title", ascending: true)
        var sortDescriptors = [authorDescriptor, titleDescriptor]
        fetchRequest.sortDescriptors = sortDescriptors
        
        // 创建获取数据的控制器,将section的name设置为author,可以直接用于tableViewSourceData
        var fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: "author", cacheName: "Root")
        fetchedResultsController.delegate = self
        self.fetchedResultsController = fetchedResultsController
        return fetchedResultsController
    }
    
    //通知控制器即将开始处理一个或多个的单元格变化,包括添加、删除、移动或更新。在这里处理变化时对tableView的影响,例如删除sqlite数据时同时要删除tableView中对应的单元格
    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch(type) {
        case .Insert:
            self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Delete:
            self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Update:
            self.setCellInfo(self.tableView.cellForRowAtIndexPath(indexPath!)!, indexPath: indexPath!)
        case .Move:
            self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
            self.tableView.insertRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
        }
    }
    
    //通知控制器即将开始处理一个或多个的分组变化,包括添加、删除、移动或更新。
    func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
        switch(type) {
        case .Insert:
            self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Delete:
            self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Update:
            break
        case .Move:
            break
        }
    }

    //通知控制器即将有变化
    func controllerWillChangeContent(controller: NSFetchedResultsController) {
        //tableView启动变更,需要endUpdates来结束变更,类似于一个事务,统一做变化处理
        self.tableView.beginUpdates()
    }
    
    //通知控制器变化完成
    func controllerDidChangeContent(controller: NSFetchedResultsController) {
        self.tableView.endUpdates()
    }
    /*
    // MARK: - Navigation
    
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    }
    */
    
}
点击进入ooppookid的博客

你可能感兴趣的:(ios,技术,sqlite,swift,coredata)