matt.writes.code matt.writes.code - 2 years ago 142
Swift Question

Nested Arrays throwing error in realm.create(value: JSON) for Swift

I'm using Realm in my Swift project and have a rather long JSON file with a couple of nested properties. I'm aware that in order for Realm to use this serialized JSON data directly, the properties need to match exactly (

But because Realm Lists need to have an Object instead of a String, I have to use something like List with Requirement being a Realm Object that holds a single String called 'value'.

When I run this code:

try! realm.write {
let json = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let exhibit = Exhibit(value: json) = "1"
realm.add(exhibit, update: true)

I get this error message:
*** Terminating app due to uncaught exception 'RLMException', reason: 'req1' to initialize object of type 'Requirements': missing key 'value''

Here's a shortened version of the JSON I'm feeding in there:

"exhibit_name": "test1",
"requirements": [
"geofence": {
"latitude": 36.40599779999999,
"longitude": -105.57696279999999,
"radius": 500

And my Realm model classes are this:

class Exhibit: Object {

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

dynamic var id = "0" //primary key
dynamic var exhibit_name: String = ""
let requirements = List<Requirements>()
dynamic var geofence: Geofence?


class Geofence: Object {
dynamic var latitude: Float = 0.0
dynamic var longitude: Float = 0.0
dynamic var radius: Float = 0.0

class Requirements: Object {
dynamic var value = ""

I find it interesting that I'm not getting any errors for the Geofence property, since that's a dictionary.

How do I set up the Requirements model to make this work properly?

Answer Source

Unfortunately you can't just setup your Requirements model in a different way, which would allow you to directly map your JSON to Realm objects.

The init(value: AnyObject) initializer expects either a dictionary, where the keys are the names of your object properties, or an array, where the property values are ordered in the same like they are defined in your object model. This initializer is recursively called for related objects.

So to make that work, you will need to transform your JSON, so that you nest the string values into either dictionaries or arrays. In your specific case you could achieve that like seen below:

var jsonDict = json as! [String : AnyObject]
jsonDict["requirements"] = jsonDict["requirements"].map { ["value": $0] }
let exhibit = Exhibit(value: jsonDict)

Side Note

I'd recommend using singular names for your Realm model object classes (here Requirement instead Requirements) as each object just represent a single entity, even if you use them only in to-many relationships.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download