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
}
}