iOS-Swift之Realm的使用教程

版本:Realm Swift 3.15.0

使用要求

  • Xcode9.2或更高版本
  • 目标平台要iOS8或以上

安装

有3种方式:Dynamic Framwork\CocoaPods\Carthage

我是用CocoaPods安装的,说一下具体步骤。

  • 首先要先安装CocoaPods(1.1.0以上版本)
  • 然后在终端运行$ pod repo update 让 CocoaPods 更新realm的最新可用版本
  • 项目路径下终端运行$ pod init 新建Podfile文件(若已经有就不用新建了)
  • 在Podfile文件添加 use_frameworks!  和 pod 'RealmSwift' 
  • 在终端运行pod install 进行安装
  • 打开.xcworkspace结尾的文件以启动工程

Models模型

Realm的Model类必须继承Object。

属性必须使用 @objc dynamic var 特性,从而让其能够访问底层数据库的数据。

有3个例外,LinkingObjects \ List \ RealmOptional。这些属性不能声明为动态属性,因为泛型属性无法在 Objective-C 运行时中正确表示,而这个运行时是用来对 dynamic 属性进行动态调度的。这些属性应当始终用 let 进行声明。

import RealmSwift

class Person: Object {

    //属性必须使用 @objc dynamic var 特性,从而让其能够访问底层数据库的数据。
    @objc dynamic var tmpID = 0
    @objc dynamic var id = 0
    @objc dynamic var name = ""
    @objc dynamic var picture: Data? = nil //支持可选类型
    let dogs = List<Dog>()
    
    //设置主键--声明主键允许对象的查询和更新更加高效,并且会强制要求每个值保持唯一性。
    //主键的值一旦写入Realm便不能修改了
    override static func primaryKey() -> String? {
        return "id"
    }
    
    //设置索引属性--会让写的操作稍微慢些, 但用equality和IN操作符查询数据会更快.
    //最好在特殊的情况下使用索引属性,譬如希望能提升读取数据的速度的情况。
    override static func indexedProperties() -> [String] {
        return ["name"]
    }
    
    //设置忽略属性--不会保存在Realm数据库中
    //就像正常的属性,但不支持使用任何realm中的功能,例如是查询功能。但还是能通过KVO来观察值的变化。 
    override static func ignoredProperties() -> [String] {
        return ["tmpID"]
    }
   
}

操作Realm对象

1)对象的自动更新

let person = Person()
person.name = "Fido"
mperson.age = 1

try! realm.write {
    realm.add(person)
}

let targetPerson = realm.objects(Person.self).filter("age == 1").first
try! realm.write {
    targetPerson!.age = 2
}

print("age of my dog: \(person.age)") // => 2

2)model类继承

// Base Model
class Animal: Object {
    @objc dynamic var age = 0
}

// 与Animal类组合的models
class Duck: Object {
    @objc dynamic var animal: Animal? = nil
    @objc dynamic var name = ""
}
class Frog: Object {
    @objc dynamic var animal: Animal? = nil
    @objc dynamic var dateProp = Date()
}

// 使用
let duck = Duck(value: [ "animal": [ "age": 3 ], "name": "Gustav" ])

 

Writes写

  • models: 
class Dog: Object {
    @objc dynamic var name = ""
    @objc dynamic var color = ""
    @objc dynamic var age = 0
    
}

class Human: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    let dogs = List<Dog>()  
}
  • writes (写操作需要在transaction中)
//方法1 - 通过Dog的属性创建
let myDog = Dog()
myDog.name = "栗子"
myDog.color = "black"
myDog.age = 3
//方法2 - 通过字典创建
let myOtherDog = Dog(value: ["name":"happy","color":"white","age":1])
//方法3 - 通过数组创建
let myThirdDog = Dog(value: ["dogy","brown",3])
        
//利用存在的Dog Object创建
let aPerson = Human(value: ["James", 20, [myDog, myOtherDog]])
//直接创建
let anotherPerson = Human(value: ["Jane", 30, [["Buster","yellow", 5], ["Buddy","purple", 6]]])

// Write - 把数据写进realm数据库
try! realm.write {
     realm.add(myDog)
     realm.add(myOtherDog)
     realm.add(myThirdDog)
     realm.add(aPerson)
     realm.add(anotherPerson)           
}
  • 结果(通过Realm Browser查看,可以App Store直接下载):

 

Queries查询

  • 查询整个表格(因为realm中的查询都是懒加载的,只有在访问属性时才读取数据,所以不用担心会占用太多内存)
//查询整个Human表格 --> Results<Human>
let persons = realm.objects(Human.self)
  • 通过filter查询 
//通过filter查询1 --> Results<Dog>
let puppies = realm.objects(Dog.self).filter("age < 3")

//通过filter查询2 --> Results<Dog>
let targetDogs = realm.objects(Dog.self).filter("age = 2 AND name BEGINSWITH '栗'")
  • 通过NSPredicate查询 
//通过NSPredicate查询 --> Results<Human>
let predicate = NSPredicate(format: "age = 23 AND name BEGINSWITH %@", "J")
let targetHuman = realm.objects(Human.self).filter(predicate)

 

Update更新 (更新操作需要在transaction中)

  • 可在任何线程查询或更新
//可在任何线程查询或更新
DispatchQueue(label: "background").async {
    autoreleasepool {
        let realm = try! Realm()
        let persons = realm.objects(Human.self)
        try! realm.write {
            //把name这列数据的第一个James更新为James blunt(KeyPath是model中的变量)
            persons.first?.setValue("James blunt", forKeyPath: "name")
            //把age这列数据全部更新为23
            persons.setValue(23, forKeyPath: "age")

        }
    }
}
  • 有主键的model可直接更新 

let animal = Animal(value: [1,"elephant"])
try! realm.write {     
     //有主键的object可直接更新
     realm.add(animal, update: true)
}

 

Delete删除

  • 删除指定数据
let animal = Animal(value: [1,"elephant"])
try? realm.write {
     realm.delete(animal)
}
  • 删除所有
try! realm.write {
     realm.deleteAll()
}

Migration数据迁移

  • 当你想更新数据模型,例如在模型Animal类中新增属性age(原本只有id和name两个属性)。不仅要在model类中增加属性,还要进行migration操作。
class Animal: Object {
    @objc dynamic var id = 0
    @objc dynamic var name = ""
    @objc dynamic var age = 0

}
  • migration操作 - 在AppDelegate.swift中的 didFinishLaunchingWithOptions 函数中操作。要更新数据模型时增加下面的版本号即可。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let config = Realm.Configuration(
        // 设置新的图表版本. 一定要比之前的版本号要大,默认版本号是0.
        schemaVersion: 1,
            
        // 当打开低于上面版本realm数据库时会自动调用这个迁移闭包
        migrationBlock: { migration, oldSchemaVersion in
    
        if (oldSchemaVersion < 1) {
             // 不用做任何事,Realm会检测新的属性和移除旧的属性,然后自动更新数据库。
        }
    })
        
    // 使默认Realm使用新的配置
    Realm.Configuration.defaultConfiguration = config

    return true
}

 

参考自最新官方文档:https://realm.io/docs/swift/latest/

 

 

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值