22

How can I declare an array of integers inside RLMObject?

Like :

dynamic var key:[Int]?

Gives the following error :

Terminating app due to uncaught exception 'RLMException', reason: ''NSArray' is not supported as an RLMObject property. All properties must be primitives, NSString, NSDate, NSData, RLMArray, or subclasses of RLMObject. See https://realm.io/docs/objc/latest/api/Classes/RLMObject.html for more information.'
Daniel Krom
  • 9,751
  • 3
  • 43
  • 44
Vinicius Albino
  • 743
  • 2
  • 8
  • 21

4 Answers4

44

Lists of primitives are not supported yet unfortunately. There is issue #1120 to track adding support for that. You'll find there some ideas how you can workaround that currently.

The easiest workaround is create a object to hold int values. Then the model to have a List of the object.

class Foo: Object {
    let integerList = List<IntObject>() // Workaround
}

class IntObject: Object {
    dynamic var value = 0
}
kishikawa katsumi
  • 10,418
  • 1
  • 41
  • 53
8

Fortunately arrays of primitive types are now supported in Realm 3.0 and above. (Oct 31 2017)

You can now store primitive types or their nullable counterparts (more specifically: booleans, integer and floating-point number types, strings, dates, and data) directly within RLMArrays or Lists. If you want to define a list of such primitive values you no longer need to define cumbersome single-field wrapper objects. Instead, you can just store the primitive values themselves!

class MyObject : Object {
    @objc dynamic var myString: String = ""
    let myIntArray = List<Int>()
}

Source: https://realm.io/blog/realm-cocoa-reaches-3-0/

Philipp Otto
  • 4,061
  • 2
  • 32
  • 49
  • For what it's worth, if you choose to use a `List` of Primitives like this, you won't be able to filter `Results` using the `@count` predicate style as it's not supported on `List`s of Primitives . That said, wrapping them in Realm objects has it's own downsides... From https://docs.mongodb.com/realm/sdk/ios/examples/filter-data/: "Evaluates to the number of objects in the given collection. This is currently only supported on to-many relationship collections and not on lists of primitives. In order to use `@count` on a list of primitives, consider wrapping the primitives in a Realm object." – Ohifriend Aug 11 '21 at 00:00
5

The accepted offer is very costly in term of memory. You might get a List of very big "n" of objects.

It's not a matter of right and wrong but I think it's good to write here a different workaround.

Another approach:
I decided to use a single string to represent an Int array.

In my Realm class I defined a variable:

dynamic var arrInt: String? = nil

And use it very easily:

let arrToSave = [0, 1, 33, 12232, 394]
<MY_CUSTOM_REALM_CLASS>.arrInt = arrToSave.map { String(describing: $0) }.joined(separator: ",")

And the way back:

let strFetched = <MY_CUSTOM_REALM_CLASS>.arrInt 
let intArray = strFetched.components(separatedBy: ",").flatMap { Int($0) }

Will be happy to hear your feedback, as I think this approach is better.

MatanGold
  • 739
  • 10
  • 18
  • Why the down vote? I presented this answer as a proposal that worked for me, if you don't like this solution, please share your thoughts, don't just down vote. – MatanGold Feb 12 '17 at 01:42
  • Using `description` is a very, very bad idea. Use this: to: `let stringOfArray = arrToSave.map { String(describing: $0) }.joined(separator: ",")`. From: `let intArray = stringOfArray.components(separatedBy: ",").flatMap { Int($0) }` – basvk Mar 17 '17 at 07:25
1

As the error message states, you have to use RLMArray - or rather it's swift equivalent List.

See: Realm docs