Archiving in iOS
Bài đăng này đã không được cập nhật trong 7 năm
Archiving
Hầu hết các ứng dụng iOS về cơ bản đều có chung một điểm chung: cung cấp giao diện cho người dùng thao tác với dữ liệu. Mỗi object trong ứng dụng đều đóng ghóp 1 vài trò trong quá trình này. Model object chịu trách nhiệm nắm giữ dữ liệu mà người dùng thao tác với nó. View là cách mà dữ liệu thể hiện đến người dùng. Vì vậy việc lưu trữ và đọc các dữ liệu cũng đồng nghĩa lưu trữ và đọc các model object. Archiving là một trong những kỹ thuật cơ bản để lưu trữ và đọc object lên trong iOS. Arvicing một object nghĩa là ta sao lưu toàn bộ các thuộc tính của obecjt đó xuống file system. Unarchving là quá trự ngược lại, đọc dữ liệu từ file system và trả lại model object cho ta sử dụng. Các object muốn archived và unarchived thì class của object đó phải confirm NSCoding protocol và implement 2 method encodeWithCoder( và invit(coder:) Khi một object được thêm vào một file giao diện ví dụ storyboard, chúng được archived lại. Khi chạy chương trình, các object này được load vào bộ nhớ bằng cách unarchived từ file giao diện. UIView và UIViewController đều conform NSCoding protocol nên cả hai đều có thể archived và unarchived mà chúng ta ko cần implement gì thêm.
Serialization object
Ta tạo class Book
class Book: NSObject, NSCoding {
var title: String
var author: String
var pageCount: Int
var categories: [String]
var available: Bool
// Memberwise initializer
init(title: String, author: String, pageCount: Int, categories: [String], available: Bool) {
self.title = title
self.author = author
self.pageCount = pageCount
self.categories = categories
self.available = available
}
// MARK: NSCoding
public required convenience init?(coder aDecoder: NSCoder) {
guard let title = aDecoder.decodeObject(forKey: "title") as? String,
let author = aDecoder.decodeObject(forKey: "author") as? String,
let categories = aDecoder.decodeObject(forKey: "categories") as? [String]
else { return nil }
self.init(
title: title,
author: author,
pageCount: aDecoder.decodeInteger(forKey: "pageCount"),
categories: categories,
available: aDecoder.decodeBool(forKey: "available")
)
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(self.title, forKey: "title")
aCoder.encode(self.author, forKey: "author")
aCoder.encodeCInt(Int32(self.pageCount), forKey: "pageCount")
aCoder.encode(self.categories, forKey: "categories")
aCoder.encode(self.available, forKey: "available")
}
}
Các property được encoded hay decoded như làm một object hoặc kiểu dữ liệu, dùng tên của property làm key. Đến đây chúng ta đã có thể serialization object. Phần tiếp theo chúng ta sẽ tìm hiểu về lưu trữ object sau khi archived ở đâu.
Lưu Trữ
Chúng ta có 2 lựa chọn để lưu các object sau khi archived: file system và NSUserDefaults.
File System
NSKeyedArchiver và NSKeyedUnarchiver cung cấp sẵn các hàm cho chúng ta đọc, ghi object trưc tiếp vào đĩa.
Archiving
NSKeyedArchiver.archiveRootObject(books, toFile: "/path/to/archive")
Unarchiving
guard let books = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? [Book] else { return nil }
NSUserDefaults
Mỗi app đều có NSUserDefaults riêng của nó, chúng ta có thể lưu các biến setting. Có thể dùng NSUserDefaults để lưu các object của class conform NSCoding.
Archiving
let data = NSKeyedArchiver.archivedDataWithRootObject(books)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "books")
Unarchiving
if let data = NSUserDefaults.standardUserDefaults().objectForKey("books") as? NSData {
let books = NSKeyedUnarchiver.unarchiveObjectWithData(data)
}
Tổng kết
Chúng ta đã có thêm một lựa chọn nữa để lưu dữ liệu ngoài cách dùng database. Với archiving, các bạn chỉ nên sử dụng với dữ liệu nhỏ, ko yêu cầu query vì tốc độ của archiving so với Core Data hoặc sqllite là chậm hơn rất nhiều. Archiving cho phép bạn lưu trữ nhanh một object mà không cần tạo bản hay kết nối database.
All rights reserved