This is not the current version. View the latest documentation

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.


// Define your models like regular Swift classes
class Dog: Object {
  dynamic var name = ""
  dynamic var age = 0
class Person: Object {
  dynamic var name = ""
  dynamic var picture: NSData? = nil // optionals supported
  let dogs = List<Dog>()

// Use them like regular Swift objects
let myDog = Dog() = "Rex"
myDog.age = 1
print("name of dog: \(")

// Get the default Realm
let realm = try! Realm()

// Query Realm for all dogs less than 2 years old
let puppies = realm.objects(Dog.self).filter("age < 2")
puppies.count // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
try! realm.write {

// Queries are updated in realtime
puppies.count // => 1

// Query and update from any thread
DispatchQueue(label: "background").async {
  let realm = try! Realm()
  let theDog = realm.objects(Dog.self).filter("age == 1").first
  try! realm.write {
    theDog!.age = 3


Getting Started

Download Realm Swift or see the source on GitHub.


  • Apps using Realm can target: iOS 8 or later, macOS 10.9 or later, all versions of tvOS and watchOS.
  • Xcode 7.3 or later required.


  2. Go to your Xcode project’s “General” settings. Drag RealmSwift.framework and Realm.framework from the appropriate Swift-versioned directory for your project in ios/, osx/, tvos/ or watchos/ directory to the “Embedded Binaries” section. Make sure Copy items if needed is selected and click Finish.
  4. If using Realm in an iOS, tvOS or watchOS project, create a new “Run Script Phase” in your app’s target’s “Build Phases” and paste the following snippet in the script text field:



  1. Install CocoaPods 0.39.0 or later.
  3. If using Xcode 8, paste the following at the bottom of your Podfile, updating the Swift version if necessary:

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
          config.build_settings['SWIFT_VERSION'] = '2.3' # or '3.0'
  4. From the command line, run pod install.
  5. Use the .xcworkspace file generated by CocoaPods to work on your project!
  1. Install Carthage 0.17.0 or later.
  3. Run carthage update. To modify the Swift toolchain used to build, specify it via the --toolchain argument. The --no-use-binaries argument is also necessary to avoid Carthage pulling the prebuilt Swift 3.0 binaries. For example:

    carthage update --toolchain --no-use-binaries
  4. Drag RealmSwift.framework and Realm.framework from the appropriate platform directory in Carthage/Build/ to the “Linked Frameworks and Libraries” section of your Xcode project’s “General” settings.
  5. iOS/tvOS/watchOS: On your application targets’ “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script with the following contents:

    /usr/local/bin/carthage copy-frameworks




Importing the Realm Framework

At the top of your Swift source files, use import RealmSwift to import Realm Swift and make it available for use with your code. That’s all you need to get started!


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.

If you would like to share a Realm file between a tvOS app and a TV services extension (e.g. Top Shelf extension), you have to use the Library/Caches/ directory within the shared container for the application group.

let fileURL = FileManager.default
    .containerURL(forSecurityApplicationGroupIdentifier: "")!



Realm Browser


Realm Browser



The Realm Browser is available on the Mac App Store.

Xcode Plugin

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

Realm Plugin


API Reference




Getting Help




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.


import RealmSwift

// Dog model
class Dog: Object {
    dynamic var name = ""
    dynamic var owner: Person? // Properties can be optional

// Person model
class Person: Object {
    dynamic var name = ""
    dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
    let dogs = List<Dog>()



See Object for more details.

Supported Types

Realm supports the following property types: Bool, Int8, Int16, Int32, Int64, Double, Float, String, NSDate, and NSData.


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


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.


class Dog: Object {
    dynamic var name = ""

To-One Relationships


class Dog: Object {
    // ... other property declarations
    dynamic var owner: Person? // to-one relationships must be optional

You can use this property like you would any other:

let jim = Person()
let rex = Dog()
rex.owner = jim


To-Many Relationships



class Person: Object {
    // ... other property declarations
    let dogs = List<Dog>()

You can access and assign List properties as usual:

let someDogs = realm.objects(Dog.self).filter("name contains 'Fido'")
jim.dogs.append(objectsIn: someDogs)

List properties are guaranteed to preserve their order of insertion.

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 type LinkingObjects and then specifying the relationship that it has with the Person object.

class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0

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:

class Person: Object {
    // Optional string property, defaulting to nil
    dynamic var name: 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 desired
    let age = RealmOptional<Int>()

let realm = try! Realm()
try! realm.write() {
    var person = realm.create(Person.self, value: ["Jane", 27])
    // Reading from or modifying a `RealmOptional` is done via the `value` property
    person.age.value = 28

RealmOptional supports Int, Float, Double, Bool, and all of the sized versions of Int (Int8, Int16, Int32, Int64).


This table provides a handy reference to declaring model properties.

Type Non-optional Optional
Bool dynamic var value = false let value = RealmOptional<Bool>()
Int dynamic var value = 0 let value = RealmOptional<Int>()
Float dynamic var value: Float = 0.0 let value = RealmOptional<Float>()
Double dynamic var value: Double = 0.0 let value = RealmOptional<Double>()
String dynamic var value = "" dynamic var value: String? = nil
Data dynamic var value = NSData() dynamic var value: NSData? = nil
Date dynamic var value = NSDate() dynamic var value: NSDate? = nil
Object n/a: must be optional dynamic var value: Class?
List let value = List<Class>() n/a: must be non-optional
LinkingObjects let value = LinkingObjects(fromType: Class.self, property: "property") n/a: must be non-optional

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.

Indexed Properties


class Book: Object {
  dynamic var price = 0
  dynamic var title = ""

  override static func indexedProperties() -> [String] {
    return ["title"]

Realm supports indexing for string, integer, boolean, and NSDate properties.


Auto-Updating Objects


let myDog = Dog() = "Fido"
myDog.age = 1

try! realm.write {

let myPuppy = realm.objects(Dog.self).filter("age == 1").first
try! realm.write {
  myPuppy!.age = 2

print("age of my dog: \(myDog.age)") // => 2

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 specific Realm object, you don’t need to worry about refreshing or re-fetching it before triggering a UI redraw.


Primary Keys


class Person: Object {
  dynamic var id = 0
  dynamic var name = ""

  override static func primaryKey() -> String? {
    return "id"

Ignored Properties


class Person: Object {
  dynamic var tmpID = 0
  var name: String { // read-only properties are automatically ignored
    return "\(firstName) \(lastName)"
  dynamic var firstName = ""
  dynamic var lastName = ""

  override static func ignoredProperties() -> [String] {
    return ["tmpID"]

Model Inheritance



The following is not possible:

  • Querying on multiple classes simultaneously.
  • Multi-class containers (List and Results).



// Base Model
class Animal: Object {
  dynamic var age = 0

// Models composed with Animal
class Duck: Object {
  dynamic var animal: Animal? = nil
  dynamic var name = ""
class Frog: Object {
  dynamic var animal: Animal? = nil
  dynamic var dateProp = NSDate()

// Usage
let duck = Duck(value: [ "animal": [ "age": 3 ], "name": "Gustav" ])


Realm has several types that help represent groups of objects, which we refer to as “Realm Collections”:

  1. Results, a class representing objects retrieved from queries.
  2. List, a class representing to-many relationships in models.
  3. LinkingObjects, a class representing inverse relationships in models.
  4. RealmCollection, a protocol defining the common interface to which all Realm Collections conform.
  5. 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 RealmCollection protocol, which ensures they behave consistently. This protocol inherits from CollectionType so that it may be used in the same ways 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 RealmCollection protocol, you can write generic code that can operate on any Realm collection:

func operateOn<C: RealmCollection>(collection: C) {
  // Collection could be either Results or List
  print("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:

class ViewController {
//  let collection: RealmCollection
//                  ^
//                  error: protocol 'RealmCollection' can only be used
//                  as a generic constraint because it has Self or
//                  associated type requirements
//  init<C: RealmCollection>(collection: C) where C.Element == MyModel {
//    self.collection = collection
//  }

  let collection: AnyRealmCollection<MyModel>

    self.collection = AnyRealmCollection(collection)



Realm objects can be instantiated and used as unmanaged objects (i.e. not yet added to a Realm) just like regular Swift objects. To share objects between threads or re-use them between app launches you must add them into a Realm, an operation which must be done within a write transaction.


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


class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0

We can create new objects in several ways:

var myDog = Dog() = "Rex"
myDog.age = 10

// (2) Create a Dog object from a dictionary

// (3) Create a Dog object from an array
  3. 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


// Instead of using already existing dogs...

// ...we can create them inline

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 object
let author = Person() = "David Foster Wallace"

// Get the default Realm
let realm = try! Realm()

// Add to the Realm inside a transaction
try! realm.write {


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 practice for this situation: offloading your writes to a separate thread.


See Realm and Object for more details.

Updating Objects


Typed Updates


// Update an object with a transaction
try! realm.write { = "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:).

let cheeseBook = Book()
cheeseBook.title = "Cheese recipes"
cheeseBook.price = 9000 = 1

// Updating book with id = 1
try! realm.write {
  realm.add(cheeseBook, update: true)



try! realm.write {
  // 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



let persons = realm.objects(Person.self)
try! realm.write {
  // set each person's planet property to "Earth"
  persons.setValue("Earth", forKeyPath: "planet")

Deleting Objects


// let cheeseBook = ... Book stored in Realm

// Delete an object with a transaction
try! realm.write {


// Delete all objects from the realm
try! realm.write {


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.



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.


let dogs = realm.objects(Dog.self) // retrieves all Dogs from the default Realm



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

// Query using a predicate string
var tanDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'")

// Query using an NSPredicate
tanDogs = realm.objects(Dog.self).filter(predicate)


  • The comparison operators ==, <=, <, >=, >, !=, and BETWEEN are supported for Int, Int8, Int16, Int32, Int64, Float, Double and NSDate property types. Such as age == 45
  • 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.self).filter("[email protected] > 5") to find all companies with more than five employees.
  • Subqueries are supported with the following limitations:
    • Correlated subqueries are not yet supported.



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

let sortedDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'").sorted(byProperty: "name")

For more, see Results().sorted(_:) and Results().sorted(_:ascending:).




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

let tanDogs = realm.objects(Dog.self).filter("color = 'tan'")

Auto-Updating Results


puppies.count // => 0
try! realm.write {
  realm.create(Dog.self, value: ["name": "Fido", "age": 1])
puppies.count // => 1

This applies to all Results: all objects, filtered and chained.

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.


Since results are auto-updating, it’s important to not rely on indices and 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:

try! realm.write {
  for person in realm.objects(Person.self).filter("age == 10") {
    person.age += 1

Alternatively, use key-value coding to perform operations on Results.

Limiting Results



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 disk
let dogs = try! Realm().objects(Dog.self)
for i in 0..<5 {
  let dog = dogs[i]
  // ...


The Default Realm


Realm Configuration



func setDefaultRealmForUser(username: String) {
  var config = Realm.Configuration()

  config.fileURL = config.fileURL!.deletingLastPathComponent()

  // Set this as the configuration used for the default Realm
  Realm.Configuration.defaultConfiguration = config

Other Realms


let config = Realm.Configuration(
    // Get the URL to the bundled file
    fileURL: Bundle.main.url(forResource: "MyBundledData", withExtension: "realm"),
    readOnly: true)

// Open the Realm with the configuration
let realm = try! Realm(configuration: config)

// Read some data from the bundled Realm
let results = realm.objects(Dog.self).filter("age > 5")


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.

let realm = try! Realm(configuration: Realm.Configuration(inMemoryIdentifier: "MyInMemoryRealm"))




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 {
  let realm = try Realm()
} catch let error as NSError {
  // 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


Auxiliary Realm Files


  • .realm.lock - A lock file for resource locks.
  • .realm.note - A named pipe for notifications.



Bundling a Realm with an App


  1. 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.
  2. 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.
  3. Drag the new compacted copy of your Realm file to your final app’s Xcode Project Navigator.
  4. Go to your app target’s build phases tab in Xcode and add the Realm file to the “Copy Bundle Resources” build phase.
  5. At this point, your bundled Realm file will be accessible to your app. You can find its path by using NSBundle.main.pathForResource(_:ofType:).

You can refer to our migration sample app for an example of how to use a bundled Realm file.

Class Subsets


let realm = try! Realm(configuration: config)

Deleting Realm Files


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.


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.

autoreleasepool {
  // all Realm usage here
let realmURL = Realm.Configuration.defaultConfiguration.fileURL!
let realmURLs = [
for URL in realmURLs {
  do {
    try FileManager.default.removeItem(at: URL)
  } catch {
    // handle error

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 choose 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 recommend 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.

let realm = try! Realm()

// Get our Realm file's parent directory
let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().path

// Disable file protection for this directory
try! FileManager.default.setAttributes([FileAttributeKey(rawValue: NSFileProtectionKey): NSFileProtectionNone],
                                       ofItemAtPath: folderPath)





Seeing Changes From 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()).


Passing Instances Across Threads

Unmanaged instances of Objects behave exactly as regular NSObject subclasses, and are safe to pass across threads.

Instances of Realm, Results, or List, or managed instances of Object 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 without 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.


  • Realm: all properties, class methods, and initializers.
  • Object: invalidated, objectSchema, realm, class methods, and initializers.
  • Results: objectClassName and realm.
  • List: invalidated, objectClassName, and realm.

Using a Realm Across Threads


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:

DispatchQueue(label: "background").async {
  autoreleasepool {
    // Get realm and table instances for this thread
    let realm = try! Realm()

    // Break up the writing blocks into smaller portions
    // by starting a new transaction
    for idx1 in 0..<1000 {

      // Add row via dictionary. Property order is ignored.
      for idx2 in 0..<1000 {
        realm.create(Person.self, value: [
          "name": "\(idx1)",
          "birthdate": Date(timeIntervalSince1970: TimeInterval(idx2))

      // Commit the write transaction
      // to make this data available to other threads
      try! realm.commitWrite()


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 city
class City: Object {
  dynamic var city = ""
  dynamic var id = 0
  // other properties left out ...

// Insert from NSData containing JSON
try! realm.write {
  let json = 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 repository.


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

It’s also possible to observe changes to a single Object through Key-Value Observation.

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 keep 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


// Observe Realm Notifications
let token = realm.addNotificationBlock { notification, realm in

// later

Collection Notifications

Collection notifications are different from Realm notifications in that they contain information that describe what changes have occurred at a fine-grained level. This consists of the indices of objects that have been inserted, deleted, or modified since the last notification.

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. This object holds information about the indices affected by deletions, insertions and modifications.

The former two, deletions and insertions, record the indices whenever objects start and stop being part of the collection. This takes into account when you add objects to the Realm or delete them from the Realm. For Results this also applies when you filter for specific values and the object was changed so that it is now matching the query or not matching anymore. For collections based either on List or LinkingObjects, including derived Results, this applies in addition when objects are added or removed from the relationship.

You’re notified about modifications whenever a property of an object has changed, which was previously part of the collection and is still part of it. This happens as well when to-one and to-many relationships change, but doesn’t take changes on inverse relationships into account.

class Dog: Object {
  dynamic var name = ""
  dynamic var age = 0

class Person: Object {
  dynamic var name = ""
  let dogs = List<Dog>()

So let’s assume you’re observing a list of dog owners as given by the model code above, you will be notified about modifications for a matched Person object for example when:

  • You modify the Person’s name property.
  • You add or remove a Dog to the Person’s dogs property.
  • You modify the age property of a Dog belonging to that Person.

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.

class ViewController: UITableViewController {
  var notificationToken: NotificationToken? = nil

  override func viewDidLoad() {
    let realm = try! Realm()
    let results = realm.objects(Person.self).filter("age > 5")

    // Observe Results Notifications
    notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
      guard let tableView = self?.tableView else { return }
      switch changes {
      case .initial:
        // Results are now populated and can be accessed without blocking the UI
      case .update(_, let deletions, let insertions, let modifications):
        // Query results have changed, so apply them to the UITableView
        tableView.insertRowsAtIndexPaths(indexPaths: { NSIndexPath(forRow: $0, inSection: 0) },
          withRowAnimation: .Automatic)
          withRowAnimation: .Automatic)
          withRowAnimation: .Automatic)
      case .error(let error):
        // An error occurred while opening the Realm file on the background worker thread

  deinit {

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).

Notification APIs

See the following API documentation for details:

Key-Value Observation

Realm objects are Key-Value Observing compliant for most properties. Almost all managed (non-ignored) properties on your Object subclasses are KVO-compliant, along with the invalidated property on Object and List. (LinkingObjects properties can’t be observed using KVO.)


Observing properties of managed objects (those previously added to a Realm) works a little differently. With managed 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.


Unlike NSMutableArray properties, observing changes made to List properties does not require using mutableArrayValueForKey(_:), although that is supported for compatibility with code not written with Realm in mind. 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.




class Person: Object {
    dynamic var firstName = ""
    dynamic var lastName = ""
    dynamic var age = 0


class Person: Object {
    dynamic var fullName = ""
    dynamic var age = 0


Performing a Migration

Defining Migrations



// Inside your application(application:didFinishLaunchingWithOptions:)

let config = Realm.Configuration(
  schemaVersion: 1,

  // a schema version lower than the one set above
  migrationBlock: { migration, oldSchemaVersion in
    if (oldSchemaVersion < 1) {
      // Nothing to do!
      // Realm will automatically detect new properties and removed properties
      // And will update the schema on disk automatically

Realm.Configuration.defaultConfiguration = config

// will automatically perform the migration
let realm = try! Realm()


Updating Values

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().enumerateObjects(ofType: _:_:) 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, oldSchemaVersion in
    if (oldSchemaVersion < 1) {
      // The enumerateObjects(ofType:_:) method iterates
      // over every Person object stored in the Realm file
      migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
        // combine name fields into a single field


Renaming Properties

Renaming the property on a class as part of a migration is more efficient than copying values and preserves relationships rather than duplicating them.

To rename a property during a migration, make sure that your new models have a property with the new name and don’t have a property with the old name.

If the new property has different nullability or indexing settings, those will be applied during the rename operation.

Here’s how you could rename Person’s yearsSinceBirth property to age:

// Inside your application(application:didFinishLaunchingWithOptions:)

Realm.Configuration.defaultConfiguration = Realm.Configuration(
  schemaVersion: 1,
  migrationBlock: { migration, oldSchemaVersion in
    if (oldSchemaVersion < 1) {
      // The renaming operation should be done outside of calls to `enumerateObjects(ofType: _:)`.
      migration.renameProperty(onType: Person.className(), from: "yearsSinceBirth", to: "age")

Adding more versions

Suppose now we have two previous versions of the Person class:

// v0
// class Person: Object {
//   dynamic var firstName = ""
//   dynamic var firstName = ""
//   dynamic var age = 0
// }

// v1
// class Person: Object {
//   dynamic var fullName = "" // new property
//   dynamic var age = 0
// }

// v2
class Person: Object {
  dynamic var fullName = ""
  dynamic var email = "" // new property
  dynamic var age = 0

The logic in our migration block might look like the following:

Realm.Configuration.defaultConfiguration = Realm.Configuration(
  schemaVersion: 2,
  migrationBlock: { migration, oldSchemaVersion in
    // The enumerateObjects:block: method iterates
      if oldSchemaVersion < 1 {

      if oldSchemaVersion < 2 {
          newObject!["email"] = ""

let realm = try! Realm()


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 order: he downloaded a version of the app that took him from v0 to v1, and later another update that took him from v1 to v2. In contrast, it’s possible that Tim might download an update of the app that will need to take him from v0 to v2 immediately. Structuring your migration blocks with non-nested if (oldSchemaVersion < X) calls ensures that they will see all necessary upgrades, no matter which schema version they start from.







// Generate a random encryption key
var key = Data(count: 64)
key.withUnsafeMutableBytes { bytes in
  SecRandomCopyBytes(kSecRandomDefault, 64, bytes)

// Open the encrypted Realm file
let config = Realm.Configuration(encryptionKey: key)
do {
  let realm = try Realm(configuration: config)
  // Use the Realm as normal
  let dogs = realm.objects(Dog.self).filter("name contains 'Fido'")
} catch let error as NSError {
  fatalError("Error opening realm: \(error)")




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.

import XCTest

// than directly from XCTestCase
class TestCaseBase: XCTestCase {
  override func setUp() {

    // there's nothing that needs to be cleaned up.
    Realm.Configuration.defaultConfiguration.inMemoryIdentifier =

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 Realms 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:

// Application Code
func updateUserFromServer() {
  let url = URL(string: "")
  URLSession.shared.dataTask(with: url!) { data, _, _ in
    let realm = try! Realm()
    createOrUpdateUser(in: realm, with: data!)

public func createOrUpdateUser(in realm: Realm, with data: Data) {
  let object = try! JSONSerialization.jsonObject(with: data) as! [String: String]
  try! realm.write {
    realm.create(User.self, value: object, update: true)

// Test Code

let testRealmURL = URL(fileURLWithPath: "...")

func testThatUserIsUpdatedFromServer() {
  let config = Realm.Configuration(fileURL: testRealmURL)
  let testRealm = try! Realm(configuration: config)
  let jsonData = "{\"email\": \"[email protected]\"}".data(using: .utf8)!
  createOrUpdateUser(in: testRealm, with: jsonData)
  XCTAssertEqual(testRealm.objects(User.self).first!, expectedUser,
                 "User was not properly updated from server.")


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



Avoid Linking Realm and Tested Code in Test Targets


If your tests fail with an exception message "Object type 'YourObject' is not managed by the 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.



Current Limitations

Here’s a list of our most commonly hit limitations.


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:

  1. Class names are limited to a maximum of 57 UTF8 characters.
  2. Property names are limited to a maximum of 63 UTF8 characters.
  3. 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.
  5. String sorting and case insensitive queries are only supported for character sets in ‘Latin Basic’, ‘Latin Supplement’, ‘Latin Extended A’, ‘Latin Extended B’ (UTF-8 range 0-591).


Although Realm files can be accessed by multiple threads concurrently, you cannot hand over Realms, Realm objects, queries, and results between threads. Read more about Realm’s threading.

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





Realm doesn’t have auto-incrementing properties


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:

class MyModel: Object {
    dynamic var myValue = ""

    convenience init(myValue: String) {
        self.init() //Please note this says 'self' and not 'super'
        self.myValue = myValue


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.


How big is the Realm library?


Should I use Realm in production applications?

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

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

Do I have to pay to use Realm?


How do you all plan on making money?







Crash Reporting



Reporting Realm Issues


The following information is very useful to us:

  1. Goals.
  2. Expected results.
  3. Actual results.
  4. Steps to reproduce.
  6. Version of Realm / Xcode / OS X.

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 part of your build tools have stale caches.


You can also try deleting derived data and cleaning the build folder in Xcode; this can fix issues caused by updating build tool versions or making changes to your project setup such as adding a new target, sharing dependencies across targets, etc. To clean the build folder, hold down the ‘Option’ key while opening the ‘Product’ menu, then choose ‘Clean Build Folder…’. You can also type ‘Clean’ into the Xcode help search menu and select the ‘Clean Build Folder…’ menu item when it shows up in the search results.


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:

pod cache clean Realm
pod cache clean RealmSwift
pod deintegrate || rm -rf Pods
pod install --verbose
rm -rf ~/Library/Developer/Xcode/DerivedData

You can also use cocoapods-deintegrate instead of deleting the Pods directory. With CocoaPods 1.0, 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.


Realm can be installed via Carthage 0.9.2 or later.


rm -rf Carthage
rm -rf ~/Library/Developer/Xcode/DerivedData
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.



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