Skip to content

Commit c161c16

Browse files
committed
addresses #57
1 parent 82825ad commit c161c16

File tree

2 files changed

+95
-58
lines changed

2 files changed

+95
-58
lines changed

README.md

+95-58
Original file line numberDiff line numberDiff line change
@@ -5,104 +5,117 @@
55
[![License](https://img.shields.io/cocoapods/l/RxRealm.svg?style=flat)](http://cocoapods.org/pods/RxRealm)
66
[![Platform](https://img.shields.io/cocoapods/p/RxRealm.svg?style=flat)](http://cocoapods.org/pods/RxRealm)
77

8-
## Usage
8+
This library is a thin wrapper around __RealmSwift__ ( [Realm Docs](https://realm.io/docs/swift/latest/) ).
99

10-
This library is a thin wrapper around __RealmSwift__.
10+
**Table of contents:**
1111

12-
### Observing collections
12+
1. Observing object collections
13+
2. Observing a single object
14+
3. Write transactions
15+
4. Automatically binding table and collection views
16+
5. Example app
1317

14-
RxRealm can be used to create `Observable`s from objects of type `Results`, `List`, `LinkingObjects` or `AnyRealmCollection` as follows:
18+
## Observing object collections
1519

16-
#### Observable.from(_:)
17-
Emits every time the collection changes
20+
RxRealm can be used to create `Observable`s from objects of type `Results`, `List`, `LinkingObjects` or `AnyRealmCollection`. These types are typically used to load and observe object collections from the Realm Mobile Database.
21+
22+
##### `Observable.collection(from:synchronizedStart:)`
23+
Emits an event each time the collection changes:
1824

1925
```swift
2026
let realm = try! Realm()
2127
let laps = realm.objects(Lap.self)
2228

23-
Observable.from(laps)
29+
Observable.collection(from: laps)
2430
.map {
2531
laps in "\(laps.count) laps"
26-
}.subscribe(onNext: { text in
32+
}
33+
.subscribe(onNext: { text in
2734
print(text)
2835
})
2936
```
3037

31-
#### Observable.arrayFrom(_:)
32-
Fetches the a snapshot of a Realm collection and converts it to an array value (for example if you want to use array methods on the collection)
38+
The above prints out "X laps" each time a lap is added or removed from the database. If you set `synchronizedStart` to `true` (the default value), the first element will be emitted synchronously - e.g. when you're binding UI you might not be able for an asynchronous notification to come through.
39+
40+
##### `Observable.array(from:synchronizedStart:)`
41+
Upon each change fetches a snapshot of the Realm collection and converts it to an array value (for example if you want to use array methods on the collection):
3342

3443
```swift
3544
let realm = try! Realm()
3645
let laps = realm.objects(Lap.self)
3746

38-
Observable.arrayFrom(laps)
47+
Observable.array(from: laps)
3948
.map { array in
4049
return array.prefix(3) //slice of first 3 items
41-
}.subscribe(onNext: { text in
50+
}
51+
.subscribe(onNext: { text in
4252
print(text)
4353
})
4454
```
4555

46-
#### Observable.changesetFrom(_:)
47-
Emits every time the collection changes and provides the exact indexes that has been deleted, inserted or updated
56+
##### `Observable.changeset(from:synchronizedStart:)`
57+
Emits every time the collection changes and provides the exact indexes that has been deleted, inserted or updated:
4858

4959
```swift
5060
let realm = try! Realm()
5161
let laps = realm.objects(Lap.self))
5262

53-
Observable.changesetFrom(laps)
63+
Observable.changeset(from: laps)
5464
.subscribe(onNext: { results, changes in
5565
if let changes = changes {
56-
// it's an update
57-
print(results)
58-
print("deleted: \(changes.deleted) inserted: \(changes.inserted) updated: \(changes.updated)")
59-
} else {
60-
// it's the initial data
61-
print(results)
62-
}
66+
// it's an update
67+
print(results)
68+
print("deleted: \(changes.deleted)")
69+
print("inserted: \(changes.inserted)")
70+
print("updated: \(changes.updated)")
71+
} else {
72+
// it's the initial data
73+
print(results)
74+
}
6375
})
6476
```
6577

66-
#### Observable.changesetArrayFrom(_:)
67-
Combines the result of `Observable.arrayFrom(_:)` and `Observable.changesetFrom(_:)` returning an `Observable<Array<T>, RealmChangeset?>`
78+
##### `Observable.arrayWithChangeset(from:synchronizedStart:)`
79+
Combines the result of `Observable.array(from:)` and `Observable.changeset(from:)` returning an `Observable<Array<T>, RealmChangeset?>`
6880

6981
```swift
7082
let realm = try! Realm()
7183
let laps = realm.objects(Lap.self))
7284

73-
Observable.changesetArrayFrom(laps)
85+
Observable.arrayWithChangeset(from: laps)
7486
.subscribe(onNext: { array, changes in
7587
if let changes = changes {
7688
// it's an update
7789
print(array.first)
78-
print("deleted: \(changes.deleted) inserted: \(changes.inserted) updated: \(changes.updated)")
90+
print("deleted: \(changes.deleted)")
91+
print("inserted: \(changes.inserted)")
92+
print("updated: \(changes.updated)")
7993
} else {
8094
// it's the initial data
8195
print(array)
8296
}
8397
})
8498
```
8599

86-
### Observing a single object
100+
## Observing a single object
87101

88-
There's a separate API to make it easier to observe single object (it creates `Results` behind the scenes):
102+
There's a separate API to make it easier to observe a single object (it creates `Results` behind the scenes):
89103

90104
```swift
91-
Observable.from(ticker)
92-
.map({ (ticker) -> String in
105+
Observable.from(object: ticker)
106+
.map { ticker -> String in
93107
return "\(ticker.ticks) ticks"
94-
})
108+
}
95109
.bindTo(footer.rx.text)
96110
```
97111

98112
This API uses the primary key of the object to query the database for it and observe for change notifications. Observing objects without a primary key does not work.
99113

100-
### Performing transactions
114+
## Write transactions
101115

102-
#### rx.add()
103-
##### **Writing to an existing Realm reference**
116+
##### `rx.add()`
104117

105-
You can add newly created objects to a Realm that you already have initialized:
118+
Writing objects to **existing** realm reference. You can add newly created objects to a Realm that you already have initialized:
106119

107120
```swift
108121
let realm = try! Realm()
@@ -114,8 +127,9 @@ Observable.from(messages)
114127

115128
Be careful, this will retain your Realm until the `Observable` completes or errors out.
116129

117-
##### **Writing to the default Realm**
118-
You can leave it to RxRealm to grab the default Realm on any thread your subscribe and write objects to it:
130+
##### `Realm.rx.add()`
131+
132+
Writing to the default Realm. You can leave it to RxRealm to grab the default Realm on any thread your subscribe and write objects to it:
119133

120134
```swift
121135
let messages = [Message("hello"), Message("world")]
@@ -124,16 +138,17 @@ Observable.from(messages)
124138
.subscribe(Realm.rx.add())
125139
```
126140

127-
##### **Writing to a specific Realm**
128-
If you want to switch threads and not use the default Realm, provide a `Realm.Configuration`:
141+
###### `Realm.rx.add(configuration:)`
142+
143+
Writing to a **custom** Realm. If you want to switch threads and not use the default Realm, provide a `Realm.Configuration`:
129144

130145
```swift
131146
var config = Realm.Configuration()
132147
/* custom configuration settings */
133148

134149
let messages = [Message("hello"), Message("world")]
135150
Observable.from(messages)
136-
.observeOn( /* you can switch threads if you want to */ )
151+
.observeOn( /* you can switch threads here */ )
137152
.subscribe(Realm.rx.add(configuration: config))
138153
```
139154

@@ -143,7 +158,7 @@ If you want to create a Realm on a different thread manually, allowing you to ha
143158
let messages = [Message("hello"), Message("world")]
144159

145160
Observable.from(messages)
146-
.observeOn( /* you can switch threads if you want to */ )
161+
.observeOn( /* you can switch threads here */ )
147162
.subscribe(onNext: {messages in
148163
let realm = try! Realm()
149164
try! realm.write {
@@ -152,9 +167,10 @@ Observable.from(messages)
152167
})
153168
```
154169

155-
#### rx.delete()
170+
##### `rx.delete()`
171+
172+
Deleting object(s) from an existing realm reference:
156173

157-
#####**Deleting from an existing realm reference**
158174
```swift
159175
let realm = try! Realm()
160176
let messages = realm.objects(Message.self)
@@ -164,14 +180,46 @@ Observable.from(messages)
164180

165181
Be careful, this will retain your realm until the `Observable` completes or errors out.
166182

167-
#####**Deleting from the object's realm automatically**
168-
You can leave it to RxRealm to grab the Realm from the first object and use it:
183+
##### `Realm.rx.delete()`
184+
185+
Deleting from the object's realm automatically. You can leave it to RxRealm to grab the Realm from the first object and use it:
169186

170187
```swift
171188
Observable.from(someCollectionOfPersistedObjects)
172189
.subscribe(Realm.rx.delete())
173190
```
174191

192+
## Automatically binding table and collection views
193+
194+
RxRealm does not depend on UIKit/Cocoa and it doesn't provide built-in way to bind Realm collections to UI components.
195+
196+
There is a separate library __`RxRealmDataSources`__ [link](https://github.com/RxSwiftCommunity/RxRealmDataSources), which mimics the default data sources library for RxSwift
197+
198+
`RxRealmDataSources` allows you to bind directly an observable collection of Realm objects to a table or collection view. Here's how the code to bind a collection of laps to a table view looks like:
199+
200+
```swift
201+
// create data source
202+
let dataSource = RxTableViewRealmDataSource<Lap>(
203+
cellIdentifier: "Cell", cellType: PersonCell.self) {cell, ip, lap in
204+
cell.customLabel.text = "\(ip.row). \(lap.text)"
205+
}
206+
207+
// RxRealm to get Observable<Results>
208+
let realm = try! Realm()
209+
let lapsList = realm.objects(Timer.self).first!.laps
210+
let laps = Observable.changeset(from: lapsList)
211+
212+
// bind to table view
213+
laps
214+
.bindTo(tableView.rx.realmChanges(dataSource))
215+
.addDisposableTo(bag)
216+
```
217+
218+
The data source will reflect all changes via animations to the table view:
219+
220+
![RxRealm animated changes](assets/animatedChanges.gif)
221+
222+
If you want to learn more check the __`RxRealmDataSources`__ [README](https://github.com/RxSwiftCommunity/RxRealmDataSources).
175223

176224
## Example app
177225

@@ -195,31 +243,20 @@ pod "RxRealm"
195243

196244
#### Carthage
197245

198-
RxRealm is available through [Carthage](https://github.com/Carthage/Carthage). You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
199-
200-
```bash
201-
$ brew update
202-
$ brew install carthage
203-
```
204-
205246
To integrate RxRealm into your Xcode project using Carthage, specify it in your `Cartfile`:
206247

207248
```ogdl
208-
github "RxSwiftCommunity/RxRealm" ~> 1.0
249+
github "RxSwiftCommunity/RxRealm"
209250
```
210251

211252
Run `carthage update` to build the framework and drag the built `RxRealm.framework` into your Xcode project.
212253

213-
#### As Source
214-
215-
You can grab the files in `Pod/Classes` from this repo and include them in your project.
216-
217254
## TODO
218255

219256
* Test add platforms and add compatibility for the pod
220257

221258
## License
222259

223-
This library belongs to _RxSwiftCommunity_.
260+
This library belongs to _RxSwiftCommunity_. Maintainer is [Marin Todorov](https://github.com/icanzilb).
224261

225262
RxRealm is available under the MIT license. See the LICENSE file for more info.

assets/animatedChanges.gif

1000 KB
Loading

0 commit comments

Comments
 (0)