Realm Blog

Realm Java 0.83 — with Null Support!

by /

Realm files read or written by this version cannot be opened with previous versions of Realm. Please be careful about shipping updates to your existing apps!

We just released a Realm Java update to this website, and to Maven. This release includes support for null values, one of the most-frequently requested Realm features!

Breaking Changes

With this release, fields of the types String, Date, and byte[] are now nullable by default. (In previous versions of Realm Java, no fields could have the value null.) Existing apps will have to either modify model classes or provide a migration step to explicitly support this new feature. Read on for details.

In order to be able to support null values, Realm’s underlying storage engine has changed its file format. Your Realm files will automatically be converted to new file format when you open the Realm file for the first time. The file format conversion is irreversible! It is not possible to open the new Realm file using a previous version of Realm. Furthermore, it is not possible to downgrade a Realm file to the old file format.

If you are going to upgrade existing apps, we recommend that you test carefully before shipping.

Boxed types

Realm Java supports the most common types in Java, including boolean, integer types (byte, short, int, and long), and floating-point numbers (float and double). These primitive (or unboxed) types cannot be assigned to null in Java, and thereby they have served us well. You can still use the primitive types in your model classes. As before, the primitive types indicate that the field cannot be assigned to null.

On the other hand, boxed types are common in Java, and variables and fields of boxed types can be assigned to null. We are introducing boxed types for booleans (Boolean), integers (Byte, Short, Integer, and Long), and floating-point numbers (Float and Double) to Realm Java. When you use these boxed types in your model classes, the field can be assigned to null.

Fields of the types String, Date, and byte[] can be null. Setting a RealmList field to null means that the list is cleared. No objects are removed, only the references to the objects are removed. Moreover, a RealmList field cannot be null. The getter will always return a RealmList object but the length of the list might be zero.

Let us show you a little example. The model class below has two integer fields and one string field.

class Person extends RealmObject {
    String name;
    int age;
    Integer weight; // weight is not required!
}

You can create objects, and assign values to the fields.

Person john = realm.createObject(Person.class);
john.setName("John");
john.setAge(25);
john.setWeight(73);

Person bill = realm.createObject(Person.class);
bill.setName("Bill");
bill.setAge(41);
bill.setWeight(null);

As you can see, we set all three fields for John, while we don’t know the weight of Bill and set it to null (actually, the default value for Person.weight is null so we can skip the line).

The new @Required annotation

Strings, Dates, byte[], and box typed fields can all be assigned to null. As the example above showed, sometimes a proper value (not null) is required. You can specify that a field cannot be null by using the new @Required annotation. Using this annotation, Realm will not allow you to set it to null. If you will always know the name of a person, a better model class is:

class Person extends RealmObject {
    @Required
    String name;
    int age;
    Integer weight;
}

It is possible to add the @Required annotation to boxed typed fields, and Realm will enforce that no null values are saved. The annotation is not used for the primitive types, as a field of a primitive type cannot be null. Moreover, relationships (RealmList and single Realm objects) cannot be required.

Querying

For any field which is not required, you can query with null as a value. Moreover, aggregate functions (sum, min, etc.) will not take null values into account. The Realm interpretation of null implies that every string begins with, ends with, and contains null. This means that the following query will return all objects:

RealmResults<Person> persons = realm.where(Person.class).where().beginsWith("name", null).findAll();

If you query with null as a value for required fields, an exception is thrown.

Migration

With the release supporting null, Realm’s underlying storage engine will automatically convert your Realm files. The conversion is required as the file format used by the storage engine has been changed. The conversion is done even though you don’t intend to use null values in your model classes. The automatic conversion will take time, so the very first access to a Realm file will take a bit longer. After the conversion, files will be opened just as fast as before.

You are likely to do some manual migration as well. If you have string, date or binary (byte[]) fields in your model classes, you will have to migrate them. In previous versions of Realm Java, Strings could not be null. In version 0.83.0 of Realm Java, the semantics of String has been changed. Take the following model class as an example:

class Dog {
    String name;
    int age;
}

If you have created a Realm file which includes Dog, the field name could not be assigned to null. With Realm Java 0.83.0 and later, if you which to disallow null as a value, you must change the model class to:

class Dog {
    @Required
    String name;
    int age;
}

If you don’t wish to change the model class (or wish to use null), you will have to migrate the Realm file. For that purpose, you can use the method Table.convertColumnToNullable() as part of your migration.

RealmMigration migration = new RealmMigration() {
    @Override
    public long execute(Realm realm, long version) {
        Table table = realm.getTable(Dog.class);
        table.convertColumnToNullable(table.getColumnIndex("name"));
        return 1;
    }
};

RealmConfiguration realmConfig = new RealmConfiguration.Builder(getContext())
    .schemaVersion(1)
    .schema(Dog.class)
    .migration(migration)
    .build();
Read more

Leonardo Kim joins Realm

by /

We’re happy to announce that Leonardo has joined Realm and will be helping us from Seoul, Korea.

김용욱 님이 대한민국 서울에서 렘과 함께 일하게 되었다는 사실을 알릴 수 있어 기쁩니다.

Leonardo Kim 김용욱

Leonardo YongUk Kim is a software developer with extensive experience in mobile and embedded projects, including: several WIPI modules (Korean mobile platform based on Nucleus RTOS), iOS projects, a scene graph engine for Android, an Android tablet, a client utility for black boxes, and some mini games using Cocos2d-x. He has also developed many open source projects.

Additionally, Leonardo has been an organizer of GDG Korea Android for the last several years. To date, he has organized conferences, codelabs, hackathons, and meetups.

Get in touch with Leonardo on Facebook, GitHub or email. Welcome to Realm, Leonardo!

김용욱님이 대한민국 서울에서 Realm에 합류 하였습니다.

김용욱님은 많은 모바일 프로젝트와 임베디드 프로젝트를 개발한 소프트웨어 프로그래머로 WIPI, iOS, 씬 그래프 엔진, 안드로이드 타블렛, 블랙박스, Cocos2d-x로 작성된 미니게임 등의 다양한 프로젝트에 참여했습니다.

그는 또한 GDG 코리아 안드로이드의 오거나이저로 몇년간 활동해왔습니다. 그는 몇몇 오픈소스 프로젝트를 개발하고 컨퍼런스, 코드랩, 해커톤, 밋업을 개최하였습니다.

김용욱님을 페이스북, 깃헙, 이메일를 통해 만나보세요. 용욱님 환영합니다!

Realm Community in Korea

Realm is a mobile database: a replacement for SQLite & Core Data. It’s easy to use, fast, and cross platform.

The Realm community in Korea has expanded rapidly since our public launch in July 2014. From the start, we’ve prioritized the Korean developer community; Tim Anglade, our VP of Product unveiled Realm for Android publicly while on stage at Seoul’s DEVIEW conference in September, 2014. This year, we expanded and presented at both GDG Android and DEVIEW 2015.

In Korea, we organize regular meetups in Seoul to share knowledge, host technical presentations, and help Realm users meet one another. In the future, we plan to organize a coding club, hackathons, and more. Many Korean apps are already using Realm, including: Retrica, Cymera, RidiBooks, CJmall, and Interpark. We hope your app will join this list!

Please join us on the Realm Korea Page where we share the latest news about Realm & mobile development. We also have a Realm Korea User Group on Facebook to help you solve technical problems, share case studies, presentations, tips, and more. Feel free to ask your questions in Korean there or email [email protected]. Happy hacking!

Realm 은 Android와 iOS 에서 SQLite와 Core Data를 대체해 사용하실 수 있는 모바일 데이터베이스입니다. 오픈소스로 무료로 사용하실 수 있고, 간결하고 짧은 코드로 편하게 개발할 수 있으며 속도가 빨라 더 나은 사용성의 앱을 만들 수 있습니다. 현재 Starbucks, Amazon, Ebay 등에서 모바일 앱 개발에 사용되고 있습니다.

Realm 사용자 커뮤니티는 2014년 7월에 Realm SDK 가 공개된 이후 빠르게 발전해 왔습니다. Realm은 2014 DEVIEW 컨퍼런스에서 Realm: Android와 iOS를 위한 데이터베이스 세션을 진행 하였고, Realm Android SDK는 그 세션에서 공개 되었습니다. 이는 Realm 이 한국 Android 사용자를 얼마나 중요하게 생각하고 있는지를 보여줍니다. 현재 카카오헬로, 네이버 폴라, 싸이메라, 리디북스, CJmall 를 포함한 다양한 한국 앱들이 이미 Realm을 사용하고 있습니다.

2014년에 제품을 발표한 이래 한국에서 꾸준히 Realm 개발자 모임을 진행하고 있습니다. 최근에는 8월에 네이버 D2에서 Realm 개발자 모임을 가졌습니다.

앞으로도 한국에서 정기적인 개발자모임을 가지고 기술정보를 교환하는 등 모바일 개발자들들 위한 자리를 만들 계획입니다. 또한 코딩 클럽, 해커톤, 코드랩 등의 행사도 기획하고 있습니다. 페북에서 운영중인 Realm 한국 사용자 그룹 에 기술이슈나 사용 경험, 프리젠테이션 자료, 사용 팁 등을 공유해 주시고 Realm 한국 사용자 페이지와도 방문해 주십시오. 한국어 연락처는 [email protected] 입니다. 감사합니다.

Read more

Makoto Yamazaki joins Realm

by /

We’re happy to announce that Realm’s recent agreement with uPhyca Inc. has resulted in Makoto Yamazaki, a.k.a. @zaki50, joining our team! Makoto will support Realm’s development in Japan, focusing mainly on the Android platform.


株式会社ウフィカとRealmが契約を結び、山﨑 誠(@zaki50)がRealmの活動に加わることになりました! 主にAndroidを中心に、Realm自体の開発と日本における利用を支援してまいります。

Makoto Yamazaki

As a seasoned Java and Android expert, Makoto has already developed many apps. He has also given technical presentations at several Android conferences, including Android Bazaar and Conference (ABC) and DroidKaigi.

In addition to helping us develop Realm software, Makoto will also support Japanese developers by sharing information and maintaining a helpful presence in the community.

Japanese developers have already been talking about Realm on channels such as Twitter, Facebook, Stack Overflow, and Slack, thanks to Katsumi Kishikawa, another Realm team member based in Japan. With Makoto’s help, we are confident that we will provide even better support to Japanese developers.

You can follow Makoto on Twitter and GitHub, or you can even drop him an old fashioned email.

山﨑はJavaおよびAndroidのエキスパートとして様々なアプリケーションの開発に携わってきただけでなく、Android Bazaar and Conference(ABC)DroidKaigi など各種Android関連イベントでの豊富なプレゼンテーション経験をもっています。

これらの経験をもとに、これからはRealmの開発だけでなく、日本の開発者のみなさんとRealmをつなぐ存在として積極的に情報発信と支援活動をおこなってまいります。

現在Realmでは、TwitterFacebook GroupStack Overflow日本語版Slackを日本の開発者のみなさんとのコミュニケーションのチャンネルとして活用しています。 これまでは岸川がひとりで日本の開発者のみなさんを支援してまいりましたが、山﨑が加わることでより一層充実した支援体制となることを確信しております。

TwitterGitHubで山﨑をフォローしてください。また、困ったことや要望があれば、どんなことでもお気軽にメールしてください。

Realm Community in Japan

Realm is a mobile database: a replacement for SQLite & Core Data. It’s easy to use, fast, and cross platform.

The Realm community in Japan is very active. We regularly organize meetups to share knowledge, host technical presentations, and help Realm users meet one other. Many Japanese apps are already using Realm, including AWA, Nikkei, Eight, Sync by Wantedly, and ChatWork.

Please join our Realm Japan User Group on Facebook to find help solving technical problems, as well as case studies, presentations, and tips for using Realm. We also run Realm Slack. Feel free to join us there and ask any questions you have, in Japanese or English. Happy Hacking!

RealmはSQLiteやCoreDataの代替となるべくオープンソースソフトウェアとして開発されているモバイルデータベースです。クロスプラットフォーム(現在はiOSとAndroid)で利用でき、シンプルなAPIで簡単に利用することができ、動作速度が非常に高速であることが特長です。この利点を活かして、より短期間で使い勝手の良いアプリケーションを開発することが可能になります。

すでに日本では音楽ストリーミングサービスのAWA日本経済新聞 電子版、名刺管理のEightSync by WantedlyChatWorkなど数多くのアプリケーションでRealmが使用されています。

デベロッパーコミュニティに対する活動として、毎月のRealmミートアップの開催や、各種の勉強会、ミートアップをサポートしています。

また、私たちはFacebookにユーザーグループRealm Japan User Groupを開設して、技術情報の共有、新機能のお知らせ、アプリケーションの紹介など、日本のデベロッパーの皆さんの情報交換をサポートしています。

より複雑な質問にはSlackチャットによるサポートを活用しており、迅速な問題解決に役立っています。もちろん、質問は日本語でしていただいて構いません。

We’re Hiring!

Welcome to Realm, Makoto!

If you’d like to work with Makoto and the rest of us at Realm, take a look at our jobs page, or drop Tim a line.

Read more

Realm Objective-C & Swift 0.96 Beta

by /

Realm files read or written by this version cannot be opened with previous versions of Realm. Please be careful about shipping updates to your existing apps!

We just made a special release of Realm Objective-C & Swift numbered “0.96.0-beta”. This release can be installed manually using our zip release for Objective-C or Swift, or by specifying this exact version in your Podfile or Cartfile. For the RealmSwift pod, you’ll need to use 0.96.0-beta2.

This release contains early support for null properties, keypath collection queries (count/min/max/sum/avg), a new RealmCollectionType protocol in Swift, error handling in writes, and a fistful of bug fixes!

We encourage you to try out this version in your local development environments. Although we’ve taken every precaution to test this new file format and the migration process, we’re relying on your feedback to catch any possible issues before we cut an official release.

After a period of beta-testing, these features will be made available as part of an official 0.96.0 release.

Null Support

This version adds support for null values for all property types.

Objective-C

NSString *, NSDate *, NSData * now allow nil by default. You can disallow setting a property to nil by overriding the +requiredProperties class method and including the names of the properties which you want to disallow nil for. Accessing a Realm file created with a previous version will automatically convert these properties to nullable in the file itself, unless explicitly marked not to do so in +requiredProperties.

Optional numbers can be stored using an NSNumber * property which is tagged with the type of the number. You can use NSNumber<RLMInt> *, NSNumber<RLMBool> *, NSNumber<RLMFloat> *, and NSNumber<RLMDouble> *.

@interface OptionalTypes : RLMObject
@property NSString *optionalString;
@property NSString *requiredString;
@property NSData *optionalData;
@property NSDate *optionalDate;
@property NSNumber<RLMInt> *optionalInt;
@property NSNumber<RLMBool> *optionalBool;
@property NSNumber<RLMFloat> *optionalFloat;
@property NSNumber<RLMDouble> *optionalDouble;
@end
@implementation OptionalTypes
+ (NSArray *)requiredProperties {
    return @[@"requiredString"];
}
@end

Swift

String, NSDate and NSData properties work as you’d expect them to and can either be optional or non-optional. Unfortunately, we’re unable to directly support optional numeric types (see #2147), so you have to wrap the types in RealmOptional. For example:

class OptionalTypes: Object {
    dynamic var string: String? = "B"
    dynamic var data: NSData? = "C".dataUsingEncoding(NSUTF8StringEncoding)
    dynamic var date: NSDate? = NSDate(timeIntervalSince1970: 10)
    let int = RealmOptional<Int>(1)
    let float = RealmOptional<Float>(2.2)
    let double = RealmOptional<Double>(3.3)
    let bool = RealmOptional<Bool>(true)
    let boolWithNilDefault = RealmOptional<Bool>(nil)
}

As with List properties, RealmOptional properties should always be declared with let and not be declared dynamic. The actual value of the RealmOptional is read from and written to the value property.

Automatic Conversion

Realm files opened with this version will be automatically converted to the new file format on first access, even when only accessed in a read transaction. This automatic conversion will perform the following operations:

  1. All indexes will be recreated (only applies to ints and strings).
  2. All NSString, NSDate, and NSData properties are converted to nullable, unless marked as required in +requiredProperties.
  3. The new format version number will be written to the file.

Since this writes to the file, Realm files created with a previous version of Realm won’t be able to be read with this new version. If you’re bundling a Realm file in your app, it will have to be updated to use this new file format.

Note that this format conversion is irreversible.

Keypath Collection Queries

Keypath collection queries using @count, @min, @max, @sum and @avg are now supported on RLMArray/List properties. See our handy NSPredicate Cheatsheet for more details on how to use these.

RealmCollectionType

Editor’s Note: RealmCollectionType is deprecated and has been replaced by RealmCollection. The section below is retained in its original state for posterity, but you should see here for the latest on `RealmCollection`.

Users of Realm Objective-C have had the ability to represent both RLMArray and RLMResults using their shared protocol (RLMCollection) for a long time. We’re now reflecting that protocol in Swift, while expanding what it can do.

Functionality common to both List and Results is now declared in a RealmCollectionType protocol that both types conform to. A type-erased wrapper is also provided, so Swift can store a reference to the underlying collection despite its layout being different:

class ViewController: UIViewController {
    var collection: AnyRealmCollection

    init(collection: RealmCollectionType) {
        super.init()
        self.collection = AnyRealmCollection(collection)
    }
}

Improved Error Handling

In current versions of Realm committing a write transaction on a severely space-constrained device would cause Realm to crash. Thankfully, Realm’s crash safety would prevent existing data from being corrupted, but this wasn’t exactly a solid user experience.

Now committing write transactions via commitWrite / commitWriteTransaction and write / transactionWithBlock optionally allow for handling errors when the disk is out of space.

Minor Enhancements

  • Added isEmpty property on RLMRealm/Realm to indicate if it contains any objects.

Bug Fixes

  • Fix assertion failure when inserting NSData between 8MB and 16MB in size.
  • Fix assertion failure when rolling back a migration which removed an object link or RLMArray/List property.
  • Add the path of the file being opened to file open errors.
  • Fix crashes when the first Realm opened uses a class subset and later Realms opened do not.
  • Fix inconsistent errors when Object(value: ...) is used to initialize the default value of a property of an Object subclass.
  • Throw an exception when a class subset has objects with array or object properties of a type that are not part of the class subset.

Again, we encourage you to try out this version in your local development environments. Although we’ve taken every precaution to test this new file format and the migration process, we’re relying on your feedback to catch any possible issues before we cut an official release.

Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

Realm Objective-C & Swift 0.95.1

by /

We just released version 0.95.1 of Realm Objective-C and Realm Swift.

New Technologies

Now that Xcode 7 is officially out, all the new technologies that it brings are now officially supported: Swift 2.0, iOS 9, watchOS 2 & OS X 10.11.

We’ve been testing and building for these new technologies for months now, so you should feel confident that Realm will run smoother than ever with this release.

We’ll still be supporting Swift 1.2 via the swift-1.2 branch for some time to come, but we encourage you to move to Swift 2 as soon as possible.

Bug Fixes

Along with support for new Apple technologies, we’ve included a number of bug fixes in this release:

  • We added missing KVO handling for moving and exchanging objects in RLMArray and List.
  • We fixed a crash due to race condition in RLMRealmConfiguration where the default configuration was in the process of being copied in one thread, while released in another.
  • We fixed a crash when a migration which removed an object or array property is rolled back due to an error.
  • Setting the primary key property on persisted RLMObjects / Objects via subscripting or key-value coding will cause an exception to be thrown.

Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

Groupon

by /

Groupon App Screenshots

At the time of this writing, many apps on the iOS App Store are powered by Realm. A lot of them are brand new and still relatively small, while some have already reached critical success, and others even exceeded that, earning Apple’s coveted ‘Essentials’ badge.

This week, we’re proud to recognize a very prominent app, straight from Apple’s “Essentials” collection: Groupon!

If you haven’t heard of it before, Groupon is a global service aimed at connecting users and merchants in the same area, letting users take advantage of special discounts and deals of merchants around them. Merchants can advertise their products or services as separate discounted ‘coupons’ via the Groupon app that users can simply buy directly in the app. These coupons are then saved in the user’s account, and may be redeemed for their full value from the merchant at a later date.

The model is both amazingly simple and effective. The discounted prices aren’t trivial, with certain products and services being advertised for 50% off or more. Even without buying anything from the app, it’s a great advertising channel for merchants to let users find out about them!

Of course, if you hadn’t already guessed, we’re absolutely thrilled that the Groupon apps are powered by Realm. Groupon has been an early adopter of Realm, and we couldn’t be happier that it fit their scale requirements well.

Also, while we have the chance, special recognition should also be given to Groupon for letting the Swift Language Users Group meetup periodically host events at their incredibly beautiful office in Palo Alto.

From everyone at Realm, we thank Groupon for leveraging our tech in their fantastic, worldwide service (as well as allowing the use of their offices)! We wish them the very best in their endeavors, and will continue to support them in the future!

Read more

Realm Objective-C & Swift 0.95

by /

We just released version 0.95 of Realm Objective-C and Realm Swift.

Key-Value Observing

Realm objects are now Key-Value Observing compliant for most properties. Using KVO on standalone Realm objects has always worked as normal, but on persisted objects you would only get notifications for changes made directly to the observed object, and not changes made on other threads or via other accessors for the same object. This has now been fixed, and observing properties of persisted objects will now work correctly regardless of how they’re changed. In addition, you can now observe the invalidated property of persisted objects to be notified of when the object is deleted from the Realm.

See the docs for Objective-C or Swift for more information on KVO with Realm, or check out our ReactKit or ReactiveCocoa examples showing them used with Realm.

Realm Configuration

We’ve reworked how you open and configure Realm instances. Rather than a mixture of class methods that register options for a path and overloaded initializers, all options are stored in a Realm configuration object (RLMRealmConfiguration in Objective-C and Realm.Configuration in Swift). This configuration object can be safely passed around between threads to easily create Realm instances for each thread, or can be set as the default configuration to use.

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

// Set either the path for the file or the identifer for an in-memory Realm
// By default config.path will be the Default realm path
config.path = "";
// config.inMemoryIdentifier = @"MyInMemoryRealm";

// Encryption keys, schema versions and migration blocks are now all set on the
// config object rather than registered for a path:
config.encryptionKey = GetKeyFromKeychain();
config.schemaVersion = 10;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
    // do stuff
};

// New feature: a Realm configuration can explicitly list which object classes
// should be stored in the Realm, rather than always including every `RLMObject`
// and `Object` subclass.
config.objectClasses = @[Dog.class, Person.class];

// Either use the configuration to open a Realm:
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];

// Or set the configuration used for the default Realm:
[RLMRealmConfiguration setDefaultConfiguration:config];

The following APIs have been deprecated in favor of the new RLMRealmConfiguration class in Realm Objective-C:

Deprecated API New API
+[RLMRealm realmWithPath:readOnly:error:] +[RLMRealm realmWithConfiguration:error:]
+[RLMRealm realmWithPath:encryptionKey:readOnly:error:] +[RLMRealm realmWithConfiguration:error:]
+[RLMRealm setEncryptionKey:forRealmsAtPath:] -[RLMRealmConfiguration setEncryptionKey:]
+[RLMRealm inMemoryRealmWithIdentifier:] +[RLMRealm realmWithConfiguration:error:]
+[RLMRealm defaultRealmPath] +[RLMRealmConfiguration defaultConfiguration]
+[RLMRealm setDefaultRealmPath:] +[RLMRealmConfiguration setDefaultConfiguration:]
+[RLMRealm setDefaultRealmSchemaVersion:withMigrationBlock] RLMRealmConfiguration.schemaVersion and RLMRealmConfiguration.migrationBlock
+[RLMRealm setSchemaVersion:forRealmAtPath:withMigrationBlock:] RLMRealmConfiguration.schemaVersion and RLMRealmConfiguration.migrationBlock
+[RLMRealm migrateRealmAtPath:] +[RLMRealm migrateRealm:]
+[RLMRealm migrateRealmAtPath:encryptionKey:] +[RLMRealm migrateRealm:]

The following APIs have been deprecated in favor of the new Realm.Configuration struct in Realm Swift for Swift 1.2:

Deprecated API New API
Realm.defaultPath Realm.Configuration.defaultConfiguration
Realm(path:readOnly:encryptionKey:error:) Realm(configuration:error:)
Realm(inMemoryIdentifier:) Realm(configuration:error:)
Realm.setEncryptionKey(:forPath:) Realm(configuration:error:)
setDefaultRealmSchemaVersion(schemaVersion:migrationBlock:) Realm.Configuration.schemaVersion and Realm.Configuration.migrationBlock
setSchemaVersion(schemaVersion:realmPath:migrationBlock:) Realm.Configuration.schemaVersion and Realm.Configuration.migrationBlock
migrateRealm(path:encryptionKey:) migrateRealm(configuration:)

The following APIs have been deprecated in favor of the new Realm.Configuration struct in Realm Swift for Swift 2.0:

Deprecated API New API
Realm.defaultPath Realm.Configuration.defaultConfiguration
Realm(path:readOnly:encryptionKey:) throws Realm(configuration:) throws
Realm(inMemoryIdentifier:) Realm(configuration:) throws
Realm.setEncryptionKey(:forPath:) Realm(configuration:) throws
setDefaultRealmSchemaVersion(schemaVersion:migrationBlock:) Realm.Configuration.schemaVersion and Realm.Configuration.migrationBlock
setSchemaVersion(schemaVersion:realmPath:migrationBlock:) Realm.Configuration.schemaVersion and Realm.Configuration.migrationBlock
migrateRealm(path:encryptionKey:) migrateRealm(configuration:)

The old methods will be removed entirely in a future version.

Class Subsets

The new Realm configuration API also adds the ability to specify what object classes you want to be stored in a given Realm file, rather than having it be all RLMObject and RealmSwift.Object subclasses. This is done by setting the objectClasses property to an array of the class objects you want to be persisted in the Realm.

RLMRealmConfiguration *config = [[RLMRealmConfiguration alloc] init];
config.objectClasses = @[MyClass.class, MyOtherClass.class];
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
var config = Realm.Configuration()
config.objectTypes = [MyClass.self, MyOtherClass.self]
let realm = Realm(configuration: config)

The main benefit of this is that it makes it much easier to have independent components in your application which use Realm. In previous versions, making a change to an object class would require bumping the schema version for all Realms you open, even ones which would never actually be used to store objects of that type.

Explicitly listing the classes to include also lets Realm skip scanning for RLMObject and RealmSwift.Object subclasses. This can be important for App Extensions. Iterating over all of the registered classes in a process eagerly loads all linked bundles, which in applications linking a large number of frameworks can cause problems with the App Extension memory limit.

Modifying objects while enumerating query results

Previously, Realm’s collection types matched the behavior of the Foundation collections and forbade modifying the collection while enumerating it with for..in. Unfortunately, this combined confusingly with Realm’s live-updating query results. A simple loop like for employee in realm.objects(Employee).filter("hired = false") { employee.hired = true } didn’t actually work because as soon as you set hired = true that object is removed from the Results that you’re enumerating.

To fix this, we’ve made it so that enumerating a Realm collection always enumerates the objects which are in the collection at the beginning of the enumeration. This means that you can freely add or remove items from an RLMArray/List while enumerating it, or modify the values of objects in the Realm while enumerating an RLMResults/Results. For example, you can now safely do the following and have it work as desired:

let realm = Realm()
let dogs = realm.objects(Dog)
realm.write {
  for dog in dogs {
    if dog.age > 10 {
      realm.delete(dog)
    }
    else {
      dog.age += 1
    }
  }
}

Performance Improvements

Adding objects to a Realm via the Swift API has been greatly optimized to bring it in line with the Objective-C API.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

Dubsmash

by /

Dubsmash App Screenshots

Wow. Just wow. This app. The power level of this app. This is amazing.

This week, we’re extremely thrilled to bring you a feature on Dubsmash, the social selfie app that lets you dub yourself to famous sound clips by Mobile Motion!

In case you somehow missed it on the front page of your iPhone’s App Store page, Dubsmash is an app that lets you record a video of yourself dubbing, or acting in sync to a wide range of available sound clips; mostly famous movie quotes. Once you’ve created one of these dubbed video masterpieces, Dubsmash makes it seamless to publish it anywhere on the web; on web sites, on your social feed, or even directly to friends. The app also lets you manage your previous videos, as well as submit your own dubbed sound clips for other users to use. All of this is in a very simple, clean user interface that takes mere seconds to learn.

The uptake of Dubsmash has been absolutely staggering. Within a week of its launch, it had hit the coveted #1 position of free apps on the App Store in its home region of Germany, and later went on to achieve the #1 position in over 40 other App Store regions after that! And no, that isn’t simply #1 in one of the App Store’s category filters, that’s #1 overall, beating out apps such as Facebook and YouTube!

Finally, if you hadn’t already guessed it from this post, both the iOS and Android apps for Dubsmash are taking full advantage of Realm! We’re absolutely over the moon that our technology was able to contribute to Dubsmash’s efforts, and congratulate them on the ridiculous achievements they’ve reached with both of these apps. We thank everyone at Mobile Motion for choosing to go with Realm, and wish them all the very best in their future of Dubsmash!

Read more

Chris Kurose joins Realm

by /

We’re delighted to announce that Chris Kurose has joined Realm and will be helping us in San Francisco, California!

Chris Kurose

Chris comes from a filmmaking background, and after shooting most of the past year’s SLUG meetups, is joining the marketing team to expand Realm’s video production and manage content publishing. Besides his love of all things camera-related and an eye for composition, he brings a storytelling perspective that he hopes to use to help create better and better content!

Get in touch with Chris.

Welcome to Realm, Chris!

We’re hiring!

If you’d like to work with Chris & the rest of us, take a look at our jobs page.

Read more

Cymera - Collage & Filters

by /

Cymera App Screenshots

Following on with the photography trend we started last week, our quest for this week’s App of the Week took us farther than we’ve been before; all the way to Korea! This week, the crew at Realm is very happy to put our official support behind the iOS and Android app of Cymera, the selfie social networking service by SK Communications Co., Ltd in Korea.

When Apple first announced the iPhone 4 with its front-facing camera, it’s quite possible they didn’t quite realize the magnitude of just what sort of powerful emotions they were enabling. Us humans are a passionate bunch; we love expressing ourselves and we love seeing our friends’ expressions. Because of this passion, posting pictures of yourself online (in case you’ve been living under a rock, more commonly referred to as a “selfie”) has become a very popular social networking content medium.

And it turns out that a lot of users agree. Cymera has proudly announced that they now have over one hundred and fifty million users! Holy Guacamole, Batman!

Getting started on Cymera is VERY simple. You simply download the app, make an account (Which is VERY quick thanks to Facebook and Google+ integration), and away you go! Right off the bat, you can start posting your own photos, or simply browse some the publicly joinable community galleries. There is a slide-out menu from the left that provides all of the major app navigation, and the tab buttons at the bottom make it very fast to post photos.

Speaking of which, posting photos via the Cymera app is absolutely amazing. If there’s an image manipulation feature out there, Cymera has it. Period. You can change the color grade, perform distortions via facial detection (like enhancing a smile!), add tilt shift, and if all that wasn’t enough, on top of that, you can then choose to apply stickers from an absolutely vast sticker collection; all completely free!

Cymera is an amazing service. With a simple concept, features that enable a truly ridiculous amount of personal freedom and expression, as well as an absolutely thriving userbase, it is a very impressive implementation. All of us at Realm are humbled that our technology was able to help enable and empower a service of this magnitude and we wish everyone at SK Communications the very best of luck in their endeavor!

Read more

#Photos - A simple, powerful photo manager

by /

#Photos App Screenshots

This week, we’re thrilled to feature another beautifully designed app that’s using Realm for an absolutely excellent cause.

Apple tells us time and time again that the iPhone is one of the best cameras out there. It’s a camera we constantly carry with us, and at the drop of a dime it’s very easy to quickly pull it out and snap a photo. It’s no wonder Flickr reports that more photos are uploaded to their service by iPhones than any other camera!

With all that said and done, sadly the experience of managing all these photos on an iPhone isn’t as great as it could be. Photos are simply dumped in one massive scrolling view called the “Camera Roll”. More sorting options were added in iOS 7, but it remains quite a cumbersome thing to manage, and you still have to manually navigate a large collection of photos. Sadness, and frustration.

Enter #Photos!

Elegantly designed and very thoughtfully crafted, #Photos is an app developed by beyondf that helps you manage all of the photos on your iOS device. Unlike the system Photos app, #Photos brings order to your chaotic mess by extracting the timestamp from each photo, and it breaks up the list into time blocks of your choosing (months or days), visually separating them in the list. Additionally, by simply swiping to the left, a menu appears that makes it possible to instantly jump between batches of photos taken in specific months, making it far easier to navigate your photo collection than the system Photos app. On top of that, swiping to the left reveals a menu that will let you edit your photo albums as well. Again, much faster than the standard system app.

If all that wasn’t enough, when actually viewing your images, #Photos provides an absolute plethora of features to extend what you can do with your photos. You can share them with the standard iOS share sheet, send them directly to another app, add memos or tags, or even — perhaps most importantly — directly view all of the EXIF metadata embedded in that photo, including an embedded map of where the photo was taken. The level of functionality that #Photos provides is mind-blowing.

#Photos is awesome. This is how the default Photos app should have worked from the start. Apple should be watching this and taking notes for iOS 10. All of us at Realm are incredibly happy to see our technology contribute to an app that will help people every day with one of the most common and usually frustrating tasks on the iOS platform. We wish them all the best, and we can’t wait to see the app grow from this point onwards!

Read more

Realm Objective-C & Swift 0.94

by /

We just pushed version 0.94 of Realm Objective-C and Realm Swift. Along with many bug fixes and performance enhancements, this release improves support for Xcode 7 Beta 4, watchOS, Swift 2.0, Objective-C generics, and bitcode.

We’ve also exposed the ability to swap & move objects in an RLMArray or a List.

Finally, to allow us to make more informed product decisions moving forward, this release introduces the collection of development analytics.

Read on for an overview of all the changes included in 0.94.

Performance Improvements

RLMRealm notification listener threads should now consume less memory than ever before. This is part of an ongoing effort to reduce the memory footprint of apps using Realm.

Filtering and sorting results is now done lazily, which will further reduce the overhead of chaining queries together.

Support for New Apple Features

Nullability

The Objective-C API has been fully annotated for nullability semantics to provide enhanced compiler warnings and bridging to Swift. Here’s what that looks like when using Realm Objective-C from Swift:

// Before nullability annotations
class func ignoredProperties() -> [AnyObject]!

// After nullability annotations
class func ignoredProperties() -> [AnyObject]

Generics

RLMResults and RLMArrays now support native Objective-C generics if available (Xcode 7 or later), which should help catch more type errors at compile-time.

Here’s how you can make use of these new generics:

// Define a Company model with a generic array of employees
@interface Company : RLMObject
@property RLMArray<Employee *><Employee> *employees;
@end

// Retrieve all employees and store in a generic RLMResults
RLMResults<Employee *> *allEmployees = [Employee allObjects];

Here’s what the different components of the RLMArray property definition mean and why they are useful:

  • RLMArray: The property type.
  • <Object *>: The generic specialization. This helps prevent using the array with the wrong object type at compile-time.
  • <Object>: The protocol this RLMArray conforms to. This enables Realm to know how to specialize the schema of this model at runtime.

Objective-C generics are unfortunately type-erased, which means Realm can’t determine the specialization at runtime. This is why the protocol conformance declaration is still necessary, even though it’s unsightly. We apologize for the angle-bracket blindness!

Bitcode, watchOS & Swift 2.0

iOS & watchOS builds of Realm now include bitcode. Our zip archives distributed via this website, GitHub Releases, and Carthage now include builds for all these configurations:

  • Objective-C / Swift 1.2 / Swift 2.0 Beta 4
  • Mac / iOS / watchOS

Yikes! And people say Android is fragmented!

realm-cocoa-deal-with-it

Other Enhancements

  • The exceptions thrown in getters and setters are more informative.
  • Add -[RLMArray exchangeObjectAtIndex:withObjectAtIndex:] and List.swap(_:_:) to allow exchanging the location of two objects in the given RLMArray / List.
  • Add -[RLMArray moveObjectAtIndex:toIndex:] and List.move(from:to:) to allow moving objects in the given RLMArray / List.

Bugfixes

  • Processes crashing due to an uncaught exception inside a write transaction will
  • Fix incorrect results when querying for < or <= on ints that require 64 bits to represent with a CPU that supports SSE 4.2.
  • An exception will no longer be thrown when attempting to reset the schema version or encryption key on an open Realm to the current value.
  • Date properties on 32 bit devices will retain 64 bit second precision.
  • Wrap calls to the block passed to enumerate in an autoreleasepool to reduce memory growth when migrating a large amount of objects.
  • In-memory realms no longer write to the Documents directory on iOS or Application Support on OS X.

Analytics

Realm now asynchronously submits build information to Realm if running in an iOS Simulator or on OS X if a debugger is attached. Nothing is done when running on a physical iOS / watchOS device or if a debugger is not attached.

To be clear: this does not run when your app is in production or on your end-user’s devices; it will only run in the simulator or when a debugger is attached.

For more information, see PR #2276 which introduced this change.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

BarkBuddy - Adopt a Dog Near You

by /

BarkBuddy App Screenshots

Our App of the Week this time cranks the d’awwww! factor all the way up to eleven out of ten! BarkBuddy is an app for iOS that makes it super easy to view all of the pups, pooches, mutts, and dogs of all breeds available for adoption in your area.

Whether intentionally abandoned, or simply born outside of a home, a sadly large number of dogs end up in shelters, most without any hope of seeing the outside. While many potential new owners would consider visiting a shelter to look for their new family member, in practice, making the trip in the hope of finding a match may leave a bit too much to chance for most people.

By bringing the shelters directly to prospective owners, BarkBuddy can cut out the uncertainty, and really make a difference! Using a swipe-left / swipe-right interface — which you may recognize from certain other popular apps :) — BarkBuddy presents beautiful, high-resolution photos of potential pooches currently up for adoption. You can quickly view these pictures, and then choose whether to ‘like’ or ‘pass’ on each pup. If you discover your perfect tail-wagger, you can get in touch with the shelter directly through the app. Frictionless pup adoption!

Hands down, not only is this app a fantastic, modern solution to a centuries-old problem, it also has the potential to bring a great deal of happiness to new owners and, most importantly, to the dogs. All of us at Realm are both thrilled and humbled that our technology helped the developers make an app of this calibre, and we wish them all the best!

🐶

Read more

Realm Java 0.82.0 with in-memory Realm support!

by /

We just released a Realm Java update to this website, and to Maven. This release includes new features like in-memory Realms, and updates to the @PrimaryKey and @Index annotations.

In-Memory Realms

It’s now possible to create an in-memory Realm. In-memory Realms are useful when you want the benefits of Realm objects (schema, queries, threading model, etc.) without persistence, but a bit of extra performance. They’re great for temporary caching, per-session details, and so on.

Just set this option when building a RealmConfiguration

// In-Memory RealmConfiguration
RealmConfiguration config = new RealmConfiguration.Builder(context)
        .name("myrealm.realm")
        .inMemory()
        .build();

Realm realm = Realm.getInstance(config);

The RealmQuery.between() predicate has been removed for link queries. You can still use the predicate for ordinary queries. Realm’s underlaying storage engine does not support the predicate for link queries, and Realm for Android implemented the predicate using two predicates. In some use cases, the results can be counter-intuitive. Likewise, Realm for Swift & Objective-C does not support the predicate for link queries, and for consistency we have decided to remove it.

Other improvements

In addition, @Index annotation can also be applied to byte/short/int/long/boolean/Date. As a consequence of this, @PrimaryKey will now be indexed automatically, which should improve queries performance.

Breaking changes

Since all primary keys are now automatically indexed, your old primary keys of type short and int will need to be migrated to be indexed fields. To do this, you will have to use the Table.addSearchIndex(long columnIndex) method in your migration class.

Here is an example:

RealmConfiguration.Builder(context)
   .schemaVersion(2) // Bump schema version
   .migration(new RealmMigration() {
      @Override
      public long execute(Realm realm, long version);
         if (version == 1) {
            Table table = realm.getTable(Foo.class);
            long keyIndex = table.getColumnIndex("id");
            table.addSearchIndex(keyIndex);
            version++;
         }
         return version;
      }
   })
   .build();

See the full changelog for full details.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, and Twitter.

Read more

The Beginning of a Love Story with Realm 💘

by /

Today’s blog post is by Genady Okrain, a developer in Israel addicted to making shiny apps, and is originally published on his blog. You can find Genady on GitHub and Twitter.

If you’d like to share your story about Realm, please email Tim!


Last week I was working on a new networking module that gets data using Rest API, the response is a JSON which represents a list of cities and each city has list of landmarks.

I wanted the data to be persistent (as cache) and have some kind of object representation. When I started to think about that problem I had few options to choose from. For the networking part I could go with the native NSURLSession or Alamofire - both are good options but the idea was to write less code, and Alamofire is built exactly for that mission with Rest API and JSONs. For the persistent database I had more options: Core Data, NSUserDefaults, Parse, FMDB and Realm - here again the idea was to write less code, try something new and built for Swift. I thought Realm will be easier to setup and wanted to see what is all the buzz around.

Eventually, I decided to use the two most used open source Swift frameworks and test them out.


Alamofire

It was pretty straight forward, added pod 'Alamofire' to my Podfile and sent that request:

Alamofire.request(.GET, url).responseJSON { _, _, JSON, _ in
...
}

 

The response is a list of cities with list of landmarks, I will use it for this example:

[
    {
        "name": "San Francisco",
        "landmarks": [
            {
                "name": "Golden Gate Bridge"
            },
            {
                "name": "Fisherman's Wharf"
            }
        ]
    }
]

More info: https://github.com/Alamofire/Alamofire


Realm

All you need to do to start using Realm in your project is add pod 'RealmSwift' to your Podfile, after that your objects look like that:

class City: Object {
    dynamic var name = ""
    dynamic var landmarks = List<Landmark>()
}

class Landmark: Object {
    dynamic var name = ""
}

 

Write example:

let city = City()
...
let realm = Realm()
realm.write {
  realm.add(city)
}

 

Read example:

let cities = Realm().objects(City)

More info: https://realm.io/docs/swift/latest/


Problem 1: List properties aren’t accessible from Objective-C

One to many relationship is probably something you are going to use, and probably you have at least one Objective-C file in your project too. Currently there is bug in Xcode that generates wrong bridging file that won’t even compile:

If you’re planning on using Realm Swift from Objective-C, you’ll have to make your List properties private or internal. This is due to a known Swift bug which causes the automatically-generated Objective-C header (-Swift.h) to be unable to compile. See GitHub issue #1925 for more details and suggested workarounds.

Solution

The workaround here is to make the List property to be private and expose it to the outside world with a function:

private let landmarks = List<Landmark>()
func _landmarks() -> List<Landmark> {
    return landmarks
}

More info: https://realm.io/docs/swift/latest/#current-limitations


Problem 2: Rest API to Realm objects mapping

This example is pretty basic but the real data is way complicated, I was trying to avoid writing this ugly block of code to parse the response:

if let cities = JSON as? [[String: NSObject]] {
    for city in cities {
        let city = City()
        city.name = city["name"] as! String
        ...
    }
}

 

Solution

The good news is that it is possible to use auto mapping, each key that matched to the Realm object will be mapped automatically:

let cities = JSON as! [[String: NSObject]]
let realm = Realm()
realm.write {
    for city in cities {
        realm.create(City.self, value: city)
    }
}

More info: https://realm.io/docs/swift/latest/#example


Problem 3: Support for null string

Turns out that null is a valid JSON value and with the automatic mapping of the previous section I found out that with the release version of Realm it is not possible to use String? as type:

Solution

Realm are working on adding that support and it is already possible to use beta version to solve it.

First, Switch to the ‘null-string-beta-2’ tag and add Realm pod to your Podfile too:

pod 'Realm', :git => 'https://github.com/realm/realm-cocoa', :tag => 'null-string-beta-2'

pod 'RealmSwift', :git => 'https://github.com/realm/realm-cocoa', :tag => 'null-string-beta-2'

Second, replace all the nullable String types to NSString?:

dynamic var name: NSString?

More info: https://github.com/realm/realm-cocoa/issues/628#issuecomment-106952727


The original post can be found on Genady’s blog, Unwrapped Swift. Thanks Genady!

Read more