Swift-RealmSwift 的使用

Swift版本的Realm測試用例沛善,有關(guān)Realm介紹請看之前 OC的文章
目錄:
1、Realm庫的配置
2嗽上、增
3办绝、刪
4伊约、改
5姚淆、查
6、個人信息的存儲和調(diào)試

一屡律、Realm庫的配置

/**
 Realm 致力于平衡數(shù)據(jù)庫讀取的靈活性和性能腌逢。為了實現(xiàn)這個目標(biāo),在 Realm 中所存儲的信息的各個方面都有基本的限制超埋。例如:
 (1)類名稱的長度最大只能存儲 57 個 UTF8 字符搏讶。
 (2)屬性名稱的長度最大只能支持 63 個 UTF8 字符。
 (3)NSData 以及 String 屬性不能保存超過 16 MB 大小的數(shù)據(jù)霍殴。如果要存儲大量的數(shù)據(jù)媒惕,可通過將其分解為16MB 大小的塊,或者直接存儲在文件系統(tǒng)中来庭,然后將文件路徑存儲在 Realm 中妒蔚。如果您的應(yīng)用試圖存儲一個大于 16MB 的單一屬性,系統(tǒng)將在運行時拋出異常月弛。
 (4)對字符串進行排序以及不區(qū)分大小寫查詢只支持“基礎(chǔ)拉丁字符集”面睛、“拉丁字符補充集”、“拉丁文擴展字符集 A” 以及”拉丁文擴展字符集 B“(UTF-8 的范圍在 0~591 之間)尊搬。
 */

// 事件閉包(做完Realm操作后的事件)
public typealias RealmDoneTask = () -> Void
class RealmTools: NSObject {
    /// 單粒
    static let sharedInstance = RealmTools()
    /// 當(dāng)前的 Realm
    fileprivate var currentRealm: Realm?
    /// 當(dāng)前realm存儲的路徑
    static var fileURL: URL? {
        return sharedInstance.currentRealm?.configuration.fileURL
    }
    /// 當(dāng)前的版本號
    fileprivate var currentSchemaVersion: UInt64 = 0
    /// 當(dāng)前的加密字符串
    fileprivate var currentKeyWord: String? = ""
}

// MARK:- Realm數(shù)據(jù)庫配置和版本差異化配置
/**
 通過調(diào)用 Realm() 來初始化以及訪問我們的 realm 變量叁鉴。其指向的是應(yīng)用的 Documents 文件夾下的一個名為“default.realm”的文件。
 通過對默認(rèn)配置進行更改佛寿,我們可以使用不同的數(shù)據(jù)庫幌墓。比如給每個用戶帳號創(chuàng)建一個特有的 Realm 文件,通過切換配置冀泻,就可以直接使用默認(rèn)的 Realm 數(shù)據(jù)庫來直接訪問各自數(shù)據(jù)庫
 */
// 在(application:didFinishLaunchingWithOptions:)中進行配置
extension RealmTools {

    // MARK: 配置數(shù)據(jù)庫常侣,為用戶提供個性化的 Realm 配置(加密暫時沒有使用)
    /// 配置數(shù)據(jù)庫,為用戶提供個性化的 Realm 配置
    /// - Parameters:
    ///   - userID: 用戶的ID
    ///   - keyWord: 加密字符串
    ///   - schemaVersion: 設(shè)置新的架構(gòu)版本(如果要存儲的數(shù)據(jù)模型屬性發(fā)生變化)弹渔,這個版本號必須高于之前所用的版本號胳施,如果您之前從未設(shè)置過架構(gòu)版本,那么這個版本號設(shè)置為 0)
    static func configRealm(userID: String?,
                        keyWord: String? = nil,
                        schemaVersion: UInt64 = 0, migrationBlock: MigrationBlock? = nil) {
        // 加密串128位結(jié)果為:464e5774625e64306771702463336e316a4074487442325145766477335e21346b715169364c406c6a4976346d695958396245346e356f6a62256d2637566126
        // let key: Data = "FNWtb^d0gqp$c3n1j@tHtB2QEvdw3^!4kqQi6L@ljIv4miYX9bE4n5ojb%m&7Va&".data(using: .utf8, allowLossyConversion: false)!
        // 加密的key
        // let key: Data = keyWord.data(using: .utf8, allowLossyConversion: false)!
        // 打開加密文件
        // (encryptionKey: key)
        // 使用默認(rèn)的目錄肢专,但是使用用戶 ID 來替換默認(rèn)的文件名
        let fileURL = FileManager.DocumnetsDirectory() + "/" + ("\(userID ?? "")default.realm")
        let config = Realm.Configuration(fileURL: URL(string: fileURL), schemaVersion: schemaVersion, migrationBlock: { (migration, oldSchemaVersion) in
            // 目前我們還未進行數(shù)據(jù)遷移舞肆,因此 oldSchemaVersion == 0
            if oldSchemaVersion < 1 {
                // 什么都不要做!Realm 會自行檢測新增和需要移除的屬性博杖,然后自動更新硬盤上的數(shù)據(jù)庫架構(gòu)
            }
            // 低版本的數(shù)據(jù)庫遷移......
            if migrationBlock != nil {
                migrationBlock!(migration, oldSchemaVersion)
            }
        })
        // 告訴 Realm 為默認(rèn)的 Realm 數(shù)據(jù)庫使用這個新的配置對象
        Realm.Configuration.defaultConfiguration = config
        guard let realm = try? Realm(configuration: config) else {
            return
        }
        sharedInstance.currentSchemaVersion = schemaVersion
        sharedInstance.currentRealm = realm
        sharedInstance.currentKeyWord = keyWord
    }

    // MARK: 刪除當(dāng)前的realm庫
    /// 刪除當(dāng)前的realm庫
    @discardableResult
    static func deleteRealmFiles() -> Bool {
        let realmURL = sharedInstance.currentRealm?.configuration.fileURL ?? Realm.Configuration.defaultConfiguration.fileURL!
        let realmURLs = [
            realmURL,
            realmURL.appendingPathExtension("lock"),
            realmURL.appendingPathExtension("management")
        ]
        for URL in realmURLs {
            do {
                try FileManager.default.removeItem(at: URL)
                self.configRealm(userID: nil, keyWord: sharedInstance.currentKeyWord, schemaVersion: sharedInstance.currentSchemaVersion)
            } catch {
                // handle error
               return false
            }
        }
        return true
    }
}

二椿胯、增

// MARK:- 增
extension RealmTools {

    // MARK: 添加單個對象
    /// 添加單個對象
    /// - Parameters:
    ///   - object: 對象
    ///   - update: 是否更新
    ///   - task: 添加后操作
    static func add(_ object: Object, update: Realm.UpdatePolicy = .error, task: @escaping RealmDoneTask) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.add(object, update: update)
            task()
        }
    }

    // MARK: 添加多個對象
    /// 添加多個對象
    /// - Parameters:
    ///   - objects: 對象組
    ///   - update: 是否更新
    ///   - task: 添加后操作
    static func addList(_ objects: Array<Object>, update: Realm.UpdatePolicy = .error, task: @escaping RealmDoneTask) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.add(objects, update: update)
            task()
        }
    }
}

三、刪

// MARK:- 刪
extension RealmTools {

    // MARK: 在事務(wù)中刪除一個對象
    /// 在事務(wù)中刪除一個對象
    /// - Parameters:
    ///   - object: 單個被刪除的對象
    ///   - task: 刪除后操作
    static func delete(_ object: Object, task: @escaping RealmDoneTask) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.delete(object)
            task()
        }
    }

    // MARK: 在事務(wù)中刪除多個對象
    /// 在事務(wù)中刪除多個對象
    /// - Parameters:
    ///   - objects: 多個要被刪除的對象
    ///   - task: 刪除后操作
    static func deleteList(_ objects: Array<Object>, task: @escaping RealmDoneTask) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.delete(objects)
            task()
        }
    }

    // MARK: 刪除所有數(shù)據(jù)(不要輕易調(diào)用)
    /// 從 Realm 中刪除所有數(shù)據(jù)
    /// - Parameter task: 刪除后操作
    static func deleteAll(task: @escaping RealmDoneTask) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.deleteAll()
            task()
        }
    }

    // MARK: 根據(jù)條件刪除對象
    /// 根據(jù)條件刪除對象
    /// - Parameters:
    ///   - object: 對象類型
    ///   - predicate: 條件
    static func deleteByPredicate(object: Object.Type, predicate: NSPredicate) {
        guard let results: Array<Object> = objectsWithPredicate(object: object, predicate: predicate) else {
            return
        }
        deleteList(results) {
        }
    }
}

四剃根、改

// MARK:- 改
extension RealmTools {

    // MARK: 更改某個對象(根據(jù)主鍵存在來更新哩盲,元素必須有主鍵)
    /// 更改某個對象(根據(jù)主鍵存在來更新)
    /// - Parameters:
    ///   - object: 某個對象
    ///   - update: 是否更新
    static func update(object: Object, update: Realm.UpdatePolicy = .modified) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.add(object, update: update)
        }
    }

    // MARK: 更改多個對象(根據(jù)主鍵存在來更新,元素必須有主鍵)
    /// 更改多個對象(根據(jù)主鍵存在來更新)
    /// - Parameters:
    ///   - objects: 多個對象
    ///   - update: 是否更新
    static func updateList(objects: Array<Object>, update: Realm.UpdatePolicy = .modified) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            weakCurrentRealm.add(objects, update: .modified)
        }
    }

    // MARK: 更新操作,對于realm搜索結(jié)果集當(dāng)中的元素廉油,在action當(dāng)中直接賦值即可修改(比如查詢到的某些屬性可直接修改)
    /// 更新操作惠险,對于realm搜索結(jié)果集當(dāng)中的元素,在action當(dāng)中直接賦值即可修改
    /// - Parameter action: 操作
    static func updateWithTranstion(action: (Bool) -> Void) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        try? weakCurrentRealm.write {
            action(true)
        }
    }

    // MARK: 更新一個一個對象的多個屬性值(根據(jù)主鍵存在來更新抒线,元素必須有主鍵)
    /// 更新一個一個對象的多個屬性值
    /// - Parameters:
    ///   - object: 對象類型
    ///   - value: 數(shù)組數(shù)組
    ///   - update: 更新類型
    static func updateObjectAttribute(object: Object.Type, value: Any = [:], update: Realm.UpdatePolicy = .modified) {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return
        }
        do {
            try weakCurrentRealm.write {
                weakCurrentRealm.create(object, value: value, update: update)
            }
        } catch _ {
        
        }
    }
}

五班巩、查

// MARK:- 查
extension RealmTools {
    // MARK: 查詢某個對象數(shù)據(jù)
    /// 查詢某個對象數(shù)據(jù)
    /// - Parameter type: 對象類型
    /// - Returns: 返回查詢的結(jié)果
    static func objects(_ object: Object.Type) -> Array<Object>? {
        guard let results = queryWithType(object: object) else {
            return nil
        }
        return resultsToObjectList(results: results)
    }

    // MARK: 查詢某個對象數(shù)據(jù)(根據(jù)條件)
    /// 查詢某個對象數(shù)據(jù)(根據(jù)條件)
    /// - Parameters:
    ///   - object: 對象類型
    ///   - predicate: 查詢條件
    /// - Returns: 返回查詢結(jié)果
    static func objectsWithPredicate(object: Object.Type, predicate: NSPredicate) -> Array<Object>? {
        guard let results = queryWith(object: object, predicate: predicate) else {
            return nil
        }
        return resultsToObjectList(results: results)
    }

    // MARK: 帶排序條件查詢
    ///  帶排序條件查詢
    /// - Parameters:
    ///   - object: 對象類型
    ///   - predicate:  查詢條件
    ///   - sortedKey: 排序的鍵
    ///   - isAssending: 升序還是降序,默認(rèn)升序
    /// - Returns: 返回查詢對象數(shù)組
    static func objectsWithPredicateAndSorted(object: Object.Type,
                                       predicate: NSPredicate,
                                       sortedKey: String,
                                     isAssending: Bool = true) -> Array<Object>? {
        guard let results = queryWithSorted(object: object, predicate: predicate, sortedKey: sortedKey, isAssending: isAssending) else {
            return nil
        }
        return resultsToObjectList(results: results)
    }

    // MARK: 帶分頁的查詢
    /// 帶分頁的查詢
    /// - Parameters:
    ///   - object: 對象類型
    ///   - predicate: 查詢條件
    ///   - sortedKey: 排序的鍵
    ///   - isAssending: 升序還是降序十兢,默認(rèn)升序
    ///   - fromIndex: 起始頁
    ///   - pageSize: 一頁的數(shù)量
    /// - Returns: 返回查詢對象數(shù)組
    static func objectsWithPredicateAndSortedForPages(object: Object.Type,
                                                  predicate: NSPredicate,
                                                  sortedKey: String,
                                                  isAssending: Bool,
                                                  fromIndex: Int,
                                                  pageSize: Int) -> Array<Object>? {
        guard let results = queryWithSorted(object: object,
                                     predicate: predicate,
                                     sortedKey: sortedKey,
                                 isAssending: isAssending) else {
            return nil
        }
        var resultsArray = Array<Object>()
        if results.count <= pageSize * (fromIndex - 1) || fromIndex <= 0 {
            return resultsArray
        }
        if results.count > 0 {
            for i in pageSize * (fromIndex - 1)...(fromIndex * pageSize - 1) {
                resultsArray.append(results[I])
            }
        }
        return resultsArray
    }
}

//MARK:- 私有(查詢)
extension RealmTools {

    /// 查詢某個對象數(shù)據(jù)
    /// - Parameter object: 對象類型
    /// - Returns: 返回查詢對象數(shù)組
    private static func queryWithType(object: Object.Type) -> Results<Object>? {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return nil
        }
        return weakCurrentRealm.objects(object)
    }

    // MARK: 根據(jù)條件查詢數(shù)據(jù)
    /// 根據(jù)條件查詢數(shù)據(jù)
    /// - Parameters:
    ///   - object: 對象類型
    ///   - predicate: 查詢條件
    /// - Returns: 返回查詢對象數(shù)組
    private static func queryWith(object: Object.Type,
                           predicate: NSPredicate) -> Results<Object>? {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return nil
        }
        return weakCurrentRealm.objects(object).filter(predicate)
    }

    // MARK: 帶排序條件查詢
    /// 帶排序條件查詢
    /// - Parameters:
    ///   - object: 對象類型
    ///   - predicate: 查詢條件
    ///   - sortedKey: 排序的鍵
    ///   - isAssending: 升序還是降序趣竣,默認(rèn)升序
    /// - Returns: 返回查詢對象數(shù)組
    private static func queryWithSorted(object: Object.Type,
                                 predicate: NSPredicate,
                                 sortedKey: String,
                               isAssending: Bool = true) -> Results<Object>? {
        guard let weakCurrentRealm = sharedInstance.currentRealm else {
            return nil
        }
        return weakCurrentRealm.objects(object).filter(predicate)
        .sorted(byKeyPath: sortedKey, ascending: isAssending)
    }

    // MARK: 查詢結(jié)果轉(zhuǎn)Array<Object>
    /// 查詢結(jié)果轉(zhuǎn)Array<Object>
    /// - Parameter results: 查詢結(jié)果
    /// - Returns: 返回Array<Object>
    private static func resultsToObjectList(results: Results<Object>) -> Array<Object> {
        var resultsArray = Array<Object>()
        if results.count > 0 {
            for i in 0...(results.count - 1) {
                resultsArray.append(results[I])
            }
        }
        return resultsArray
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摇庙,一起剝皮案震驚了整個濱河市旱物,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卫袒,老刑警劉巖宵呛,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夕凝,居然都是意外死亡宝穗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門码秉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逮矛,“玉大人,你說我怎么就攤上這事转砖⌒攵Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵府蔗,是天一觀的道長晋控。 經(jīng)常有香客問我,道長姓赤,這世上最難降的妖魔是什么赡译? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮不铆,結(jié)果婚禮上蝌焚,老公的妹妹穿的比我還像新娘。我一直安慰自己誓斥,他們只是感情好综看,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著岖食,像睡著了一般红碑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天析珊,我揣著相機與錄音羡鸥,去河邊找鬼。 笑死忠寻,一個胖子當(dāng)著我的面吹牛惧浴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奕剃,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼衷旅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纵朋?” 一聲冷哼從身側(cè)響起柿顶,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎操软,沒想到半個月后嘁锯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡聂薪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年家乘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藏澳。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡仁锯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翔悠,到底是詐尸還是另有隱情业崖,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布凉驻,位于F島的核電站腻要,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涝登。R本人自食惡果不足惜雄家,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胀滚。 院中可真熱鬧趟济,春花似錦、人聲如沸咽笼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剑刑。三九已至媳纬,卻和暖如春双肤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钮惠。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工茅糜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人素挽。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓蔑赘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親预明。 傳聞我的和親對象是個殘疾皇子缩赛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容