A concise Mantle-like way of working with Realm and JSON.

Last update: May 14, 2022

Realm+JSON License MIT

Badge w/ Version Badge w/ Platform

A concise Mantle-like way of working with Realm and JSON.

Breaking Change

  • Method - deepCopy replaces the previous functionality of - shallowCopy, which no longer maintains an object's primary key
  • Updated to use native primary key support in Realm 0.85.0
  • Update your code to use methods -createOrUpdateInRealm:withJSONArray: or -createOrUpdateInRealm:withJSONDictionary:
  • You must wrap these methods in a write transaction (between [realm beginWriteTransaction]; and [realm commitWriteTransaction];)
  • These methods call -createOrUpdateInRealm:withObject: behind the scenes for performance.

Installation

Add the following to your CocoaPods Podfile

pod 'Realm+JSON', '~> 0.2'

or clone as a git submodule,

or just copy files in the Realm+JSON folder into your project.

Using Realm+JSON

Simply declare your model as normal:

typedef NS_ENUM(NSInteger, MCEpisodeType) {
    MCEpisodeTypeFree = 0,
    MCEpisodeTypePaid
};

@interface MCEpisode : RLMObject

@property NSInteger episodeID;
@property NSInteger episodeNumber;
@property MCEpisodeType episodeType;

@property NSString *title;
@property NSString *subtitle;
@property NSString *thumbnailURL;

@property NSDate *publishedDate;

@end

RLM_ARRAY_TYPE(MCEpisode)

Then pass the result of NSJSONSerialization or AFNetworking as follows:

  [MCEpisode createOrUpdateInRealm:[RLMRealm defaultRealm] withJSONArray:array];

or

  [MCEpisode createOrUpdateInRealm:[RLMRealm defaultRealm] withJSONDictionary:dictionary];

Use the -JSONDictionary method to get a JSON-ready dictionary for your network requests.

Configuration

You should specify the inbound and outbound JSON mapping on your RLMObject subclass like this:

+ (NSDictionary *)JSONInboundMappingDictionary {
  return @{
         @"episode.title": @"title",
         @"episode.description": @"subtitle",
         @"episode.id": @"episodeID",
         @"episode.episode_number": @"episodeNumber",
         @"episode.episode_type": @"episodeType",
         @"episode.thumbnail_url": @"thumbnailURL",
         @"episode.published_at": @"publishedDate",
  };
}

+ (NSDictionary *)JSONOutboundMappingDictionary {
  return @{
         @"title": @"title",
         @"subtitle": @"episode.description",
         @"episodeID": @"id",
         @"episodeNumber": @"episode.number",
         @"publishedDate": @"published_at",
  };
}

JSON preprocessing can be done by implementing jsonPreprocessing: static method:

- (NSDictionary *)jsonPreprocessing:(NSDictionary *)dictionary {
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:dictionary];
    dict[@"releaseCount"] = @(0);
    return dict.copy;
}

Leaving out either one of the above will result in a mapping that assumes camelCase for your properties which map to snake_case for the JSON equivalents.

As you can do with Mantle, you can specify NSValueTransformers for your properties:

+ (NSValueTransformer *)episodeTypeJSONTransformer {
  return [MCJSONValueTransformer valueTransformerWithMappingDictionary:@{
              @"free": @(MCEpisodeTypeFree),
              @"paid": @(MCEpisodeTypePaid)
      }];
}

Working with background threads

Realm requires that you use different RLMRealm objects when working across different threads. This means you shouldn't access the same RLMObject instances from different threads. To make this easier to work with, use - primaryKeyValue to retrieve the wrapped primary key value from an instance and query for it later using + objectInRealm:withPrimaryKeyValue:.

id primaryKeyValue = [episode primaryKeyValue];
dispatch_async(dispatch_get_main_queue(), ^{
    MCEpisode *episode = [MCEpisode objectInRealm:[RLMRealm defaultRealm] withPrimaryKeyValue:primaryKeyValue];

    // do something with episode here
});

Working with (temporary) copies (RLMObject+Copying)

If you need to display UI that may or may not change an object's properties, it is sometimes useful to work with an object not bound to a realm as a backing model object. When it is time to commit changes, the properties can be copied back to the stored model.

Methods - shallowCopy and - mergePropertiesFromObject: are provided. The later of which needs to be performed in a realm transaction.

#import <Realm+Copying.h>

MCEpisode *anotherEpisode = [episode shallowCopy];
anotherEpisode.title = @"New title";

// ...

[episode performInTransaction:^{
    [episode mergePropertiesFromObject:anotherEpisode];
}];

Additionally, method - deepCopy is provided. Unlike - shallowCopy, it maintains the object's primary key.

License

Realm+JSON is under the MIT license.

GitHub

https://github.com/matthewcheok/Realm-JSON
Comments
  • 1. createInRealm:withJSONArray return adds only

    The method createInRealm:withJSONArray should only return back an array of actual objects created.

    Normal flow would be to get back an array of JSON from http response, call createInRealm:withJSONArray then add the resulting array to an existing list for another model.

    Reviewed by zeroelink at 2014-08-31 14:24
  • 2. setObjectForKey: key cannot be nil

    Running the code below causes setObjectForKey: key cannot be nil in Swift. I'm not sure if I'm actually using this correctly or not, but I can't seem to get any of the category functionality working.

        var grp = GroupRLMObject()
        grp.name = "David Foster Wallace"
    
        // Get the default Realm
        let realm = RLMRealm.defaultRealm()
        // You only need to do this once (per thread)
    
        // Add to the Realm inside a transaction
        realm.beginWriteTransaction()
        realm.addObject(grp)
        realm.commitWriteTransaction()
    
        let results: NSDictionary = grp.JSONDictionary() as NSDictionary
    
    Reviewed by joeblau at 2014-12-08 03:51
  • 3. You need to update your realm requirement in Pod Specs.

    [!] Unable to satisfy the following requirements:

    • Realm required by Podfile
    • Realm (= 0.89.1) required by Podfile.lock
    • Realm (~> 0.85.0) required by Realm+JSON (0.2.0)
    Reviewed by kikolobo at 2014-12-27 01:11
  • 4. Realm-JSON doesn't work on a device

    The Realm+JSON0.2.3 build installed via CocoaPods project throws this error when attempting to run on a device.

    ld: library not found for -lc++
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    I'm not sure if this is tied to Realm or the Realm+JSON category. Just create a basic project, add pod 'Realm+JSON', '~> 0.2' to your Podfile and try to run on a device.

    Reviewed by joeblau at 2014-12-11 18:00
  • 5. An example NSValueTransformer to deal with json null values

    Suggested as an addition to your existing transformers.

    It'll just check if a value is NSNull and convert it to an empty string.

    // ---------------------------------------------
    @interface MCJSONNonNullStringTransformer : NSValueTransformer
    + (instancetype)valueTransformer;
    @end
    
    // ---------------------------------------------
    @implementation MCJSONNonNullStringTransformer
    
    + (instancetype)valueTransformer
    {
        return [[self alloc] init];
    }
    
    
    + (Class)transformedValueClass 
    {
        return [NSString class];
    }
    
    + (BOOL)allowsReverseTransformation 
    {
        return YES;
    }
    
    - (id)transformedValue:(id)value 
    {
    
        if(value && ![value isKindOfClass:[NSNull class]]) {
            return value;
        } else {
            return @"";
        }
    }
    
    - (id)reverseTransformedValue:(id)value 
    {
        return value;
    }
    
    @end
    
    Reviewed by johanforssell at 2014-10-01 12:17
  • 6. Realm 0.85 has primary key support and does not allow it to change

    This updates Realm-JSON to use Realm 0.85.

    As this Realm version supports primary keys I needed to add a control when adding data in -mc_setValuesFromJSONDictionary:inRealm: so that it's not trying to write new data for a primary key.

    I've not checked my solution thoroughly, but it's a suggestion as to what needs to be done to solve this problem.

    Reviewed by johanforssell at 2014-09-23 13:08
  • 7. 'Realm/Realm.h' file not found

    /Pods/Realm+JSON/Realm+JSON/RLMObject+JSON.h:9:9: 'Realm/Realm.h' file not found

    I have updated to 0.1.2 ad now it's not able to find that...

    any idea?

    Reviewed by alessandrostone at 2014-08-19 09:41
  • 8. Can't compile Realm.h with CocoaPods

    I'm using CocoaPods and I'm assuming (haven't checked the podspec) that Realm is not listed as a dependency or something but I can't compile using Realm-JSON because of the following line:

    #import <Realm/Realm.h>
    

    Throwing the following message:

    'Realm/Realm.h' file not found
    

    And here's my Podfile definition:

        pod 'Realm'
        pod 'Realm+JSON', '~> 0.1.2'
    
    Reviewed by esttorhe at 2014-08-13 18:04
  • 9. How to map object coming in array and not a dictionary?

    I'm getting an array of objects, like so:

    Image of data

    I have created a DayObject, how do I write JSONInboundMappingDictionary for it?

    Since the data is in arrays and not dictionary.

    Regards

    Reviewed by Voley at 2016-06-03 08:59
  • 10. Outbound mapping per-Object

    Sometimes back-end supports Array of only abstract objects (some properties are required not to be specified), unfortunately Realm does not support abstracted objects in RLMArray so JSONOutboundMapping per-Object helps to at least somewhat adopt to abstracted logic. Like:

    class Vehicle: RLMObject {
        dynamic var maxSpeed: CGFloat = 0
        dynamic var licensePlate = ""
    
        var JSONOutboundMappingDictionary: NSDictionary {
            var mapping = [
                "maxSpeed" : "maxSpeed"
            ]
            if !licensePlate.isEmpty {
               mapping["licensePlate"] = "licensePlate"
            }
            return mapping
        }
    }
    

    or so.

    Reviewed by viktorasl at 2015-10-19 14:26
  • 11. How to parse an array of string

    Does anyone know how to parse an array of string. Like this:

    "zoneInfo": {
        "tariffInfoLines": [
            "In this city you pay per minute."
        ]
    }
    

    We have a zoneInfo object that contains a tariffInfoLines array. This tariffInfoLines array contains strings. To store in Realm, i define RealmString object and store it in RLMArray

    @interface RealmString : RLMObject
    @property NSString *stringValue;
    @end
    @implementation RealmString
    @end
    
    RLM_ARRAY_TYPE(RealmString)
    
    @interface TariffInfo : RLMObject
    @property RLMArray<RealmString> *storedTariffInfoLines;
    @end
    

    But i dont know how to parse it from JSON using Realm-JSON. The application will crash if you try to. So i really need some help to solve this problem!

    Reviewed by tuantm2014 at 2015-09-28 16:07
  • 12. Use of undeclared identifier 'RLMPropertyTypeArray' error

    Hello! I have just update my pods and with the new version of Realm (3.0.0) this identifier is not available, so RLMObeject+Copying.m file is not compiling... any help?

    Reviewed by jcmartinac at 2017-10-19 08:45
  • 13. JSON to Model

    'RLMException', reason: 'Invalid value '0' for property 'imageIndex'

    Model :@property NSString *booksID; @property NSString *bookName; @property NSNumber *imageIndex;

    Reviewed by Iyongjie at 2017-04-17 10:54
  • 14. JSONDictionary Error

    The RLMArray class will be missed when only using subclass, to judge the string of class is necessary. Just as: [classString isEqualToString:@"RLMArray"]

    Reviewed by zlyunduan at 2016-08-12 09:05
  • 15. Transform object into integer

    Let's say my object has a property which is a RLMArray of another object. I want to map each object of this array into a single int (which is its id) in the resulting JSON. How would I do that? Is that possible?

    Something like:

    [object1, object2, object3] => [1, 2, 3]
    

    ... where 1 is the object1.identifier, 2 is the object2.identifier etc.

    Reviewed by dielsonsales at 2016-08-08 18:25
Related tags
Sample app to demonstrate data sharing between a WatchKit app and its main app using Realm
Sample app to demonstrate data sharing between a WatchKit app and its main app using Realm

#Done! A sample app demonstrating how to share data between an app an its Watch extension using Realm. You can read more about it here. ##Screenshot #

Apr 2, 2022
Realm is a mobile database: a replacement for Core Data & SQLite

Realm is a mobile database that runs directly inside phones, tablets or wearables. This repository holds the source code for the iOS, macOS, tvOS & wa

Aug 6, 2022
Unrealm is an extension on RealmCocoa, which enables Swift native types to be saved in Realm.
Unrealm is an extension on RealmCocoa, which enables Swift native types to be saved in Realm.

Unrealm enables you to easily store Swift native Classes, Structs and Enums into Realm . Stop inheriting from Object! Go for Protocol-Oriented program

Aug 3, 2022
iOS price list app using Firebase, Realm & more
iOS price list app using Firebase, Realm & more

how-much iOS app to record how much things cost using various data persistence implementations. The basic data unit is an item, a simple dictionary: {

Feb 7, 2022
A small todo list with realm integration

RealmToDo Project Setup Install CocoaPods Open project directory in terminal and run pod install command Open Workspace of project *.xcworkspace Examp

Aug 1, 2022
Turn your Swift data model into a working CRUD app.
Turn your Swift data model into a working CRUD app.

Model2App is a simple library that lets you quickly generate a CRUD iOS app based on just a data model defined in Swift. (CRUD - Create Read Update De

Jul 4, 2022
Discover recent and popular movies on iOS and Android
Discover recent and popular movies on iOS and Android

PopularMovies Description This application help users discover popular and recent movies using TMDb API. Android Installation Obtain an TMDb API Key.

Feb 10, 2022
Safe and easy wrappers for RealmSwift

RealmWrapper RealmWrapper is wrapper library for RealmSwift in realm-cocoa If you use RealmWrapper, you can easily use UI update through Notification

Jul 19, 2022
Face detection and recognition iOS app with OpenCV
Face detection and recognition iOS app with OpenCV

Facemotion Facemotion it's an iOS app, allowing you to find easily a contact by face recognition. Scan the face of a person, whether the contact is in

Jun 27, 2022
iOS and watchOS app for try! NYC
iOS and watchOS app for try! NYC

trySwiftApp try! Swift Conference App 2016 presentations You can find an overview of speakers and their presentations, including slides and video here

Feb 8, 2022
Argo is a library that lets you extract models from JSON or similar structures in a way that's concise, type-safe, and easy to extend
Argo is a library that lets you extract models from JSON or similar structures in a way that's concise, type-safe, and easy to extend

Argo is a library that lets you extract models from JSON or similar structures in a way that's concise, type-safe, and easy to extend. Using Argo

Jul 20, 2022
The perfect accessory for Mantle and AFNetworking.

Overcoat We are finding maintainers, contact @sodastsai :) Overcoat is a small but powerful library that makes creating REST clients simple and fun. I

Jul 5, 2022
Realm RxSwift - This application was written in order to use Realm, RxSwift frameworks in real example

Realm_RxSwift This simple app was written to introduce basic operations of some

Apr 7, 2022
A JSON parser with concise API written in Swift.
A JSON parser with concise API written in Swift.

A JSON parser with concise API written in Swift Maps JSON attributes to different Swift types with just two methods: map and mapArrayOfObjects. The li

Aug 13, 2018
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift

EVReflection General information At this moment the master branch is tested with Swift 4.2 and 5.0 beta If you want to continue using EVReflection in

Jun 16, 2022
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift

EVReflection General information At this moment the master branch is tested with Swift 4.2 and 5.0 beta If you want to continue using EVReflection in

Jun 16, 2022
SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way.
SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way.

What is SugarRecord? SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way. Than

Jul 29, 2022
MisterFusion is Swift DSL for AutoLayout. It is the extremely clear, but concise syntax, in addition, can be used in both Swift and Objective-C. Support Safe Area and Size Class.
MisterFusion is Swift DSL for AutoLayout. It is the extremely clear, but concise syntax, in addition, can be used in both Swift and Objective-C. Support Safe Area and Size Class.

MisterFusion MisterFusion makes more easier to use AutoLayout in Swift & Objective-C code. Features Simple And Concise Syntax Use in Swift and Objecti

Jun 29, 2022
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer]
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer]

Extremely Fast views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainabl

Aug 6, 2022