Archiving in iOS

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(😃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.