If you’re looking to use Realm from Objective‑C, or from mixed Objective‑C & Swift apps please see Realm Objective‑C instead. The Realm Objective‑C and Realm Swift APIs are not interoperable and using them together is not supported.

Realm Swift enables you to efficiently write your app’s model layer in a safe, persisted and fast way. Here’s what it looks like:

// Define your models like regular Swift classesclassDog:Object{dynamicvarname=""dynamicvarage=0}classPerson:Object{dynamicvarname=""dynamicvarpicture:NSData?=nil// optionals supportedletdogs=List<Dog>()}// Use them like regular Swift objectsletmyDog=Dog()myDog.name="Rex"myDog.age=1print("name of dog: \(myDog.name)")// Get the default Realmletrealm=try!Realm()// Query Realm for all dogs less than 2 years oldletpuppies=realm.objects(Dog).filter("age < 2")puppies.count// => 0 because no dogs have been added to the Realm yet// Persist your data easilytry!realm.write{realm.add(myDog)}// Queries are updated in realtimepuppies.count// => 1// Query and update from any threaddispatch_async(dispatch_queue_create("background",nil)){letrealm=try!Realm()lettheDog=realm.objects(Dog).filter("age == 1").firsttry!realm.write{theDog!.age=3}}

If you have an app that is presently using Core Data and have been considering switching to Realm, we recently published an article discussing how to go about doing this. Go check it out!

Getting Started

Prerequisites

Apps using Realm can target: iOS 8 or later, OS X 10.9 or later & WatchKit. (iOS 7 cannot be supported because it does not allow using 3rd party dynamic frameworks, and it is impossible to build static libraries that contain Swift code.)

Xcode 7.0 or later required.

Swift 2.x is supported.

Support for Xcode 6.x and Swift older than 2.2 is deprecated and will be removed entirely in our next release.

Installation (Older Swift versions)

Run git checkout v0.101.0 in the cloned repository to check out the release tag.

Run REALM_SWIFT_VERSION=2.0 sh build.sh build in the cloned repository to build the frameworks.

Make sure that you remove the existing binaries of RealmSwift.framework and Realm.framework from your project.

Go to your Xcode project’s “General” settings. Drag the versions of RealmSwift.framework and Realm.framework from build/ios/swift-2.0/ or build/osx/swift-2.0/ directory to the “Embedded Binaries” section. Make sure Copy items if needed is selected and click Finish.

In your Podfile, add use_frameworks! and pod 'RealmSwift' to your main and test targets.

From the command line, run pod install.

Use the .xcworkspace file generated by CocoaPods to work on your project!

tvOS

Because writing to the Documents directory is prohibited on tvOS, the default Realm location is set to NSCachesDirectory. However, please be mindful that tvOS can purge files in the Caches directory at any point, so we encourage you to rely on Realm as a rebuildable cache rather than storing important user data.

You can also bundle prebuilt Realm files in your app. However, be sure to comply with App Store guidelines, keeping your app under 200MB.

Please browse our tvOS examples for sample tvOS apps demonstrating how to use Realm as either an offline cache or with preloaded data.

Xcode Plugin

Our Xcode plugin makes it easy to generate new Realm models.

The easiest way to install the Realm Xcode plugin is through Alcatraz under the name “RealmPlugin”. You can also install the plugin manually by opening plugin/RealmPlugin.xcodeproj contained in the release zip and clicking build. You will need to quit and relaunch Xcode to see our plugin. If you use the Xcode menu to create a new file (File > New > File… — or ⌘N) you should see a new option to create a new Realm model.

API Reference

Examples

You can find example applications for both iOS and OS X in our release zip under examples/, demonstrating how to use many features of Realm like migrations, how to use it with UITableViewControllers, encryption, command-line tools and much more.

If you’re using a crash reporter (like Crashlytics or HockeyApp), make sure to enable log collection. Realm logs metadata information (but no user data) when throwing exceptions and in irrecoverable situations, and these messages can help debug when things go wrong.

Models

Realm data models are defined using regular Swift classes with properties. Simply subclass Object or an existing model class to create your Realm data model objects. Realm model objects mostly function like any other Swift objects - you can add your own methods and protocols to them and use them like you would any other object. The main restriction is that you can only use an object on the thread which it was created.

If you have installed our Xcode Plugin there will be a nice template to create the Swift file in the “New File…” dialog.

Relationships and nested data structures are modeled simply by including properties of the target type or Lists for typed lists of objects.

Since Realm parses all models defined in your code at launch, they must all be valid, even if they are never used.

When using Realm from Swift, the Swift.reflect(_:) function is used to determine information about your models, which requires that calling init() succeed. This means that all non-optional properties must have a default value.

Supported Types

CGFloat properties are discouraged, as the type is not platform independent.

String, NSDate and NSData properties can be optional. Object properties must be optional. Storing optional numbers is done using RealmOptional.

Relationships

Objects can be linked to each other by using Object and List properties. Lists have an interface very similar to Array and objects contained in a List can be accessed using indexed subscripting. Unlike Arrays, Lists only hold Objects of a single subclass type. For more details see List.

To-One Relationships

For many-to-one or one-to-one relationships, simply declare a property with the type of your Object subclass:

classDog:Object{// ... other property declarationsdynamicvarowner:Person?// to-one relationships must be optional}

You can use this property like you would any other:

letjim=Person()letrex=Dog()rex.owner=jim

When using Object properties, you can access nested properties using normal property syntax. For example rex.owner?.address.country will traverse the object graph and automatically fetch each object from Realm as needed.

To-Many Relationships

You can define a to-many relationship using List properties. Lists contain other Objects of a single type and have an interface very similar to a mutable Array.

To add a “dogs” property on our Person model that links to multiple dogs, we can declare a property of type List<Dog>:

Inverse Relationships

Links are unidirectional. So if a to-many property Person.dogs links to a Dog instance and a to-one property Dog.owner links to Person, these links are independent from one another. Appending a Dog to a Person instance’s dogs property doesn’t automatically set the dog’s owner property to this Person. Because manually synchronizing pairs of relationships is error prone, complex and duplicates information, Realm provides linking objects properties to represent these inverse relationships.

With linking objects properties, you can obtain all objects that link to a given object from a specific property. For example, a Dog object can have a property named owners that contains all of the Person objects that have this exact Dog object in their dogs property. This is done by making the owners property of the target type LinkingObjects and then specifying the relationship that it has with the Person object.

Optional Properties

String, NSDate, and NSData properties can be declared as optional or non-optional using the standard Swift syntax. Optional numeric types are declared using RealmOptional:

classPerson:Object{// Optional string property, defaulting to nildynamicvarname:String?=nil// Optional int property, defaulting to nil// RealmOptional properties should always be declared with `let`,// as assigning to them directly will not work as desiredletage=RealmOptional<Int>()}letrealm=try!Realm()try!realm.write(){varperson=realm.create(Person.self,value:["Jane",27])// Reading from or modifying a `RealmOptional` is done via the `value` propertyperson.age.value=28}

Property Attributes

Realm model properties need the dynamic var attribute in order for these properties to become accessors for the underlying database data.

There are two exceptions to this: List and RealmOptional properties cannot be declared as dynamic because generic properties cannot be represented in the Objective‑C runtime, which is used for dynamic dispatch of dynamic properties, and should always be declared with let.

Indexing a property will greatly speed up queries where the property is compared for equality (i.e. the = and IN operators), at the cost of slower insertions.

Auto-Updating Objects

Object instances are live, auto-updating views into the underlying data, which means objects never have to be refreshed. Modifying the properties of an object will immediately reflect in any other instances referring to the same object.

This aspect of Object not only keeps Realm fast and efficient, it allows your code to be simpler and more reactive. For example, if your UI code is dependent on a specifc Realm object, you don’t need to worry about refreshing or re-fetching it before triggering a UI redraw.

You can subscribe to Realm notifications to know when Realm data in an object is updated, indicating when your app’s UI should be refreshed. Alternatively, you can use key-value observation to be notified when a specific property of an Object is updated.

Primary Keys

Override Object.primaryKey() to set the model’s primary key. Declaring a primary key allows objects to be looked up and updated efficiently and enforces uniqueness for each value. Once an object with a primary key is added to a Realm, the primary key cannot be changed.

Ignored Properties

Override Object.ignoredProperties() to prevent Realm from persisting model properties. Realm won’t interfere with the regular operation of these properties: they’ll be backed by ivars and you can freely override their setters and getters.

Model Inheritance

Realm allows models to be further subclassed, allowing for much code reuse across models, but some Cocoa features that contribute to the runtime’s rich class polymorphism aren’t available. Here’s what’s possible:

Class methods, instance methods and properties on parent classes are inherited in their child classes.

Methods and functions that take parent classes as arguments can operate on subclasses.

RealmCollectionType, a protocol defining the common interface to which all Realm Collections conform.

AnyRealmCollection, a type-erased class that can forward calls to a concrete Realm Collection like a Results, List or LinkingObjects.

Realm collections conform to the RealmCollectionType protocol, which ensures they behave consistently. This protocol inherits from CollectionType so that it may be used as other standard library collections. Additional common Realm Collection APIs are declared in this protocol, such as querying, sorting and aggregate operations, among others. Lists have additional mutation operations that extend beyond the protocol interface such as adding and deleting objects.

Using the RealmCollectionType protocol, you can write generic code that can operate on any Realm collection:

funcoperateOn<C:RealmCollectionType>(collection:C){// Collection could be either Results or Listprint("operating on collection containing \(collection.count) objects")}

Because protocols with associated types in Swift aren’t concrete, it’s necessary to use a type-erased wrapper such as AnyRealmCollection in order to store this collection as a property or variable:

Writes

All changes to an object (addition, modification and deletion) must be done within a write transaction.

Realm objects can be instantiated and used as ‘standalone’ objects (i.e. not stored in a Realm) just like regular Swift objects. To share objects between threads or re-use them between app launches you must persist them to a Realm, an operation which must be done within a write transaction.

Since write transactions incur non-negligible overhead, you should architect your code to minimize the number of write transactions.

Because write transactions could potentially fail like any other disk IO operations, both Realm.write() & Realm.commitWrite() are marked as throws so you can handle and recover from failures like running out of disk space. There are no other recoverable errors. For brevity, our code samples don’t handle these errors but you certainly should in your production applications.

Creating Objects

When you have defined a model you can instantiate your Object subclass and add the new instance to the Realm. Consider this simple model:

classDog:Object{dynamicvarname=""dynamicvarage=0}

We can create new objects in several ways:

// (1) Create a Dog object and then set its propertiesvarmyDog=Dog()myDog.name="Rex"myDog.age=10// (2) Create a Dog object from a dictionaryletmyOtherDog=Dog(value:["name":"Pluto","age":3])// (3) Create a Dog object from an arrayletmyThirdDog=Dog(value:["Fido",5])

The most obvious is to use the designated initializer to create an object.

Objects can also be created from dictionaries using appropriate keys and values.

Finally, Object subclasses can be instantiated using arrays. The values in the array have to be in the same order as the corresponding properties in the model.

Nested Objects

If an object has properties that are Objects or Lists, these can be set recursively using nested arrays and/or dictionaries. You simply replace each object with a dictionary or array representing its properties:

// Instead of using already existing dogs...letaPerson=Person(value:["Jane",30,[aDog,anotherDog]])// ...we can create them inlineletanotherPerson=Person(value:["Jane",30,[["Buster",5],["Buddy",6]]])

This will work for any combination of nested arrays and dictionaries. Note that a List may only contain Objects, not basic types such as String.

Adding Objects

You can add an object to a Realm like so:

// Create a Person objectletauthor=Person()author.name="David Foster Wallace"// Get the default Realmletrealm=try!Realm()// You only need to do this once (per thread)// Add to the Realm inside a transactiontry!realm.write{realm.add(author)}

After you have added the object to the Realm you can continue using it, and all changes you make to it will be persisted (and must be made within a write transaction). Any changes are made available to other threads that use the same Realm when the write transaction is committed.

Please note that writes block each other, and will block the thread they are made on if multiple writes are in progress. This is similar to other persistence solutions and we recommend that you use the usual best-practices for this situation, namely offloading your writes to a separate thread.

Thanks to Realm’s MVCC architecture, reads are not blocked while a write transaction is open. Unless you need to make simultaneous writes from many threads at once, you should favor larger write transactions that do more work over many fine-grained write transactions. When you commit a write transaction to a Realm, all other instances of that Realm will be notified, and be updated automatically.

Updating Objects

Realm provides a few ways to update objects, all of which offer different tradeoffs depending on the situation. Choose which one is best for your situation:

Typed Updates

You can update any object by setting its properties within a write transaction.

// Update an object with a transactiontry!realm.write{author.name="Thomas Pynchon"}

Creating and Updating Objects With Primary Keys

If your model class includes a primary key, you can have Realm intelligently update or add objects based off of their primary key values using Realm().add(_:update:).

// Creating a book with the same primary key as a previously saved bookletcheeseBook=Book()cheeseBook.title="Cheese recipes"cheeseBook.price=9000cheeseBook.id=1// Updating book with id = 1try!realm.write{realm.add(cheeseBook,update:true)}

If a Book object with a primary key value of ‘1’ already existed in the database, then that object would simply be updated. If it did not exist, then a completely new Book object would be created and added to the database.

You can also partially update objects with primary keys by passing just a subset of the values you wish to update, along with the primary key:

// Assuming a "Book" with a primary key of `1` already exists.try!realm.write{realm.create(Book.self,value:["id":1,"price":9000.0],update:true)// the book's `title` property will remain unchanged.}

You may not pass update: true for object types which don’t define a primary key.

Please note that when updating objects, nil is still considered a valid value for optional properties. If you supply a dictionary with nil property values, then these will be applied to your object and those properties will be emptied. To ensure you don’t experience any unplanned data loss, please make sure to provide only the properties you wish to update when using this method.

Key-Value Coding

Object, Result, and List all conform to key-value coding (KVC). This can be useful when you need to determine which property to update at runtime.

Applying KVC to a collection is a great way to update objects in bulk without the overhead of iterating over a collection while creating accessors for every item.

letpersons=realm.objects(Person)try!realm.write{persons.first?.setValue(true,forKeyPath:"isFirst")// set each person's planet property to "Earth"persons.setValue("Earth",forKeyPath:"planet")}

Deleting Objects

Pass the object to be deleted to the Realm().delete(_:) method within a write transaction.

// let cheeseBook = ... Book stored in Realm// Delete an object with a transactiontry!realm.write{realm.delete(cheeseBook)}

You can also delete all objects stored in a Realm. Note the Realm file will maintain its size on disk to efficiently reuse that space for future objects.

// Delete all objects from the realmtry!realm.write{realm.deleteAll()}

Queries

Queries return a Results instance, which contains a collection of Objects. Results have an interface very similar to Array and objects contained in a Results can be accessed using indexed subscripting. Unlike Arrays, Results only hold Objects of a single subclass type.

All queries (including queries and property access) are lazy in Realm. Data is only read when the properties are accessed.

Results to a query are not copies of your data: modifying the results of a query (within a write transaction) will modify the data on disk directly. Similarly, you can traverse your graph of relationships directly from the Objects contained in a Results.

Execution of a query is deferred until the results are used. This means that chaining several temporary Results to sort and filter your data does not perform extra work processing the intermediate state.

Once the query has been executed, or a notification block has been added, the Results is kept up to date with changes made in the Realm, with the query execution performed on a background thread when possible.

The most basic method for retrieving objects from a Realm is Realm().objects(_:), which returns a Results of all Object instances of the subclass type being queried the default Realm.

letdogs=realm.objects(Dog)// retrieves all Dogs from the default Realm

Filtering

If you’re familiar with NSPredicate, then you already know how to query in Realm. Objects, Realm, List, and Results all provide methods that allow you to query for specific Object instances by simply passing in an NSPredicate instance, predicate string, or predicate format string just as you would when querying an NSArray.

For example, the following would extend our earlier example by calling Results().filter(_:...) to retrieve all dogs with the color tan and names beginning with ‘B’ from the default Realm:

// Query using a predicate stringvartanDogs=realm.objects(Dog).filter("color = 'tan' AND name BEGINSWITH 'B'")// Query using an NSPredicateletpredicate=NSPredicate(format:"color = %@ AND name BEGINSWITH %@","tan","B")tanDogs=realm.objects(Dog).filter(predicate)

The comparison operators == and != are supported for boolean properties.

For String and NSData properties, we support the ==, !=, BEGINSWITH, CONTAINS, and ENDSWITH operators, such as name CONTAINS ‘Ja’

Case insensitive comparisons for strings, such as name CONTAINS[c] ‘Ja’. Note that only characters “A-Z” and “a-z” will be ignored for case.

Realm supports the following compound operators: “AND”, “OR”, and “NOT”. Such as name BEGINSWITH ‘J’ AND age >= 32

The containment operand IN such as name IN {‘Lisa’, ‘Spike’, ‘Hachi’}

Nil comparisons ==, !=, e.g. Results<Company>().filter("ceo == nil"). Note that Realm treats nil as a special value rather than the absence of a value, so unlike with SQL nil equals itself.

ANY comparisons, such as ANY student.age < 21

The aggregate expressions @count, @min, @max, @sum and @avg are supported on List and Results properties, e.g. realm.objects(Company).filter("[email protected] > 5") to find all companies with more than five employees.

Subqueries are supported with the following limitations:

@count is the only operator that may be applied to the SUBQUERY expression.

Sorting

Results allows you to specify a sort criteria and order based on a single or multiple properties. For example, the following calls sorts the returned dogs from the example above alphabetically by name:

Note that the order of Results is only guaranteed to stay consistent when the query is sorted. For performance reasons, insertion order is not guaranteed to be preserved. If you need to maintain order of insertion, some solutions are proposed here.

Chaining

One unique property of Realm’s query engine is the ability to chain queries with very little transactional overhead when compared to traditional databases that require a separate trip to the database server for each successive query.

For example, if we wanted a result set for just the tan colored dogs, and the tan colored dogs whose names also started with ‘B’, you might chain two queries like this:

Auto-Updating Results

Results instances are live, auto-updating views into the underlying data, which means results never have to be re-fetched. They always reflect the current state of the Realm on the current thread, including during write transactions on the current thread. The one exception to this is when using for...in enumeration, which will always enumerate over the objects which matched the query when the enumeration is begun, even if some of them are deleted or modified to be excluded by the filter during the enumeration.

This property of Results not only keeps Realm fast and efficient, it allows your code to be simpler and more reactive. For example, if your view controller relies on the results of a query, you can store the Results in a property and access it without having to make sure to refresh its data prior to each access.

You can subscribe to Realm notifications to know when Realm data is updated, indicating when your app’s UI should be refreshed for example, without having to re-fetch your Results.

Since results are auto-updating, it’s important to not rely on indices & counts staying constant. The only time a Results is frozen is when fast-enumerating over it, which makes it possible to mutate the objects matching a query while enumerating over it:

Limiting Results

Most other database technologies provide the ability to ‘paginate’ results from queries (such as the ‘LIMIT’ keyword in SQLite). This is often done out of necessity to avoid reading too much from disk, or pulling too many results into memory at once.

Since queries in Realm are lazy, performing this sort of paginating behavior isn’t necessary at all, as Realm will only load objects from the results of the query once they are explicitly accessed.

If for UI-related or other implementation reasons you require a specific subset of objects from a query, it’s as simple as taking the Results object, and reading out only the objects you need.

// Loop through the first 5 Dog objects// restricting the number of objects read from diskletdogs=try!Realm().objects(Dog)foriin0..<5{letdog=dogs[i]// ...}

Realms

The Default Realm

You may have noticed so far that we have initialized access to our realm variable by calling Realm(). That method returns a Realm object that maps to a file called “default.realm” under the Documents folder (iOS) or Application Support folder (OS X) of your app.

Realm Configuration

Configuring things like where your Realm files are stored is done through Realm.Configuration. The configuration can either be passed to Realm(configuration: config) each time you need a Realm instance, or you can set the configuration to use for the default Realm with Realm.Configuration.defaultConfiguration = config.

For example, suppose you have an application where users have to log in to your web backend, and you want to support quickly switching between accounts. You could give each account its own Realm file that will be used as the default Realm by doing the following:

funcsetDefaultRealmForUser(username:String){varconfig=Realm.Configuration()// Use the default directory, but replace the filename with the usernameconfig.fileURL=config.fileURL!.URLByDeletingLastPathComponent?.URLByAppendingPathComponent("\(username).realm")// Set this as the configuration used for the default RealmRealm.Configuration.defaultConfiguration=config}

Other Realms

It’s sometimes useful to have multiple Realms persisted at different locations. For example, you may want to bundle some data with your application in a Realm file, in addition to your main Realm. You can do this with the following code:

letconfig=Realm.Configuration(// Get the URL to the bundled filefileURL:NSBundle.mainBundle().URLForResource("MyBundledData",withExtension:"realm"),// Open the file in read-only mode as application bundles are not writeablereadOnly:true)// Open the Realm with the configurationletrealm=try!Realm(configuration:config)// Read some data from the bundled Realmletresults=realm.objects(Dog).filter("age > 5")

Please note that if a custom URL is used to initialize a Realm, it must be in a location with write permissions. The most common location to store writable Realm files is the “Documents” directory on iOS and the “Application Support” directory on OS X. Please respect Apple’s iOS Data Storage Guidelines, which recommend that documents that can be regenerated be stored in the <Application_Home>/Library/Caches directory.

In-Memory Realms

Normally Realms are persisted to disk, but you can also create ones which operate purely in memory by setting the inMemoryIdentifier rather than the fileURL on your Realm.Configuration.

In-memory Realms do not save data across app launches, but all other features of Realm will work as expected, including querying, relationships and thread-safety. This is a useful option if you need flexible data access without the overhead of disk persistence.

In-memory Realms create several files in a temporary directory for coordinating things like cross-process notifications. No data is actually written to the files unless the operating system needs to swap to disk due to memory pressure.

Notice: When all in-memory Realm instances with a particular identifier go out of scope with no references, all data is freed for that Realm. It is recommended that you hold onto a strong reference to any created in-memory Realms for the duration of your app.

Error Handling

Like any disk IO operation, creating a Realm instance could sometimes fail if resources are constrained. In practice, this can only happen the first time a Realm instance is created on a given thread. Subsequent accesses to a Realm from the same thread will reuse a cached instance and will always succeed.

To handle errors when first accessing a Realm on a given thread, use Swift’s built-in error handling mechanism:

do{letrealm=tryRealm()}catchleterrorasNSError{// handle error}

Copying Objects Between Realms

Copying Realm objects to other Realms is as simple as passing in the original object to Realm().create(_:value:update:). For example, realm.create(MyObjectSubclass.self, value: originalObjectInstance). Remember that Realm objects can only be accessed from the thread on which they were first created, so this copy will only work for Realms on the same thread.

Finding a Realm File

If you need help finding your app’s Realm file, check this StackOverflow answer for detailed instructions.

Auxiliary Realm Files

Alongside the standard .realm files, Realm also generates and maintains additional files for its own internal operations.

.realm.lock - A lock file for resource locks.

.realm.log_a, .realm.log_b - Log files for transaction logs.

.realm.note - A named pipe for notifications.

These files don’t have any effect on .realm database files, and won’t cause any erroneous behavior if their parent database file is deleted or replaced.

When reporting Realm issues, please be sure to include these auxiliary files along with your main .realm file as they contain useful information for debugging purposes.

Bundling a Realm with an App

It’s common to seed an app with initial data, making it available to your users immediately on first launch. Here’s how to do this:

First, populate the realm. You should use the same data model as your final, shipping app to create a realm and populate it with the data you wish to bundle with your app. Since realm files are cross-platform, you can use an OS X app (see our JSONImport example) or your iOS app running in the simulator.

In the code where you’re generating this realm file, you should finish by making a compacted copy of the file (see Realm().writeCopyToPath(_:encryptionKey:)). This will reduce the Realm’s file size, making your final app lighter to download for your users.

Drag the new compacted copy of your realm file to your final app’s Xcode Project Navigator.

If the bundled Realm contains fixed data that you don’t need to modify, you can open it directly from the bundle path by setting readOnly = true on the Realm.Configuration object. Otherwise, if it’s initial data that you’ll be modifying, you can copy the bundled file to your application’s Documents directory using NSFileManager.defaultManager().copyItemAtPath(_:toPath:).

Class Subsets

In some scenarios you may wish to limit which classes can be stored in a specific Realm. For example, if you have two teams working on different components of your application which both use Realm internally, you may not want to have to coordinate migrations between them. You can do this by setting the objectTypes property of your Realm.Configuration:

Deleting Realm Files

In some cases, such as clearing caches, or resetting your entire dataset, it may be appropriate to completely delete a Realm file from disk.

Unlike most files, Realm files are memory-mapped and Realm instances expect the files to be available for the duration of the instance’s lifetime.

So while most files can be deleted by calling NSFileManager’s removeItemAtPath method you must take additional steps to ensure there are no active references to any Realm objects accessing the database file at the time of deletion.

Realm instances hold a database connection for the exact duration of their lifetime. One way to limit a Realm instance’s lifetime is to wrap its usage in an autorelease pool.

So all Realm instances with their fileURL set to the Realm file you want to delete must be released before the deletion is performed.

Finally, although not strictly necessary, you should delete auxiliary realm files as well as the main Realm file to fully clean up all related files.

Using Realm with Background App Refresh

On iOS 8 and above, files inside apps are automatically encrypted using NSFileProtection whenever the device is locked. If your app attempts to do any work involving Realm while the device is locked and the NSFileProtection attributes of your Realm files are set to encrypt them (which is the case by default), an open() failed: Operation not permitted exception will be thrown.

In order to handle this, it is necessary to ensure that the file protection attributes applied to both the Realm file itself and its auxiliary files is downgraded to a less strict one that allows file access even when the device is locked, such as NSFileProtectionCompleteUntilFirstUserAuthentication.

If you are to opt out of complete iOS file encryption in this way, we encourage you to use Realm’s own built-in encryption to ensure your data is still properly secured.

Since the auxiliary files can sometimes be lazily created and deleted mid-operation, we recommended that you apply the file protection attributes to the parent folder containing these Realm files. This will ensure the attribute is properly applied to all of the relevant Realm files, regardless of their creation time.

Threading

Within individual threads you can just treat everything as regular objects without worrying about concurrency or multithreading. There is no need for any locks or resource coordination to access them (even if they are simultaneously being modified on other threads) and it is only modifying operations that have to be wrapped in write transactions.

Realm makes concurrent usage easy by ensuring that each thread always has a consistent view of the Realm. You can have any number of threads working on the same Realms in parallel, and since they all have their own snapshots, they will never cause each other to see inconsistent state.

The only thing you have to be aware of is that you cannot have multiple threads sharing the same instances of Realm objects. If multiple threads need to access the same objects they will each need to get their own instances (otherwise changes happening on one thread could cause other threads to see incomplete or inconsistent data).

Seeing Changes From Other Threads

On the main UI thread (or any thread with a runloop) objects will automatically update with changes from other threads between each iteration of the runloop. At any other time you will be working on the snapshot, so individual methods always see a consistent view and never have to worry about what happens on other threads.

When you initially open a Realm on a thread, its state will be based off the most recent successful write commit, and it will remain on that version until refreshed. Realms are automatically refreshed at the start of every runloop iteration, unless Realm’s autorefresh property is set to NO. If a thread has no runloop (which is generally the case in a background thread), then Realm.refresh() must be called manually in order to advance the transaction to the most recent state.

Realms are also refreshed when write transactions are committed (Realm.commitWrite()).

Failing to refresh Realms on a regular basis could lead to some transaction versions becoming “pinned”, preventing Realm from reusing the disk space used by that version, leading to larger file sizes. Refer to our Current Limitations for more details on this effect.

Passing Instances Across Threads

Standalone (unpersisted) instances of Objects behave exactly as regular NSObject subclasses, and are safe to pass across threads.

Persisted instances of Realm, Object, Results, or List can only be used on the thread on which they were created, otherwise an exception is thrown*. This is one way Realm enforces transaction version isolation. Otherwise, it would be impossible to determine what should be done when an object is passed between threads at different transaction versions, with a potentially extensive relationship graph.

Instead, there are several ways to represent instances in ways that can be safely passed between threads. For example, an object with a primary key can be represented by its primary key’s value; or a Results can be represented by its NSPredicate or query string; or a Realm can be represented by its Realm.Configuration. The target thread can then re-fetch the Realm, Object, Results, or List using its thread-safe representation. Keep in mind that re-fetching will retrieve an instance at the version of the target thread, which may differ from the originating thread.

* Some properties and methods on these types can be accessed from any thread:

Using a Realm Across Threads

To access the same Realm file from different threads, you must initialize a new Realm to get a different instance for every thread of your app. As long as you specify the same configuration, all Realm instances will map to the same file on disk.

Sharing Realm instances across threads is not supported. Realm instances accessing the same realm file must also all use the same Realm.Configuration.

Realm can be very efficient when writing large amounts of data by batching together multiple writes within a single transaction. Transactions can also be performed in the background using Grand Central Dispatch to avoid blocking the main thread. Realm objects are not thread safe and cannot be shared across threads, so you must get a Realm instance in each thread/dispatch_queue in which you want to read or write. Here’s an example of inserting a million objects in a background queue:

dispatch_async(queue){autoreleasepool{// Get realm and table instances for this threadletrealm=try!Realm()// Break up the writing blocks into smaller portions// by starting a new transactionforidx1in0..<1000{realm.beginWrite()// Add row via dictionary. Property order is ignored.foridx2in0..<1000{realm.create(Person.self,value:["name":"\(idx1)","birthdate":NSDate(timeIntervalSince1970:NSTimeInterval(idx2))])}// Commit the write transaction// to make this data available to other threadstry!realm.commitWrite()}}}

JSON

Realm does not have direct support for JSON, but it’s possible to add Objects from JSON using the output of NSJSONSerialization.JSONObjectWithData(_:options:). The resulting KVC-compliant object can be used to add/update Objects using the standard APIs for creating and updating objects.

// A Realm Object that represents a cityclassCity:Object{dynamicvarcity=""dynamicvarid=0// other properties left out ...}// Insert from NSData containing JSONtry!realm.write{letjson=try!NSJSONSerialization.JSONObjectWithData(data,options:NSJSONReadingOptions())realm.create(City.self,value:json,update:true)}

If there are nested objects or arrays in the JSON, these will be mapped automatically to to-one and to-many relationships - see the Nested Objects section for more detail.

When inserting or updating JSON data in a Realm using this approach, be aware that Realm expects the JSON property names and types to exactly match the Object properties. For example:

float properties should be initialized with float-backed NSNumbers.

NSDate and NSData properties cannot be automatically inferred from strings, but should be converted to the appropriate type before passing to Realm().create(_:value:update:).

If a JSON null (i.e. NSNull) is supplied for a required property, an exception will be thrown.

If no property is supplied on insert for a required property, an exception will be thrown.

Realm will ignore any properties in the JSON not defined by the Object.

If your JSON schema doesn’t align exactly with your Realm objects, we recommend you use a third party model mapping framework in order to transform your JSON. Swift has a thriving set of actively maintained model mapping frameworks which work with Realm, some of which are listed in the Realm-Cocoa repo.

Notifications

It is possible to register to be notified whenever a Realm, Results, List or LinkingObjects is updated by calling the addNotificationBlock method.

When notifications can’t be delivered instantly, multiple write transactions may be coalesced into a single notification.

Notifications are delivered as long as a reference is held to the returned notification token. You should hold onto a strong reference to this token on the class registering for updates, as notifications are automatically unregistered when the notification token is deallocated.

Realm Notifications

Realm instances send out notifications to other instances on other threads every time a write transaction is committed:

Collection Notifications

Collection notifications are a bit different from Realm notifications. They contain information that describe what changes have occurred at a fine-grained level, including the indices of objects that have been inserted, deleted, or modified since the last notification. This makes it possible to discretely control the animations and visual updates made to the content inside your UI, instead of arbitrarily reloading everything each time a notification occurs.

Collection notifications are delivered asynchronously, first with the initial results, and then again after each write transaction which changes either any of the objects in the collection, or which objects are in the collection.

These changes can be accessed via the RealmCollectionChange parameter that is passed to the notification block.

classViewController:UITableViewController{varnotificationToken:NotificationToken?=niloverridefuncviewDidLoad(){super.viewDidLoad()letrealm=try!Realm()letresults=realm.objects(Person).filter("age > 5")// 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()}}

User-Driven Updates

Realm’s notifications are designed to respond to all updates at the model layer, regardless of the thread or process that caused the change.

Most applications have interfaces where users can directly modify both the UI and underlying data simultaneously.

While it is also possible that in these same parts of the application, the model has to be observed for independent changes, such as background updates from a server, which need to be inversely reflected back to the user interface.

Reordering table view cells in a UITableView is a very common example of this pattern. Assume here that the UITableViewDataSource is based on Results, which you observe with a collection notification block for changes. Users can reorder cells by dragging them. The UITableViewDataSource is notified of changes already displayed in the user interface. You’ll need to modify your model accordingly and commit the changes to the Realm. These write transactions will trigger notifications. But re-applying those changes in the collection notification block will corrupt the order to the table view. You have to mitigate this scenario by ignoring redundant updates. Because notifications are coalesced if they can’t be delivered instantly, there’s no general solution to filtering out these changes yourself.

For that reason you should handle those UI updates manually and synchronously, while taking special care to avoid reacting to those same changes a second time in your notification block. There are a number of techniques that you can apply to accomplish this, depending on the nature of the possible changes, data models and user interactions. One approach could be to hold a write transaction open for the duration of the user interaction operation, keeping in mind the blocking nature of write transactions. Another pattern is to add a flag to your model objects that you can set and unset depending on whether the object was last mutated by user interaction or a more isolated transaction like a background import.

We’re aware of this challenging design constraint and are working on a more elegant and flexible solution (#3439).

Key-Value Observation

Realm objects are Key-Value Observing compliant for most properties. All persisted (non-ignored) properties on your Object subclasses are KVO-compliant, along with the invalidated property on Object and List.

Observing properties of standalone instances of Object subclasses works just like with any other dynamic property, but note that you cannot add an object to a Realm (with realm.add(obj) or other similar methods) while it has any registered observers.

Observing properties of persisted objects works a little differently. With persisted objects, there are three times when the value of a property may change: when you directly assign to it; when you call realm.refresh() or the Realm is automatically refreshed after a write transaction is committed on a different thread; and when you call realm.beginWrite() after changes on a different thread which have not been picked up by a refresh on the current thread.

In the latter two cases, all of the changes made in the write transaction(s) on another thread will be applied at once, and KVO notifications will all be sent at once. Any intermediate steps are discarded, so if in the write transaction you incremented a property from one to ten, on the main thread you’ll get a single notification of a change directly from one to ten. Because properties can change in value when not in a write transaction or even as part of beginning a write transaction, trying to modify persisted Realm objects from within observeValueForKeyPath(_:ofObject:change:context:) is not recommended.

Unlike NSMutableArray properties, observing changes made to List properties does not require using mutableArrayValueForKey(_:), although that is supported for compatiblity with things not written for Realm. Instead, you can simply call the modification methods on List directly, and anyone observing the property it is stored in will be notified. List properties do not need to be marked as dynamic to be observable, unlike normal properties.

Migrations

When working with any database, it is likely your data model will change over time. Since data models in Realm are defined as standard Swift classes, making model changes is as easy as changing any other Swift class. For example, suppose we have the following Person model:

We want to update the data model to require a fullName property, rather than separate first and last names. To do this, we simply change the object interface to the following:

classPerson:Object{dynamicvarfullName=""dynamicvarage=0}

At this point if you had saved any data with the previous model version, there will be a mismatch between what Realm sees defined in code and the data Realm sees on disk. When this occurs, an exception will be thrown when you try to open the existing file unless you run a migration.

Performing a Migration

You define a migration and the associated schema version by setting Realm.Configuration.schemaVersion and Realm.Configuration.migrationBlock. Your migration block provides all the logic for converting data models from previous schemas to the new schema. When creating a Realm with this configuration, the migration block will be applied to update the Realm to the given schema version if a migration is needed.

For example, suppose we want to migrate the Person model declared earlier. The minimal necessary migration block would be the following:

// Inside your application(application:didFinishLaunchingWithOptions:)letconfig=Realm.Configuration(// Set the new schema version. This must be greater than the previously used// version (if you've never set a schema version before, the version is 0).schemaVersion:1,// Set the block which will be called automatically when opening a Realm with// a schema version lower than the one set abovemigrationBlock:{migration,oldSchemaVersionin// We haven’t migrated anything yet, so oldSchemaVersion == 0if(oldSchemaVersion<1){// Nothing to do!// Realm will automatically detect new properties and removed properties// And will update the schema on disk automatically}})// Tell Realm to use this new configuration object for the default RealmRealm.Configuration.defaultConfiguration=config// Now that we've told Realm how to handle the schema change, opening the file// will automatically perform the migrationletrealm=try!Realm()

At the very minimum all we need to do is to update the version with an empty block to indicate that the schema has been upgraded (automatically) by Realm.

While this is the minimum acceptable migration, we probably want to use this block to populate any new properties (in this case fullName) with something meaningful. Within the migration block we can call Migration().enumerate(_:_:) to enumerate each Object of a certain type, and apply any necessary migration logic. Notice how for each enumeration the existing Object instance is accessed via an oldObject variable and the updated instance is accessed via newObject:

// Inside your application(application:didFinishLaunchingWithOptions:)Realm.Configuration.defaultConfiguration=Realm.Configuration(schemaVersion:1,migrationBlock:{migration,oldSchemaVersioninif(oldSchemaVersion<1){// The enumerate(_:_:) method iterates// over every Person object stored in the Realm filemigration.enumerate(Person.className()){oldObject,newObjectin// combine name fields into a single fieldletfirstName=oldObject!["firstName"]as!StringletlastName=oldObject!["lastName"]as!StringnewObject!["fullName"]="\(firstName)\(lastName)"}}})

Once the migration is successfully completed, the Realm and all of its objects can be accessed as usual by your app.

Realm.Configuration.defaultConfiguration=Realm.Configuration(schemaVersion:2,migrationBlock:{migration,oldSchemaVersionin// The enumerateObjects:block: method iterates// over every 'Person' object stored in the Realm filemigration.enumerate(Person.className()){oldObject,newObjectin// Add the `fullName` property only to Realms with a schema version of 0ifoldSchemaVersion<1{letfirstName=oldObject!["firstName"]as!StringletlastName=oldObject!["lastName"]as!StringnewObject!["fullName"]="\(firstName)\(lastName)"}// Add the `email` property to Realms with a schema version of 0 or 1ifoldSchemaVersion<2{newObject!["email"]=""}}})// Realm will automatically perform the migration and opening the Realm will succeedletrealm=try!Realm()

For a more complete look at the implementation of a data schema migration, check out our migration sample app.

Linear Migrations

Suppose we have two users for our app: JP and Tim. JP updates the app very often, but Tim happens to skip a few versions. It’s likely that JP has seen every new version of our app, and every schema upgrade in sequence: he downloaded a version of the app that took him from v0 to v1, another update that took him from v1 to v2. In contrast, it’s possible that Tim will download an update of the app that would need to take him from v0 to v2 immediately. Structuring your migration blocks with non-nestedif (oldSchemaVersion < X) calls ensures that they will see all necessary upgrades, no matter which schema version they start from.

Another scenario may arise in the case of users who skipped versions of your app. If you delete a property email at version 2 and re-introduce it at version 3, and a user jumps from version 1 to version 3, Realm will not be able to automatically detect the deletion of the email property, as there will be no mismatch between the schema on disk and the schema in the code for that property. This will lead to Tim’s Person object having a v3 address property that has the contents of the v1 address property. This may not be a problem, unless you changed the internal storage representation of that property between v1 and v3 (say, went from an ISO address representation to a custom one). To avoid this, we recommend you nil out the email property on the if (oldSchemaVersion < 3) statement, guaranteeing that all realms upgraded to version 3 will have a correct dataset.

Encryption

Realm’s encryption APIs are available for iOS, OS X & WatchKit but not watchOS because the <mach/mach.h> and <mach/exc.h> APIs used by Realm’s encryption mechanism are marked as __WATCHOS_PROHIBITED.

Please take note of the Export Compliance section of our LICENSE, as it places restrictions against the usage of Realm if you are located in countries with an export restriction or embargo from the United States.

Realm supports encrypting the database file on disk with AES-256+SHA2 by supplying a 64-byte encryption key when creating a Realm.

// Generate a random encryption keyletkey=NSMutableData(length:64)!SecRandomCopyBytes(kSecRandomDefault,key.length,UnsafeMutablePointer<UInt8>(key.mutableBytes))// Open the encrypted Realm fileletconfig=Realm.Configuration(encryptionKey:key)do{letrealm=tryRealm(configuration:config)// Use the Realm as normalletdogs=realm.objects(Dog).filter("name contains 'Fido'")}catchleterrorasNSError{// If the encryption key is wrong, `error` will say that it's an invalid databasefatalError("Error opening realm: \(error)")}

This makes it so that all of the data stored on disk is transparently encrypted and decrypted with AES-256 as needed, and verified with a SHA-2 HMAC. The same encryption key must be supplied every time you obtain a Realm instance.

See our encryption sample app for an end-to-end app that generates an encryption key, stores it securely in the keychain, and uses it to encrypt a Realm.

There is a small performance hit (typically less than 10% slower) when using encrypted Realms.

Testing and Debugging

Configuring the Default Realm

The easiest way to use and test Realm apps is to use the default realm. To avoid overriding application data or leaking state between tests, you can simply set the default Realm to a new file for each test.

importXCTest// A base class which each of your Realm-using tests should inherit from rather// than directly from XCTestCaseclassTestCaseBase:XCTestCase{overridefuncsetUp(){super.setUp()// Use an in-memory Realm identified by the name of the current test.// This ensures that each test can't accidentally access or modify the data// from other tests or the application itself, and because they're in-memory,// there's nothing that needs to be cleaned up.Realm.Configuration.defaultConfiguration.inMemoryIdentifier=self.name}}

Injecting Realm Instances

Another way to test realm-related code is to have all the methods you’d like to test accept a Realm instance as an argument, so that you can pass in different realm when running the app and when testing it. For example, suppose your app has a method to GET a user profile from a JSON API and you’d like to test that the local profile is properly created:

Debugging

Debugging your Realm apps is easy, with the ability to view your app’s data in the Realm Studio.

Debugging apps using Realm’s Swift API must be done through the LLDB console.

Note that although the LLDB script installed via our Xcode Plugin allows inspecting the contents of your Realm variables in Xcode’s UI, this doesn’t yet work for Swift. Instead, those variables will show incorrect data. You should instead use LLDB’s po command to inspect the contents of data stored in a Realm.

Avoid Linking Realm and Tested Code in Test Targets

Since you’re using Realm as a dynamic framework, you’ll need to make sure your unit test target can find Realm. You can do this by adding the parent path to RealmSwift.framework to your unit test’s “Framework Search Paths”.

If your tests fail with an exception message "Object type '...' not persisted in Realm", it’s likely because you’ve linked the Realm framework directly to your test target, which should not be done. Unlinking Realm from your test target should address that.

You should also make sure to only compile your model class files in your application or framework targets; never add them to your unit test targets. Otherwise, those classes will be duplicated when testing, which can lead to difficult to debug issues (see this issue for details).

You’ll need to make sure all the code you need to test is exposed to your unit test targets (use the public access modifier or @testable). See this Stack Overflow answer for details.

Current Limitations

Realm is currently in beta and we are continuously adding features and fixing issues while working towards a 1.0 release. Until then, we’ve compiled a list of our most commonly hit limitations.

Please refer to our GitHub issues for a more comprehensive list of known issues.

General Limits

Realm aims to strike a balance between flexibility and performance. In order to accomplish this goal, realistic limits are imposed on various aspects of storing information in a realm. For example:

Class names must be between 0 and 63 bytes in length. UTF8 characters are supported. An exception will be thrown at your app’s initialization if this limit is exceeded.

Property names must be between 0 and 63 bytes in length. UTF8 characters are supported. An exception will be thrown at your app’s initialization if this limit is exceeded.

NSData and String properties cannot hold data exceeding 16MB in size. To store larger amounts of data, either break it up into 16MB chunks or store it directly on the file system, storing paths to these files in the realm. An exception will be thrown at runtime if your app attempts to store more than 16MB in a single property.

Any single Realm file cannot be larger than the amount of memory your application would be allowed to map in iOS — this changes per device, and depends on how fragmented the memory space is at that point in time (there is a radar open about this issue: rdar://17119975). If you need to store more data, you can map it over multiple Realm files.

Realm Object Setters & Getters cannot be overriden

Since Realm overrides setters and getters to back properties directly by the underlying database, you cannot override them on your objects. A simple workaround is to create new, realm-ignored properties, whose accessors can be overriden, and can call other setters/getters.

File size & tracking of intermediate versions

You should expect a Realm database to take less space on disk than an equivalent SQLite database. If your Realm file is much larger than you expect, it may be because you have a Realm that is referring to an older version of the data in the database.

In order to give you a consistent view of your data, Realm only updates the active version accessed at the start of a run loop iteration. This means that if you read some data from the Realm and then block the thread on a long-running operation while writing to the Realm on other threads, the version is never updated and Realm has to hold on to intermediate versions of the data which you may not actually need, resulting in the file size growing with each write. The extra space will eventually be reused by future writes, or may be compacted — for example by calling Realm().writeCopyToPath(_:encryptionKey:).

To avoid this issue you, may call invalidate to tell Realm that you no longer need any of the objects that you’ve read from the Realm so far, which frees us from tracking intermediate versions of those objects. The Realm will update to the latest version the next time it is accessed.

You may also see this problem when accessing Realm using Grand Central Dispatch. This can happen when a Realm ends up in a dispatch queue’s autorelease pool as those pools may not be drained for some time after executing your code. The intermediate versions of data in the Realm file cannot be reused until the Realm object is deallocated. To avoid this issue, you should use an explicit autorelease pool when accessing a Realm from a dispatch queue.

Realm doesn’t have auto-incrementing properties

Realm doesn’t have a mechanism for thread-/process-safe auto-incrementing properties commonly used in other databases when generating primary keys. However, in most situations where a unique auto-generated value is desired, it isn’t necessary to have sequential, contiguous, integer IDs.

In these cases, a unique string primary key is typically sufficient. A common pattern is to set the default property value to NSUUID().UUIDString to generate unique string IDs.

Another common motivation for auto-incrementing properties is to preserve order of insertion. In some situations, this can be accomplished by appending objects to a List or by using a createdAt property with a default value of NSDate().

List and RealmOptional properties aren’t accessible from Objective‑C

If you need to access your Realm Swift models from Objective‑C, your List and RealmOptional properties will cause the auto-generated Objective‑C header (-Swift.h) to fail to compile because of the use of generics. You can work around this known Swift bug by annotating your List and RealmOptional properties as @nonobjc, which will hide them from the auto-generated Objective‑C header (-Swift.h).

Adding custom initializers to Object subclasses

When creating your model Object subclasses, you may sometimes want to add your own custom initialization methods for added convenience.

Due to some present limitations with Swift introspection, these methods cannot be designated initializers for the class. Instead, they need to be marked as convenience initializers using the Swift keyword of the same name:

classMyModel:Object{dynamicvarmyValue=""convenienceinit(myValue:String){self.init()//Please note this says 'self' and not 'super'self.myValue=myValue}}

Recipes

We’ve put together some recipes showing how to use Realm to accomplish a few specific tasks. We add more recipes regularly, so check back often. If there’s an example you’d like to see, please open an issue on GitHub.

FAQ

How big is the Realm library?

Once your app is built for release, Realm should only add around 1MB to its size. The releases we distribute are significantly larger because they include support for iOS, watchOS and tvOS simulators, some debug symbols, and bitcode, which are all stripped by Xcode automatically when you build your app.

Should I use Realm in production applications?

Realm has been used in production in commercial products since 2012.

You should expect our Objective‑C & Swift APIs to change as we evolve the product from community feedback — and you should expect more features & bugfixes to come along as well.

Do I have to pay to use Realm?

No, Realm is entirely free to use, even in commercial projects.

How do you all plan on making money?

We’re actually already generating revenue selling enterprise products and services around our technology. If you need more than what is currently in our releases or in realm-cocoa, we’re always happy to chat by email. Otherwise, we are committed to developing realm-cocoa in the open, and to keep it free and open-source under the Apache 2.0 license.

I see references to a “core” in the code, what is that?

The core is referring to our internal C++ storage engine. It is not currently open-source but we do plan on open-sourcing it also under the Apache 2.0 license once we’ve had a chance to clean it, rename it, and finalize major features inside of it. In the meantime, its binary releases are made available under the Realm Core (TightDB) Binary License.

I see a network call to Mixpanel when I run my app, what is that?

Realm collects anonymous analytics when your app is run with a debugger attached, or when it runs in a simulator. This is completely anonymous and helps us improve the product by flagging which versions of Realm, iOS, OS X, or which language you target and which versions we can deprecate support for. This call does not run when your app is in production, or running on your user’s devices — only from inside your simulator or when a debugger is attached. You can see exactly how & what we collect, as well as the rationale for it in our source code.

Troubleshooting

Crash Reporting

We encourage you to use a crash reporter in your application. Many Realm operations could potentially fail at runtime (like any other disk IO), so collecting crash reports from your application will help identify areas where either you (or us) can improve error handling and fix crashing bugs.

Most commercial crash reporters have the option of collecting logs. We strongly encourage you to enable this feature. Realm logs metadata information (but no user data) when throwing exceptions and in irrecoverable situations, and these messages can help debug when things go wrong.

Reporting Realm Issues

If you’ve found an issue with Realm, please either file an issue on GitHub or email us at help@realm.io with as much information as possible for us to understand and reproduce your issue.

The following information is very useful to us:

Goals.

Expected results.

Actual results.

Steps to reproduce.

Code sample that highlights the issue (full Xcode projects that we can compile ourselves are ideal).

Reinstalling Via Dependency Managers

If you’ve installed Realm via CocoaPods or Carthage and you’re experiencing build errors, then it’s likely that you’re either using an unsupported version of that dependency manager, Realm’s integration into the project didn’t succeed, or an update to an application in your toolchain (e.g. Xcode) may have changed the installation configuration.

If that is the case, please try removing the folders the dependency manager created and installing again:

CocoaPods

Realm can be installed via CocoaPods 0.39.0 or greater.

If you have troubles with your CocoaPods integration, it might help to reset the integration state. To achieve that simply run the following commands in Terminal out of your project directory:

You can also use cocoapods-deintegrate instead of deleting the Pods directory. With CocoaPods 1.0 and its prereleases, this comes as preinstalled plugin. If you’re using an older version, you may consider installing it by gem install cocoapods-deintegrate. You can run it by pod deintegrate. That removes all traces of CocoaPods from your Xcode project.

Carthage

Realm can be installed via Carthage 0.9.2 or later.

To remove all Carthage-managed dependencies from your project, simply run the following commands in Terminal out of your project directory:

rm -rf Carthage
carthage update

Realm Core Binary Fails to Download

When building Realm, part of the process includes downloading the core library as a static binary and integrating it into the Realm-Cocoa project.

It’s been reported that in certain instances, the core binary fails to download with the following error:

Downloading core failed. Please try again once you have an Internet connection.

This error can occur due to any of the following reasons:

Your IP address range is from a region that is on the list of United States embargoes. In order to comply with U.S. law, Realm has not been made available in that region. For more information, please see our license.

You are located in mainland China, and due to the country-wide firewall are not able to properly access CloudFlare or Amazon AWS S3 services at the moment. Please see this Realm-Cocoa Issue for more information.