Usefuland practical
functionalities
in Realm cocoa
Realm meetup#1
trippiece Inc.
@kitasuke
Table ofcontents
- Encryption
- Migration
- Multiprocess
- Tips & Tools
Encryption
Realm supports encryptingthe
database file on diskwith
AES-256+SHA2 bysupplyinga64-
byte encryption keywhen
creatingaRealm.
Make sure that the encryption key should be set
before opening any Realm
OpenaRealmwithan encryption key
// Open the encrypted Realm file
RLMRealm *realm = [RLMRealm realmWithPath:[RLMRealm defaultRealmPath]
encryptionKey:encryptionKey
readOnly:NO
error:nil];
Realm can storethe encryption keyin
memory
// Set the encryption key for the default Realm
[RLMRealm setEncryptionKey:key forRealmsAtPath:[RLMRealm defaultRealmPath]];
RLMRealm *realm = [RLMRealm defaultRealm];
Setthe encryption keyto unencrypted Realm
@autoreleasepool {
RLMRealm *realm = [RLMRealm defaultRealm];
[[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath]
error:nil];
[realm beginWriteTransaction];
[realm writeCopyToPath:[RLMRealm defaultRealmPath]
encryptionKey:encryptionKey
error:nil];
[realm commitWriteTransaction];
}
[[RLMRealm defaultRealm]
writeCopyToPath:pathToRealmCopy
encryptionKey:encryptionKey error:nil]; needs to be
wrapped in @autoreleasepool { }
Notsupported using encrypted Realmswitha
debuggerattachedtothe process priorto
0.91.0
+ (RLMRealm *)encryptedRealm
{
#ifdef DEBUG
return [RLMRealm defaultRealm];
#endif
return [RLMRealm realmWithPath:[RLMRealm defaultRealmPath]
encryptionKey:encryptionKey
readOnly:NO
error:nil];
}
Notsupported opening encrypted Realm on
Realm browserapp
Afewcriticalbugs fixed in 0.91.0
- Crashes on ARM64
- Crashes when changing encryption key
- Not actually writing the entire file, and a crash
after large commits
Migration
migration block providesallthe
logic for converting datamodels
from previous schemastothe new
schema
Make sure that migration should be done before
opening any Realm
Addanewproperty
Previous schema
@interface Company
@property NSInteger ID;
@end
New schema
@interface Company
@property NSInteger ID;
@property NSString *name; // new one
@end
Setanewpropertytypewith defaultvalue
RLMMigrationBlock migrationBlock = ^(RLMMigration *migration, NSUInteger oldSchemaVersion) {
if (oldSchemaVersion < 1) {
[migrationBlock enumerateObjects:[Company className] block:^(RLMObject *oldObject, RLMObject *newObject) {
Company *company = (Company *)newObject;
[company setObject:@(RLMPropertyTypeString) forKeyedSubscript:@"name"];
}
}
}
[RLMRealm setSchemaVersion:1 forRealmAtPath:[RLMRealm defaultRealmPath] withMigrationBlock:migrationBlock];
@implementation Company
+ (NSDictionary *)defaultPropertyValues
{
return @{
@"name": @"company name"
};
}
@end
Setdefaultvalue foranewproperty
RLMMigrationBlock migrationBlock = ^(RLMMigration *migration, NSUInteger oldSchemaVersion) {
if (oldSchemaVersion < 1) {
[migrationBlock enumerateObjects:[Company className] block:^(RLMObject *oldObject, RLMObject *newObject) {
Company *company = (Company *)newObject;
company.name = @"company name";
}
}
}
[RLMRealm setSchemaVersion:1 forRealmAtPath:[RLMRealm defaultRealmPath] withMigrationBlock:migrationBlock];
Add newpropertyhaving oneto one
relationships
New schema
@interface Company
@property NSInteger ID;
@property NSString *name;
@property Employee *employee; // new one
@end
RLMMigrationBlock migrationBlock = ^(RLMMigration *migration, NSUInteger oldSchemaVersion) {
if (oldSchemaVersion < 1) {
[migrationBlock enumerateObjects:[Company className] block:^(RLMObject *oldObject, RLMObject *newObject) {
Company *company = (Company *)newObject;
company.employee = [Employee new];
}
}
}
[RLMRealm setSchemaVersion:1 forRealmAtPath:[RLMRealm defaultRealmPath] withMigrationBlock:migrationBlock];
Multiprocess
Seamlesslysharing
Realm files between
multiple processes
forAppExtensions
Putthe Realm file inyourappgroup
container
// Get the shared directory for the application group
NSURL *container = [[NSFileManager defaultManager]
containerURLForSecurityApplicationGroupIdentifier:@"group.com.example.my-app"];
// Set the default realm path to a location in the shared container
// You can also pass a path in the container to +[RLMRealm realmWithPath:], of course
NSURL *realmURL = [containerURL URLByAppendingPathComponent:@"default.realm"];
[RLMRealm setDefaultRealmPath:realmURL.path];
Currentlimitations
- Encrypted Realms cannot be shared between
processes.
- All processes must be running on a single machine,
and must be the same architecture (so no sharing
Realm files on a network drive, and opening a Realm
in both an iOS simulator and an OS X application
requires using a 64-bit simulator).
- All processes must be using the same version of
Realm Cocoa, and must have identical object schemas.
tips & tools
use grepwith 'RLMException'
@throw RLMException(@"Cannot set schema version for Realms that are already open.");
@throw RLMException(@"Encryption key must be exactly 64 bytes long");
@throw RLMException(@"Custom schema only supported when using dynamic Realms");
@throw RLMException(@"The notification block should not be nil");
@throw RLMException(@"The Realm is already in a write transaction");
@throw RLMException(@"Invalid array type - container must be an RLMArray, RLMArray, or NSArray of RLMObjects");
@throw RLMException(@"Cannot migrate Realms that are already open.");
@throw RLMException(@"Can't mutate a persisted array outside of a write transaction.");
@throw RLMException(@"Object type does not match RLMResults");
@throw RLMException(@"RLMArray properties require a protocol defining the contained type - example: RLMArray<Person>");
@throw RLMException([NSString stringWithFormat:@"Migration is required for object type '%@' due to the following errors:n- %@",
objectSchema.className, [exceptionMessages componentsJoinedByString:@"n- "]]);
ues grepwith 'FIXME'
// FIXME: make sure delete rules don't purge objects
// FIXME - enable when Any supports links
// FIXME - enable for ints when we have core suppport
// FIXME: Add condition to check for Mixed once it can support a nil value.
// FIXME: int64_t should be DateTime but that doesn't work on 32 bit
// FIXME: for new apis only return swift initialized values
// FIXME - remove deleted tables
// FIXME: this should be supported by core in some way
takea lookatCHANGELOG.md
+Master Release notes
+=============================================================
+
+### Enhancements
+
+* The browser will automatically refresh when the Realm has been modified
+ from another process.
+
0.91.0 Release notes (2015-03-10)
=============================================================
takealookatIssues
- LLDB hangs when debugging an application that is
using an encrypted Realm.
- Support Carthage prebuilt framework
- App crashes on read when using writeCopyToPath: to
compact encrypted realm
- Add RLMConfiguration
- Support querying "%@ IN (RLMArray keypath)"
- multiple realms contain all classes
- Swift: Nested JSON Objects
takea lookatGoogle Groups
- SQL Join in Realm
- HOW TO FETCH ALL CHILD NODE DATA??
- Integer to String conversion
- Querying by large number of Integer values via
predicate with IN clause
- Realm Online Office Hours next week - Ask us
anything :)
- Fine grained notifications and core open sourcing
- Time Frame
Realm +JSONhttps://github.com/matthewcheok/Realm-JSON
+ (NSDictionary *)JSONInboundMappingDictionary {
return @{
@"episode.title": @"title",
@"episode.description": @"subtitle",
@"episode.id": @"episodeID",
@"episode.episode_number": @"episodeNumber",
@"episode.episode_type": @"episodeType",
@"episode.thumbnail_url": @"thumbnailURL",
@"episode.published_at": @"publishedDate",
};
}
JSONExporthttps://github.com/Ahmed-Ali/JSONExport
Any questions?

Useful and Practical Functionalities in Realm

  • 1.
    Usefuland practical functionalities in Realmcocoa Realm meetup#1 trippiece Inc. @kitasuke
  • 4.
    Table ofcontents - Encryption -Migration - Multiprocess - Tips & Tools
  • 5.
  • 6.
    Realm supports encryptingthe databasefile on diskwith AES-256+SHA2 bysupplyinga64- byte encryption keywhen creatingaRealm. Make sure that the encryption key should be set before opening any Realm
  • 7.
    OpenaRealmwithan encryption key //Open the encrypted Realm file RLMRealm *realm = [RLMRealm realmWithPath:[RLMRealm defaultRealmPath] encryptionKey:encryptionKey readOnly:NO error:nil];
  • 8.
    Realm can storetheencryption keyin memory // Set the encryption key for the default Realm [RLMRealm setEncryptionKey:key forRealmsAtPath:[RLMRealm defaultRealmPath]]; RLMRealm *realm = [RLMRealm defaultRealm];
  • 9.
    Setthe encryption keytounencrypted Realm @autoreleasepool { RLMRealm *realm = [RLMRealm defaultRealm]; [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:nil]; [realm beginWriteTransaction]; [realm writeCopyToPath:[RLMRealm defaultRealmPath] encryptionKey:encryptionKey error:nil]; [realm commitWriteTransaction]; } [[RLMRealm defaultRealm] writeCopyToPath:pathToRealmCopy encryptionKey:encryptionKey error:nil]; needs to be wrapped in @autoreleasepool { }
  • 10.
    Notsupported using encryptedRealmswitha debuggerattachedtothe process priorto 0.91.0 + (RLMRealm *)encryptedRealm { #ifdef DEBUG return [RLMRealm defaultRealm]; #endif return [RLMRealm realmWithPath:[RLMRealm defaultRealmPath] encryptionKey:encryptionKey readOnly:NO error:nil]; }
  • 11.
    Notsupported opening encryptedRealm on Realm browserapp
  • 12.
    Afewcriticalbugs fixed in0.91.0 - Crashes on ARM64 - Crashes when changing encryption key - Not actually writing the entire file, and a crash after large commits
  • 13.
  • 14.
    migration block providesallthe logicfor converting datamodels from previous schemastothe new schema Make sure that migration should be done before opening any Realm
  • 15.
    Addanewproperty Previous schema @interface Company @propertyNSInteger ID; @end New schema @interface Company @property NSInteger ID; @property NSString *name; // new one @end
  • 16.
    Setanewpropertytypewith defaultvalue RLMMigrationBlock migrationBlock= ^(RLMMigration *migration, NSUInteger oldSchemaVersion) { if (oldSchemaVersion < 1) { [migrationBlock enumerateObjects:[Company className] block:^(RLMObject *oldObject, RLMObject *newObject) { Company *company = (Company *)newObject; [company setObject:@(RLMPropertyTypeString) forKeyedSubscript:@"name"]; } } } [RLMRealm setSchemaVersion:1 forRealmAtPath:[RLMRealm defaultRealmPath] withMigrationBlock:migrationBlock]; @implementation Company + (NSDictionary *)defaultPropertyValues { return @{ @"name": @"company name" }; } @end
  • 17.
    Setdefaultvalue foranewproperty RLMMigrationBlock migrationBlock= ^(RLMMigration *migration, NSUInteger oldSchemaVersion) { if (oldSchemaVersion < 1) { [migrationBlock enumerateObjects:[Company className] block:^(RLMObject *oldObject, RLMObject *newObject) { Company *company = (Company *)newObject; company.name = @"company name"; } } } [RLMRealm setSchemaVersion:1 forRealmAtPath:[RLMRealm defaultRealmPath] withMigrationBlock:migrationBlock];
  • 18.
    Add newpropertyhaving onetoone relationships New schema @interface Company @property NSInteger ID; @property NSString *name; @property Employee *employee; // new one @end RLMMigrationBlock migrationBlock = ^(RLMMigration *migration, NSUInteger oldSchemaVersion) { if (oldSchemaVersion < 1) { [migrationBlock enumerateObjects:[Company className] block:^(RLMObject *oldObject, RLMObject *newObject) { Company *company = (Company *)newObject; company.employee = [Employee new]; } } } [RLMRealm setSchemaVersion:1 forRealmAtPath:[RLMRealm defaultRealmPath] withMigrationBlock:migrationBlock];
  • 19.
  • 20.
  • 21.
    Putthe Realm fileinyourappgroup container // Get the shared directory for the application group NSURL *container = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.example.my-app"]; // Set the default realm path to a location in the shared container // You can also pass a path in the container to +[RLMRealm realmWithPath:], of course NSURL *realmURL = [containerURL URLByAppendingPathComponent:@"default.realm"]; [RLMRealm setDefaultRealmPath:realmURL.path];
  • 22.
    Currentlimitations - Encrypted Realmscannot be shared between processes. - All processes must be running on a single machine, and must be the same architecture (so no sharing Realm files on a network drive, and opening a Realm in both an iOS simulator and an OS X application requires using a 64-bit simulator). - All processes must be using the same version of Realm Cocoa, and must have identical object schemas.
  • 23.
  • 24.
    use grepwith 'RLMException' @throwRLMException(@"Cannot set schema version for Realms that are already open."); @throw RLMException(@"Encryption key must be exactly 64 bytes long"); @throw RLMException(@"Custom schema only supported when using dynamic Realms"); @throw RLMException(@"The notification block should not be nil"); @throw RLMException(@"The Realm is already in a write transaction"); @throw RLMException(@"Invalid array type - container must be an RLMArray, RLMArray, or NSArray of RLMObjects"); @throw RLMException(@"Cannot migrate Realms that are already open."); @throw RLMException(@"Can't mutate a persisted array outside of a write transaction."); @throw RLMException(@"Object type does not match RLMResults"); @throw RLMException(@"RLMArray properties require a protocol defining the contained type - example: RLMArray<Person>"); @throw RLMException([NSString stringWithFormat:@"Migration is required for object type '%@' due to the following errors:n- %@", objectSchema.className, [exceptionMessages componentsJoinedByString:@"n- "]]);
  • 25.
    ues grepwith 'FIXME' //FIXME: make sure delete rules don't purge objects // FIXME - enable when Any supports links // FIXME - enable for ints when we have core suppport // FIXME: Add condition to check for Mixed once it can support a nil value. // FIXME: int64_t should be DateTime but that doesn't work on 32 bit // FIXME: for new apis only return swift initialized values // FIXME - remove deleted tables // FIXME: this should be supported by core in some way
  • 26.
    takea lookatCHANGELOG.md +Master Releasenotes +============================================================= + +### Enhancements + +* The browser will automatically refresh when the Realm has been modified + from another process. + 0.91.0 Release notes (2015-03-10) =============================================================
  • 27.
    takealookatIssues - LLDB hangswhen debugging an application that is using an encrypted Realm. - Support Carthage prebuilt framework - App crashes on read when using writeCopyToPath: to compact encrypted realm - Add RLMConfiguration - Support querying "%@ IN (RLMArray keypath)" - multiple realms contain all classes - Swift: Nested JSON Objects
  • 28.
    takea lookatGoogle Groups -SQL Join in Realm - HOW TO FETCH ALL CHILD NODE DATA?? - Integer to String conversion - Querying by large number of Integer values via predicate with IN clause - Realm Online Office Hours next week - Ask us anything :) - Fine grained notifications and core open sourcing - Time Frame
  • 29.
    Realm +JSONhttps://github.com/matthewcheok/Realm-JSON + (NSDictionary*)JSONInboundMappingDictionary { return @{ @"episode.title": @"title", @"episode.description": @"subtitle", @"episode.id": @"episodeID", @"episode.episode_number": @"episodeNumber", @"episode.episode_type": @"episodeType", @"episode.thumbnail_url": @"thumbnailURL", @"episode.published_at": @"publishedDate", }; }
  • 30.
  • 31.