Recipe: Convert a local Realm to a synced Realm

Author: Ian Ward
Language: Objective-C
Date: September 1, 2017

As your application grows to take advantage of more Realm features, you may add synchronization backed by the Realm Object Server—and this may require converting a locally-stored Realm file to a synchronized Realm. While the Realm Platform doesn’t offer an automatic solution to this, it doesn’t require a lot of code to accomplish. This recipe is for a small Objective-C application to perform this task; the code could be easily integrated into an existing application.

AppDelegate.h

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

AppDelegate.m

#import "AppDelegate.h"

@import Realm;
@import Realm.Dynamic;
@import Realm.Private;

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSString *sourceFilePath = [[NSBundle mainBundle] pathForResource:@"fieldFlow" ofType:@"realm"];

    RLMRealmConfiguration *configuration = [[RLMRealmConfiguration alloc] init];
    configuration.fileURL = [NSURL URLWithString:sourceFilePath];
    configuration.dynamic = true;
    configuration.readOnly = YES;

    RLMRealm *localRealm = [RLMRealm realmWithConfiguration:configuration error:nil];

    RLMSyncCredentials *creds = [RLMSyncCredentials credentialsWithUsername:@"admin@realm.io" password:@"password" register:NO];
    [RLMSyncUser logInWithCredentials:creds authServerURL:[NSURL URLWithString:@"http://localhost:9080"] onCompletion:^(RLMSyncUser *syncUser, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self copyToSyncRealmWithRealm: localRealm user:syncUser];
        });
    }];

    return YES;
}

- (void)copyToSyncRealmWithRealm:(RLMRealm *)realm user:(RLMSyncUser *)user
{
    RLMRealmConfiguration *syncConfig = [[RLMRealmConfiguration alloc] init];
    syncConfig.syncConfiguration = [[RLMSyncConfiguration alloc] initWithUser:user realmURL:[NSURL URLWithString:@"realm://localhost:9080/~/fieldRow"]];
    syncConfig.customSchema = [realm.schema copy];

    RLMRealm *syncRealm = [RLMRealm realmWithConfiguration:syncConfig error:nil];
    syncRealm.schema = syncConfig.customSchema;

    [syncRealm transactionWithBlock:^{
        NSArray *objectSchema = syncConfig.customSchema.objectSchema;
        for (RLMObjectSchema *schema in objectSchema) {
            RLMResults *allObjects = [realm allObjects:schema.className];
            for (RLMObject *object in allObjects) {
                RLMCreateObjectInRealmWithValue(syncRealm, schema.className, object, true);
            }
        }
    }];
}

@end