tìm hiểu về CoreData

Để lưu trữ dữ liệu, hiện nay có rất nhiều cách lưu trữ. Nhưng hiện nay lưu trữ sử dụng framework CoreData của Apple là một lựa chọn được rất nhiều người sử dụng.

Trong bài viết dưới đây tôi sẽ làm rõ nội dung:

  • CoreData là gì?
  • CoreData hoạt động ra sao
  • CoreData có thể làm được những gì

CoreData là gì?

CoreData là một framework của Apple. Nó hỗ trợ các tác vụ quản lý quản lý các Object Graph ví dụ như:

  • Tạo cầu nối giữa Data tới các lớp Cocoa Model Layer một cách đơn giản,
  • Lưu giữ dữ liệu vào Back end mà bạn chọn.
  • Tự động bảo trì các mối quan hệ trong Object Graph
  • ...

CoreData hoạt động như thế nào?

figure-03.jpg

Persistent Store Coordinator (viết tắt là PSC) được khởi tạo với Managed Object Model (viết tắt là MOM). Nhờ có nội dung trong MOM, PSC biết nội dung trong các Persistent Store có những bảng nào, mối quan hệ giữa các bảng ra sao.

Nếu chỉ có các MOM thì PSC cũng chưa hoạt động được. PSC cần biết cơ sở dữ liệu cần tương tác là gì thông qua việc thêm PersistentStore. App của chúng ta có thể tương tác cùng một lúc với nhiều loại cơ sở dữ liệu khác nhau thông qua hoạt động của PSC.

Khi chúng ta kéo dữ liệu lên. PSC sẽ copy một bản sao dữ liệu lên vùng Managed Object Context (viết tắt là MOC). Tại vùng này, các dữ liệu của chúng ta sẽ được tương tác (thêm, sửa, xóa). Các hoạt động trên MOC chỉ là tương tác với bản sao của các dữ liệu. Nếu chúng ta không thực hiện động tác saveContext() thì những dữ liệu đó sẽ bị mất đi khi chúng ta reset app.

Một PSC có thể hoạt động đồng thời với nhiều MOC khác nhau. Mỗi MOC có thể hoạt động độc lập trên hoặc song song trên các thread khác nhau.

CoreData có thể làm được gì?

Các hoạt động tìm kiếm dữ liệu, chủ yếu được xử lý thông qua NSFetchRequest

NSFetchRequest

Sau đây tôi sẽ giới thiệu sơ qua những tính năng cơ bản của NSFetchRequest

Khi gọi dữ liệu chúng ta cần phải trả lời, chúng ta xử lý dữ liệu lấy từ entity nào

let fetchRequest = NSFetchRequest (entityName: "Person")

Khi chúng ta gọi ra rất nhiều dữ liệu có thể dẫn đến việc đơ app hoặc tràn bộ nhớ. Vì vậy, lúc đó cần đặt batchSize. Trường hợp mặc định batchSize = 0

fetchRequest.fetchBatchSize = 100

Nếu chúng ta muốn trả về dữ liệu đã được sắp xếp theo một thứ tự nào đó thì chúng ta phải truyền vào một mảng các NSSortDescriptor. Và thứ tự ưu tiên sort chính là thứ tự của mảng NSSortDescriptior

fetchRequest.sortDescriptors = [sortDescriptor]

Theo mặc định, giá trị trả về là một Managed Object. Tuy nhiên, chúng ta có thể tùy chỉnh kết quả trả về theo các loại khác nhau:

  • CountResultType: trả về giá trị số phần tử
  • DictionaryResultType: Trả về kiểu dictionary
  • ManagedObjectResultType: trả về kiểu Managed Object
  • ManagedObjectIDResultType: trả về kiểu Managed Object ID

NSFetchResultController

Đây là thành phần hết sức quan trọng của CoreData, nhờ có thành phần này, chúng ta không cần quan tâm, SQLite làm thể nào để lấy lên dữ liệu, làm thế nào để sắp xếp dữ liệu theo các mảng nhiều chiều để hiển thị section, làm thế nào để lưu vào cache, làm thế nào để tối ưu hóa bộ nhớ. CoreData đã xử lý hết cho chúng ta. Chúng ta chỉ có việc gán NSFetchResultController vào các function của UITableViewDataSource, hoặc UICollactionViewDataSoure.

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return fetchedResultsController.sections!.count
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let sections = fetchedResultsController.sections![section]
    return sections.numberOfObjects
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath) as! TransactionCell
    configureCell(cell, indexPath: indexPath)
    return cell
}

override func tableView( tableView : UITableView,  titleForHeaderInSection section: Int)->String {
    return fetchedResultsController.sections![section].name
}

Khi có bất cứ thay đổi nào ở dữ liệu, CoreData sẽ gọi đến các function trong NSFetchedResultsControllerDelegate. Và để nhận các xử lý những thay đổi này, chúng ta cần gán

fetchResultController.delegate = self

(ở đây self implement NSFetchedResultsControllerDelegate)

Xử lý dữ liệu tại Persistent Store

Trước đây khi cần xóa, hay update một loạt các dữ liệu. Chúng ta cần phải fetch dữ liệu lên, chỉnh sửa đồng loạt, sau đó lưu xuống. Việc làm này tốn rất nhiều performance.

Gần đây, chúng ta đã không cần phải làm như vậy nữa. Chúng ta có thể tương tác trực tiếp vào dữ liệu thông qua các class như: NSBatchUpdateRequest NSBatchDeleteRequest