1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import
Foundation
import
RealmSwift
//消费类型
class
ConsumeType
:
Object
{
//类型名
@objc
dynamic
var
name =
""
}
//消费条目
class
ConsumeItem
:
Object
{
//条目名
@objc
dynamic
var
name =
""
//金额
@objc
dynamic
var
cost = 0.00
//时间
@objc
dynamic
var
date =
Date
()
//所属消费类别
@objc
dynamic
var
type:
ConsumeType
?
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
import
UIKit
import
RealmSwift
class
ViewController
:
UIViewController
{
override
func
viewDidLoad() {
super
.viewDidLoad()
//使用默认的数据库
let
realm = try!
Realm
()
//查询全部的消费记录
let
items = realm.objects(
ConsumeItem
.
self
)
//已经有记录的话就不插入了
if
items.count>0 {
return
}
//建立两个消费类型
let
type1 =
ConsumeType
()
type1.name =
"购物"
let
type2 =
ConsumeType
()
type2.name =
"娱乐"
//建立三个消费记录
let
item1 =
ConsumeItem
(value: [
"买一台电脑"
,5999.00,
Date
(),type1])
//可以使用数组建立
let
item2 =
ConsumeItem
()
item2.name =
"看一场电影"
item2.cost = 30.00
item2.date =
Date
(timeIntervalSinceNow: -36000)
item2.type = type2
let
item3 =
ConsumeItem
()
item3.name =
"买一包泡面"
item3.cost = 2.50
item3.date =
Date
(timeIntervalSinceNow: -72000)
item3.type = type1
// 数据持久化操做(类型记录也会自动添加的)
try! realm.write {
realm.add(item1)
realm.add(item2)
realm.add(item3)
}
//打印出数据库地址
print
(realm.configuration.fileURL ??
""
)
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
|
1
2
|
//打印出数据库地址
print
(realm.configuration.fileURL ??
""
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
import
UIKit
import
RealmSwift
class
ViewController
:
UIViewController
,
UITableViewDelegate
,
UITableViewDataSource
{
@IBOutlet
weak
var
tableView:
UITableView
!
var
dformatter =
DateFormatter
()
//保存从数据库中查询出来的结果集
var
consumeItems:
Results
<
ConsumeItem
>?
override
func
viewDidLoad() {
super
.viewDidLoad()
self
.dformatter.dateFormat =
"MM月dd日 HH:mm"
self
.tableView!.delegate =
self
self
.tableView!.dataSource =
self
//建立一个重用的单元格
self
.tableView!.register(
UITableViewCell
.
self
, forCellReuseIdentifier:
"MyCell"
)
//使用默认的数据库
let
realm = try!
Realm
()
//查询全部的消费记录
consumeItems = realm.objects(
ConsumeItem
.
self
)
}
//在本例中,只有一个分区
func
numberOfSections(
in
tableView:
UITableView
) ->
Int
{
return
1;
}
//返回表格行数(也就是返回控件数)
func
tableView(_ tableView:
UITableView
, numberOfRowsInSection section:
Int
) ->
Int
{
return
self
.consumeItems!.count
}
//建立各单元显示内容(建立参数indexPath指定的单元)
func
tableView(_ tableView:
UITableView
, cellForRowAt indexPath:
IndexPath
)
->
UITableViewCell
{
//同一形式的单元格重复使用,在声明时已注册
let
cell =
UITableViewCell
(style: .value1, reuseIdentifier:
"MyCell"
)
let
item =
self
.consumeItems![indexPath.row]
cell.textLabel?.text = item.name +
" ¥"
+
String
(format:
"%.1f"
, item.cost)
cell.detailTextLabel?.text =
self
.dformatter.string(from: item.date)
return
cell
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
|
1
2
3
4
5
6
|
//查询并取出前5条数据
let
dogs = try!
Realm
().objects(
Dog
.
self
)
for
i
in
0..<5 {
let
dog = dogs[i]
// ...
}
|
1
2
3
4
5
6
7
8
9
|
//查询花费超过10元的消费记录(使用断言字符串查询)
consumeItems = realm.objects(
ConsumeItem
.
self
).
filter
(
"cost > 10"
)
//查询花费超过10元的购物记录(使用 NSPredicate 查询)
let
predicate =
NSPredicate
(format:
"type.name = '购物' AND cost > 10"
)
consumeItems = realm.objects(
ConsumeItem
.
self
).
filter
(predicate)
//使用链式查询
consumeItems = realm.objects(
ConsumeItem
.
self
).
filter
(
"cost > 10"
).
filter
(
"type.name = '购物'"
)
|
1
2
|
//查询花费超过10元的消费记录,并按升序排列
consumeItems = realm.objects(
ConsumeItem
.
self
).
filter
(
"cost > 10"
).sorted(byKeyPath:
"cost"
)
|
1
2
3
4
5
6
7
8
9
10
|
class
Person
:
Object
{
...
// 其他的属性声明
let
dogs =
List
<
Dog
>()
}
// 这里咱们就可使用已存在的狗狗对象来完成初始化
let
aPerson =
Person
(value: [
"李四"
, 30, [aDog, anotherDog]])
// 还可使用多重嵌套
let
aPerson =
Person
(value: [
"李四"
, 30, [[
"小黑"
, 5], [
"旺财"
, 6]]])
|
1
2
3
|
let
someDogs = realm.objects(
Dog
.
self
).
filter
(
"name contains '小白'"
)
ZhangSan
.dogs.append(objectsIn: someDogs)
ZhangSan
.dogs.append(dahuang)
|
1
2
3
4
5
6
7
8
|
class
Dog
:
Object
{
@objc
dynamic
var
name =
""
@objc
dynamic
var
age = 0
// Realm 并不会存储这个属性,由于这个属性只定义了 getter
// 定义“owners”,和 Person.dogs 创建反向关系
let
owners =
LinkingObjects
(fromType:
Person
.
self
, property:
"dogs"
)
}
|
1
2
3
4
5
6
7
8
|
class
Person
:
Object
{
@objc
dynamic
var
id = 0
@objc
dynamic
var
name =
""
override
static
func
primaryKey() ->
String
? {
return
"id"
}
}
|
1
2
3
4
5
6
7
8
|
class
Book
:
Object
{
@objc
dynamic
var
price = 0
@objc
dynamic
var
title =
""
override
static
func
indexedProperties() -> [
String
] {
return
[
"title"
]
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
class
Person
:
Object
{
@objc
dynamic
var
tmpID = 0
var
name:
String
{
// 计算属性将被自动忽略
return
"\(firstName) \(lastName)"
}
@objc
dynamic
var
firstName =
""
@objc
dynamic
var
lastName =
""
override
static
func
ignoredProperties() -> [
String
] {
return
[
"tmpID"
]
}
}
|
1
2
3
4
|
// 在一个事务中更新对象
try! realm.write {
consumeItem.name =
"去北京旅行"
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/****** 方式1 ***/
// 建立一个带有主键的“书籍”对象,做为事先存储的书籍
let
cheeseBook =
Book
()
cheeseBook.title =
"奶酪食谱"
cheeseBook.price = 9000
cheeseBook.id = 1
// 经过 id = 1 更新该书籍
try! realm.write {
realm.add(cheeseBook, update:
true
)
}
/****** 方式2 ***/
// 假设带有主键值 `1` 的“书籍”对象已经存在
try! realm.write {
realm.create(
Book
.
self
, value: [
"id"
: 1,
"price"
: 22], update:
true
)
// 这本书的`title`属性不会被改变
}
|
1
2
3
4
5
6
7
|
let
persons = realm.objects(
Person
.
self
)
try! realm.write {
// 更新第一个
persons.first?.setValue(
true
, forKeyPath:
"isFirst"
)
// 将每一个人的 planet 属性设置为“地球”
persons.setValue(
"地球"
, forKeyPath:
"planet"
)
}
|
1
2
3
4
5
6
|
let
cheeseBook = ...
// 存储在 Realm 中的 Book 对象
// 在事务中删除一个对象
try! realm.write {
realm.delete(cheeseBook)
}
|
1
2
3
4
|
// 从 Realm 中删除全部数据
try! realm.write {
realm.deleteAll()
}
|
1
2
3
4
5
6
7
8
9
10
|
func
setDefaultRealmForUser(username:
String
) {
var
config =
Realm
.
Configuration
()
// 使用默认的目录,可是使用用户名来替换默认的文件名
config.fileURL = config.fileURL!.deletingLastPathComponent()
.appendingPathComponent(
"\(username).realm"
)
// 将这个配置应用到默认的 Realm 数据库当中
Realm
.
Configuration
.defaultConfiguration = config
}
|
1
2
3
4
5
6
7
8
9
10
11
|
let
config =
Realm
.
Configuration
(
// 获取须要打包文件的 URL 路径
fileURL:
Bundle
.main.url(forResource:
"MyBundledData"
, withExtension:
"realm"
),
// 以只读模式打开文件,由于应用数据包并不可写
readOnly:
true
)
// 经过配置打开 Realm 数据库
let
realm = try!
Realm
(configuration: config)
// 经过配置打开 Realm 数据库
let
results = realm.objects(
Dog
.
self
).
filter
(
"age > 5"
)
|
1
|
let
realm = try!
Realm
(configuration:
Realm
.
Configuration
(inMemoryIdentifier:
"MyInMemoryRealm"
))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/***** 在建立 Realm 数据库时采用64位的密钥对数据库文件进行 AES-256+SHA2 加密 ****/
// 产生随机密钥
var
key =
Data
(count: 64)
_ = key.withUnsafeMutableBytes { bytes
in
SecRandomCopyBytes
(kSecRandomDefault, 64, bytes)
}
// 打开加密文件
let
config =
Realm
.
Configuration
(encryptionKey: key)
let
realm:
Realm
do {
realm = try
Realm
(configuration: config)
} catch
let
error
as
NSError
{
// 若是密钥错误,`error` 会提示数据库不可访问
fatalError(
"Error opening realm: \(error)"
)
}
// 和往常同样使用 Realm 便可
let
dogs = realm.objects(
Book
.
self
).
filter
(
"name contains 'Fido'"
)
|
1
2
3
4
5
|
class
Person
:
Object
{
@objc
dynamic
var
firstName =
""
@objc
dynamic
var
lastName =
""
@objc
dynamic
var
age = 0
}
|
1
2
3
4
|
class
Person
:
Object
{
@objc
dynamic
var
fullName =
""
@objc
dynamic
var
age = 0
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 在(application:didFinishLaunchingWithOptions:)中进行配置
let
config =
Realm
.
Configuration
(
// 设置新的架构版本。这个版本号必须高于以前所用的版本号
// (若是您以前从未设置过架构版本,那么这个版本号设置为 0)
schemaVersion: 1,
// 设置闭包,这个闭包将会在打开低于上面所设置版本号的 Realm 数据库的时候被自动调用
migrationBlock: { migration, oldSchemaVersion
in
// 目前咱们还未进行数据迁移,所以 oldSchemaVersion == 0
if
(oldSchemaVersion < 1) {
// 什么都不要作!Realm 会自行检测新增和须要移除的属性,而后自动更新硬盘上的数据库架构
}
})
// 告诉 Realm 为默认的 Realm 数据库使用这个新的配置对象
Realm
.
Configuration
.defaultConfiguration = config
// 如今咱们已经告诉了 Realm 如何处理架构的变化,打开文件以后将会自动执行迁移
let
realm = try!
Realm
()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 在 application(application:didFinishLaunchingWithOptions:) 中进行配置
|