Swift SDK Generated Schema Uses Generics(?) Not Standard Data Types

I have an existing set of Atlas collections for the starting point of my intended app. I have been able to mock this up initially using PHP & Web hosting, pulling this data. However, I would like to convert it to a mobile app instead, and further expand on the functionality.

Having created a new Realm app, selecting the Schema tab, choosing my collection and then auto-generating the Schema from the existing collection. Now I go to the Build section > SDKs > Realm Object Models and choose Swift (not SwiftUI, I am a novice iOS dev, don’t know this newer framework and just starting with Realm & Atlas!), the resulting class definition is filled with what looks like Swift generics, again a subject I know little about in my dev experience. All the other languages seem to show standard data types. Indeed ALL the tutorials and videos published by MongoDB themselves or others for Swift use standard data types.

import Foundation
import RealmSwift

class scoreTest: Object {
    @objc dynamic var _id: ObjectId? = nil

    @objc dynamic var compId: ObjectId? = nil

    let gross = RealmProperty<Int?>()

    let holeNo = RealmProperty<Int?>()

    let nett = RealmProperty<Int?>()

    let par = RealmProperty<Int?>()

    @objc dynamic var playerId: ObjectId? = nil

    let pointsGross = RealmProperty<Int?>()

    let pointsNett = RealmProperty<Int?>()

    let roundNo = RealmProperty<Int?>()

    let si = RealmProperty<Int?>()

    let strokes = RealmProperty<Int?>()
    override static func primaryKey() -> String? {
        return "_id"
    }
}

Why is this happening? Can I simply define my Swift classes in Xcode with standard data types and replace this syntax?

I am trying to manually create the “backend” through the Atlas & Realm web UI’s, not just importing code repos, as the data already exists and I am trying to apply it to this, rather than importing a new project from published tutorials. This is actually difficult, as none of the tutorials have a video or step-by-step processes for completing these tasks & configs.

Hi @Dan_Burt ,

From the documentation:

A RealmProperty instance represents a polymorphic value for supported types.

This allows to support the dynamic nature of Realm fields with the concept of Optional in Swift, that’s necessary to have the automatic mapping to the DB when you write new data updating the fields.

You get the Generics representation when you have a non-required field in your document for one of the basic types (Int, Double, …). If you add the field to the required section of the schema the fields, they’ll be available to Swift as the basic types, but won’t be Optional.

For example, having in your schema

required: […, gross, holeNo, nett, …]

would produce

    @objc dynamic var gross: Int = 0
    @objc dynamic var holeNo: Int = 0
    @objc dynamic var nett: Int = 0

Thanks @Paolo_Manna

I presume this means all published tutorials are showing non-Optional schema designs?

Is either schema pattern preferred? I know Swift makes a lot of Optional use-case. But equally, if I know my app or backend needs a certain structure, I should be assured that it will be there…

The RealmProperty only applies to basic (i.e. non-object) types, so you can still have Optional Swift objects like String?, ObjectId?, … without any special syntax, apart from the @objc dynamic attributes.

If you set the fields as required, the Data Model tool will initialise them at a standard value, so for Realm objects created inside your app there should be no problem, and the Swift compiler will prevent you to assign nil: if documents are coming into MongoDB from somewhere else, though, you’ll need some logic to sanitise them, or they’ll generate an error and won’t be synched to your client app.

Super good info from Paolo. Let me also add with an answer of YES, you can replace that syntax.

Suppose your object has thee managed properties; a String, Bool and Decimal128 for currency, and then a computed Swift property which is not managed. Here’s a perfectly legit (and simple) example

class scoreTest: Object {
    @objc dynamic var objectId = ObjectId.generate()
    @objc dynamic var _partitionKey =  "" //used when sync'ing
    @objc dynamic var my_string = ""
    @objc dynamic var my_book = false
    @objc private dynamic var amount: Decimal128 = 0.0 //managed & backs the computed_amount
    var computed_amount: Decimal128 { //use this to get the account balance
       get {
          return self.amount
       }
       set {
          self.amount = newValue * 5
      }
   }

There doesn’t seem much documentation - @Paolo_Manna, where is the reference you quote?

I have searched for “RealmProperty” on the documentation site and only 1 page was returned. This page showed the “@Persisted” syntax was only introduced after v10.10+, and replaces the previous syntaxes (plural - “@objc dynamic”, “RealmProperty”, etc)?

“RealmProperty” isn’t used on the any of the published tutorials.

@Jay , thanks for your input as well.

In my first attempts to try this out and connect between iOS app and Atlas / Realm, I think it seems simpler (to my mind!) to use “@objc dynamic”, or even “@Persisted”, as I would expect these values to be set within my model / data / document structure. Sure I’ll return when next stuck!!!

I would highly recommend using @Persisted over @objc dynamic at this point. It is much simpler and more intuitive.

@Jason_Flax

Yes, absolutely correct - if you are getting started, please use @Persisted. Sorry for my old-school example.

We are unfortunately stuck with an older SDK Version so it’s just kind of habit to use the ‘classic’ @objc dynamic. Updating objects from older to newer SDK’s has been a slow process.

@Dan_Burt
Back in the day there when we wanted to store numbers, we used RealmOptional. That was superseded by RealmProperty which has now changed to @Persisted with the optional tag ? on the type

@Persisted var value: Int?

which has a greatly expanded its capability and made it more uniform.

See Supported Property Types and you can click the Swift and Swift pre-10.10.0 tabs to see the comparison.

Sometimes the code samples and/or documentation lags a bit behind the release notes so you (I) have to bounce back and forth between those and the git code.

Oh, and I just noticed your question states

Swift SDK Generated Schema Uses Generics(?)

To be clear, a question mark ? is not a generic, it’s an optional - you probably knew that but just wanted to add that clarity. So this RealmProperty<Int?>() is (was) an optional Int meaning it may contain a value… or may not contain a value.