29

I would like to deliver my app with already prefilled data in my realm database. Do I have to simply copy it to the documents directory or is there some other things to do?

swalkner
  • 16,679
  • 31
  • 123
  • 210

3 Answers3

32

Realm's documentation has a section on "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:

  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 -[RLMRealm writeCopyToPath:error:]). 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 mainBundle] pathForResource:ofType:].

  6. You can either create a read-only realm by calling [RLMRealm realmWithPath:readOnly:error:]. Or, if you’d like to create a writable realm file based on this initial data, you can copy the bundled file to your application’s Documents directory using [[NSFileManager defaultManager] copyItemAtPath:toPath:error:] and then construct your new realm by using [RLMRealm realmWithPath:].

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

Community
  • 1
  • 1
jpsim
  • 14,329
  • 6
  • 51
  • 68
  • 3
    What about the instructions for Android? The documentation for Java is missing a similiar section. – caulitomaz Oct 20 '15 at 12:29
  • 3
    You can see an example of how to bundle a Realm file in the Java migration example here: https://github.com/realm/realm-java/blob/master/examples/migrationExample/src/main/java/io/realm/examples/realmmigrationexample/MigrationExampleActivity.java. – Christian Melchior Oct 21 '15 at 07:19
  • 1
    See my [answer](http://stackoverflow.com/a/36850732/262789) for the Realm Android supported way of adding initial data. – Jade Apr 25 '16 at 20:48
  • @jpsim Is there any simple example for this particular case in iOS? Because migration is another case, there should be a simple example of it. – Malik Umar Oct 24 '16 at 08:34
  • Migrating bundled Realm files is a superset of just using it without migration. Just remove the migration-related code if you're not interested in that part of the example. – jpsim Oct 24 '16 at 16:29
  • what's the relative size of a .realm file and .json. i already populate realm with a json directly so im trying to see if it's worth it to convert them to .realm files – ono Aug 08 '17 at 01:47
  • If your JSON file is large, I all but guarantee you that converting it to a Realm (and compacting that Realm) will yield a significantly smaller file, and you'll avoid the performance cost of deserializing the JSON & writing to the database on app launch. – jpsim Aug 08 '17 at 20:08
  • This answer is still working in 2022. Thanks! – XY L Apr 18 '22 at 14:39
4

Pre filled Realm-database For Android

Put your realm database in res/raw folder

and execute following code in activity:

// Copying realm database

copyBundledRealmFile(this.getResources().openRawResource(R.raw.default0), "default0.realm");

RealmConfiguration config0 = new RealmConfiguration.Builder()
            .name("default0.realm")
            .build();

realm = Realm.getInstance(config0);

private String copyBundledRealmFile(InputStream inputStream, String outFileName) {
    try {
        File file = new File(this.getFilesDir(), outFileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        byte[] buf = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buf)) > 0) {
            outputStream.write(buf, 0, bytesRead);
        }
        outputStream.close();
        return file.getAbsolutePath();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
Noor Ali Butt
  • 798
  • 8
  • 24
0

A much easier way is just creating an ad-hoc function to be called just when there is no data on your realm model ("MyModel", in this example), at first app launch:

let realm = try! Realm()
lazy var data: Results<MyModel> = { self.realm.objects(MyModel.self) }()    

func populateDefaultData() {
    
    if yourdata.count == 0 {
        
        try! realm.write() {
            let defaultData = ["Data1", "Data2", "Data3"]
            for data in defaultData {
                let newData = MyModel()
                newData.data = data
                realm.add(newData)
            }
        }
        data = realm.objects(MyModel.self)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    populateDefaultData()
}
arroyot24
  • 39
  • 1
  • 4