[iOS][Swift] Sử dụng Realm thay cho CoreData

Mở đầu

Search "why not Core Data", chúng ta cho ra khoảng 57 triệu kết quả trong 0.71 giây. Ý kiến đa chiều, khen có, chê có. Bản thân tôi cũng đã từng làm việc với Core Data và SQLite + Lib. Cũng khá lâu rồi không làm việc lại, nhưng tôi vẫn thích dùng Core Data hơn. Đơn giản Core Data được xây dựng là 1 framework để làm việc với DB theo một cách hướng đối tượng hóa, đặc biệt support tận răng cho việc sử dụng UITableView, thứ gần như lúc nào cũng như hình với bóng khi chúng ta sử dụng DB trong ứng dụng. Thậm chí Core Data còn có thể sử dụng trong việc hỗ trợ việc chỉnh sửa ảnh một cách dễ dàng. Ngon vãi.

Chắc bạn sẽ đặt ngay 1 câu hỏi là "tôi đang dùng Core Data ngon, nếu tôi chuyển sang Realm, các rủi ro mà tôi nhận được ai sẽ người xử lý nó" và kèm theo 1 khẩu hiệu "if it ain’t broke, don’t fix it"

Tất nhiên người xử lý điều đó sẽ không phải là tôi rồi, tôi chỉ giới thiệu thôi. Làm hay không thì bạn phải tự chịu trách nhiệm, cũng như bạn có thể code Objective-C cả đời, thay vì cập nhật lên code thử Swift, xem nó có gì hay ho không. Nếu bạn thấy Core Data là đủ rồi, thì chúng ta sẽ không cần đi tới phần sau nữa. Nếu bạn muốn tìm hiểu, hay thậm chí chỉ là xem qua xem Realm là cái gì, welcome to my post

Realm

Định nghĩa, các thông tin liên quan về Realm thì rất nhiều, nhưng tôi chỉ tóm tắt lại : Realm là một DB sử dụng core C++ với tham vọng thay thế SQLite với các ưu điểm về tốc độ và dễ sử dụng.

Một số công cụ hỗ trợ

  • Plugin cho Xcode (khuyến khích cài qua Alcatraz )

Plugin này sẽ giúp chúng ta tiết kiệm thời gian cho việc tạo 1 Realm Object subclass. Giống như việc Apple hỗ trợ cho việc tạo 1 NSManagedObject subclass vậy

Screen Shot 2016-07-27 at 1.26.11 PM.png

Screen Shot 2016-07-27 at 1.26.11 PM.png

Sau khi cài đặt Plugin, restart Xcode. Từ giờ trở đi, chúng ta sẽ không còn phải tốn nhiều thời gian cho việc tạo Realm Object subclass nữa

Screen Shot 2016-07-27 at 1.32.33 PM.png

Realm là 1 DB nên nhu cầu cần xem nó 1 cách trực quan là điều không cần phải bàn cãi. Vì thế nên công cụ tiếp theo mà tôi muốn giới thiệu đó chính là Realm Browser. Giao diện trực quan, dễ dàng sửa đổi, tạo mới DB, đó chính là 1 trong số các tính năng mà nó mang lại cho chúng ta

Screen Shot 2016-07-27 at 1.38.19 PM.png

RealmSwift

RealmSwift là một Framework hỗ trợ việc thao tác với Realm DB với ngôn ngữ Swift, cũng giống như CoreData vậy. Chúng ta sẽ cùng tìm hiểu RealmSwift qua ứng dụng dưới đây

Vì ngại thay đổi nên tôi lấy tạm cái Project của bài report trước là ứng dụng AppSearchDemo. Trong phạm vi bài viết này, chúng ta sẽ chuyển việc quản lý dữ liệu từ file JSON sang Realm để nó chuyên nghiệp nhất có thể

1. Setup Realm

Không chỉ là quảng cáo, việc setup và configure Realm dễ dàng tới mức chúng ta không cần làm gì cả (lol). Add RealmSwift vào project là xong

2. Thực hiện các thao tác cơ bản với DB

Với ứng dụng từ điển này, các dữ liệu đầu vào được load từ 1 file JSON có sẵn. Do vậy, ngay từ đầu vào, nếu chưa có dữ liệu thì chúng ta sẽ load nó lên từ file JSON đã có.

    let realm = try! Realm()
    let vocabularyList = self.realm.objects(Vocabulary)

Đơn giản chỉ cần thế thôi, tuy vậy, kết quả trả về ở đây là kiểu Results<Vocabulary>, do đó chúng ta cần convert nó sang Array để sử dụng

     vocabularyList = Array(self.realm.objects(Vocabulary))

Nếu chưa có dữ liệu ban đầu, chúng ta sẽ đọc từ file JSON để import initialize data

    try! realm.write({
       let json = JSON(data: jsonData!)
       for (_, subJson):(String, JSON) in json {
           let vocabulary = Vocabulary(json: subJson)
           realm.add(vocabulary)
        }
    })

Hoặc đơn giản hơn nữa, hãy tạo 1 Realm db file, sau đó copy sang và dùng thôi

func fetchVocabularyFromInitRealmDB() -> [Vocabulary] {
        if vocabularyList.count > 0 {
            return vocabularyList
        }
        let dataFilePath = NSBundle.mainBundle().pathForResource("initialiseData", ofType: "realm")
        let defaultPath = realm.configuration.fileURL?.path
        guard defaultPath != nil &&  dataFilePath != nil else {
            return []
        }
        do {
            try NSFileManager.defaultManager().removeItemAtPath(defaultPath!)
            try NSFileManager.defaultManager().copyItemAtPath(dataFilePath!, toPath: defaultPath!)
        } catch {
            print(error)
        }
        return vocabularyList
    }

Edit, update, xóa dữ liệu với RealmSwift thậm chí còn đơn giản hơn

VocabularyService().realm.beginWrite()
   // Tất cả các thay đổi nằm ở đây
try! VocabularyService().realm.commitWrite()

Chỉ với 2 câu bệnh beginWrite()commitWrite() chúng ta đã có thể làm mọi thứ chúng ta cần. Ngắn gọn, rõ ràng và đơn giản

Kết

Trên đây, tôi đã giới thiệu sơ qua về Realm cũng như thế mạnh về sự đơn giản mà nó mang lại. Hi vọng rằng bài viết đã mang lại cho bạn thêm 1 lựa chọn khác ngoài Core Data. Nếu bạn cần source code, nó ở ngay đây. Cảm ơn các bạn đã theo dõi bài viết 😄