Topics

Topics

In Bite #231, we took a look at Realm's new Fine-grained notifications functionality. Today we'll build upon this by checking out another new Realm feature: Queryable, Live Inverse Collections. Whew! That's a fancy name. This feature deserves one though, let's check it out.

Here's a Realm object with a relationship defined on it:

classPerson:Object{dynamicvarname=""letdogs=List<Dog>()}

That dogsproperty can be used in a query, and it will even stay updated to reflect changes to the property's value made elsewhere in our app, automatically.

None of that is new though. What is new is the inverse of this mechanic.

LinkingObjects are live and auto-updating. When new relationships are formed or removed, they will update to reflect the new state.

LinkingObjects can be used In queries, natively. (Previously this would need to be done in our code):

// People that have a child that have a parent named Diane.realm.objects(Person).filter("ANY children.parents.name == 'Diane'")// People whose parents have an average age of > 65.realm.objects(Person).filter("parents.@avg.age > 65")

LinkingObjects behave like regular Realm collections:

// Which of my parents are over the age of 56?self.parents.filter("age > 56")// Calculate the age of my parents.self.parents.average("age")

Topics

Topics

We first looked at Realm way back in Bite #49. It's a great data storage solution for our mobile apps. Today we'll start looking at some of the latest improvements in Realm and the new capabilities they offer. First up is Fine-grained notifications. Let's dive in:

Realm has offered notifications of write operations for a while, they look like this:

.Update's values can be easily mapped to NSIndexPath objects suitable for use in table views and collection views.

Here's a complete example showing all of this in action:

classSpaceshipsViewController:UITableViewController{varnotificationToken:NotificationToken?=niloverridefuncviewDidLoad(){super.viewDidLoad()letrealm=try!Realm()letresults=realm.objects(Spaceships).filter("maxSpeed > 0")// Observe Results NotificationsnotificationToken=results.addNotificationBlock{[weakself](changes:RealmCollectionChange)inguardlettableView=self?.tableViewelse{return}switchchanges{case.Initial:// Results are now populated and can be accessed without blocking the UItableView.reloadData()breakcase.Update(_,letdeletions,letinsertions,letmodifications):// Query results have changed, so apply them to the UITableViewtableView.beginUpdates()tableView.insertRowsAtIndexPaths(insertions.map{NSIndexPath(forRow:$0,inSection:0)},withRowAnimation:.Automatic)tableView.deleteRowsAtIndexPaths(deletions.map{NSIndexPath(forRow:$0,inSection:0)},withRowAnimation:.Automatic)tableView.reloadRowsAtIndexPaths(modifications.map{NSIndexPath(forRow:$0,inSection:0)},withRowAnimation:.Automatic)tableView.endUpdates()breakcase.Error(leterror):// An error occurred while opening the Realm file on the background worker threadfatalError("\(error)")break}}}deinit{notificationToken?.stop()}}

Define a Related Object

Create an Instance of an Object

varship=Spaceship()ship.name="Outrider"ship.topSpeed=1150vardash=User()dash.firstName="Dash"dash.lastName="Rendar"ship.owner=dash// need one Realm per threadletrealm=Realm()realm.write{realm.add(ship)}

Find Objects

Queries in Realm couldn't be simpler. They are chainable. You can add as many calls to .filter as you'd like. You can sort results using the chainable sorted function.