1. 程式人生 > >Swift資料庫框架Realm的使用

Swift資料庫框架Realm的使用

GitHub地址:https://github.com/realm/realm-cocoa
不同於SQLite和CoreData,Realm跨平臺簡單易用,並可以監聽資料庫的變化。
1.使用CocoaPods匯入Realm

pod 'RealmSwift', '3.11.0'

2.建立Realm.Configuration配置檔案

import Foundation
import RealmSwift

struct RealmConfiguration {
    
    static func sharedConfiguration() -> Realm.Configuration {
        var config = Realm.Configuration()
        let directory = config.fileURL!.deletingLastPathComponent()
        let url = directory.appendingPathComponent("shared.realm")
        return Realm.Configuration(fileURL: url)
    }
    
    static func bookmarkConfiguration() -> Realm.Configuration {
        var config = Realm.Configuration()
        let directory = config.fileURL!.deletingLastPathComponent()
        let newURL = directory.appendingPathComponent("Bookmark.realm")
        config.fileURL = newURL
        return config
    }
}

import Foundation
import RealmSwift

protocol Initializer {
    func perform()
}

final class SharedMigrationInitializer: Initializer {
    
    lazy var config: Realm.Configuration = {
        return RealmConfiguration.sharedConfiguration()
    }()
    
    init() { }
    
    func perform() {
        config.schemaVersion = Config.dbMigrationSchemaVersion
        config.migrationBlock = { migration, oldSchemaVersion in }
    }
}

final class BookmarkMigrationInitializer: Initializer {
    
    lazy var config: Realm.Configuration = {
        return RealmConfiguration.bookmarkConfiguration()
    }()
    
    init() { }
    
    func perform() {
        config.schemaVersion = Config.dbMigrationSchemaVersion
        config.migrationBlock = { migration, oldSchemaVersion in
        }
    }
    
}

2.建立Model

import Foundation
import RealmSwift

final class Bookmark: Object {
    
    @objc dynamic var url: String = ""
    @objc dynamic var title: String = ""
    @objc dynamic var icon: String = ""
    @objc dynamic var id: String = ""
    @objc dynamic var type: String = ""
    @objc dynamic var create: Date = Date()

    convenience init(
        type: BookmarkType,
        url: String = "",
        title: String? = nil,
        icon: String? = nil
    ) {
        self.init()
        self.url = url
        self.type = type == .bookmark ? "bookmark" : "history"
        self.title = title == nil || title == "" ? "title" : title!
        self.icon = icon == nil ? "" : icon!
        self.id = "\(url)|\(create.timeIntervalSince1970)"
    }

    var linkURL: URL? {
        return URL(string: url)
    }

    override class func primaryKey() -> String? {
        return "id"
    }
    
}

3.建立資料庫,定義增刪改查

import Foundation
import RealmSwift

final class BookmarkStorage {
    
    public static let shared = BookmarkStorage()
    
    let realm: Realm = {
        let migration = BookmarkMigrationInitializer()
        migration.perform()
        let realm = try! Realm(configuration: migration.config)
        return realm
    }()
    
    var bookmarks: Results<Bookmark> {
        return realm.objects(Bookmark.self).sorted(byKeyPath: "create", ascending: false).filter("type = %@", "bookmark")
    }
    
    var histories: Results<Bookmark> {
        return realm.objects(Bookmark.self).sorted(byKeyPath: "create", ascending: false).filter("type = %@", "history")
    }
    
    func hasBookmark(url: String) -> Bool {
        let result = realm.objects(Bookmark.self).sorted(byKeyPath: "create", ascending: false).filter("type = %@ and url = %@", "bookmark", url)
        return !result.isEmpty
    }
    
    private func checkBookmark(bookmark: Bookmark) {
        let result = realm.objects(Bookmark.self).sorted(byKeyPath: "create", ascending: false).filter("type = %@ and url = %@", bookmark.type, bookmark.url)
        if !result.isEmpty {
            realm.beginWrite()
            realm.delete(result)
            try! realm.commitWrite()
        }
    }
    
    func add(bookmarks: [Bookmark]) {
        for item in bookmarks {
            checkBookmark(bookmark: item)
        }
        realm.beginWrite()
        realm.add(bookmarks, update: true)
        try! realm.commitWrite()
        while histories.count > 1000 {
            delete(bookmarks: [histories.last!])
        }
    }
    
    func delete(bookmarks: [Bookmark]) {
        realm.beginWrite()
        realm.delete(bookmarks)
        try! realm.commitWrite()
    }
    
    func deleteBookmark(url: String) {
        for item in bookmarks {
            if item.url == url {
                realm.beginWrite()
                realm.delete([item])
                try! realm.commitWrite()
            }
        }
    }
    
    func deleteAllBookmarks() {
        realm.beginWrite()
        realm.delete(bookmarks)
        try! realm.commitWrite()
    }
    
    func deleteAllHistories() {
        realm.beginWrite()
        realm.delete(histories)
        try! realm.commitWrite()
    }
    
}

4.新增觀察者

var observer: NotificationToken
    
observer = BookmarkStorage.shared.bookmarks.observe{ (changes: RealmCollectionChange) in
    switch changes {
    case .initial, .update:
        print("changed")
    case .error(let error):
        print(error.localizedDescription)
    }
}