How do I use realm on swift to store array of objects?

Viewed 848

In an earlier question I was asking about how I would be about to store an instance of a class on a local database, and I was suggested to use realm as my method of storage. I've setup my realm and done the research, however, in my class, I have an array of objects and when I try to set the array of objects in to "@objc dynamic" inorder to store it into the realm file, it wouldn't allow be to do so, throwing the error "Property cannot be marked @objc because its type cannot be represented in Objective-C". I don't really understand what this mean or what can be represented in Objective-C".

//
//  MealPlan.swift
//  IA
//
//  Created by Ian Dong on 8/25/20.
//  Copyright © 2020 Ian Dong. All rights reserved.
//

import Foundation
import RealmSwift
class MealPlan: Object {
    
    @objc dynamic var ingerdientList: [IngerdientCost] = [];
    var k: Int = 0;
    var serving : Int
    @objc dynamic var cost : [IngerdientCost] = [];
    var name : String;
    
    init ( size: Int, name: String){
        self.serving = size;
        self.name = name;
    }
    func addIngerdient (newIngerdient: IngerdientCost){
        ingerdientList.insert(newIngerdient, at: k);
        k = k+1;
    }
    func removeINgerdient(theIngerdient: IngerdientCost)
    {
        var c: Int = 0;
        while theIngerdient.amount != ingerdientList[c].amount && c <= k
        {
            c=c+1;
        }
        ingerdientList.remove(at: c);
        k=k-1;
    }
    func getCost() -> Array<IngerdientCost>
    {
        var c: Int = 0;
        while c <= ingerdientList.count
        {
            cost[c].ingerdientName = ingerdientList[c].ingerdientName;
            cost[c].amount = ingerdientList[c].amount * Double(serving);
            c = c+1;
        }
        return cost;
    }
    func setServing( serv: Int)
    {
        self.serving = serv;
    }
}



//
//  Ingerdient cost .swift
//  IA
//
//  Created by Ian Dong on 8/25/20.
//  Copyright © 2020 Ian Dong. All rights reserved.
//

import Foundation
import RealmSwift

class IngerdientCost: Object{
    
    init(Name: Ingerdient, Amount: Double )
    {
        self.amount = Amount;
        self.ingerdientName = Name;
    }
    
    var ingerdientName: Ingerdient;
    var amount: Double;
    
}


1 Answers

In Realm, you need to use List instead of arrays for custom classes (like IngerdientCost). For List, you don't use @objc dynamic, and it needs to be declared as let.

class MealPlan: Object {
    
    let ingerdientList = List<IngerdientCost>() /// no @objc dynamic ! but you need to use let
    var k: Int = 0
    var serving : Int
    let cost = List<IngerdientCost>() /// also no @objc dynamic !
    var name : String

    ...

}

Then, IngerdientCost needs to conform to Object:

class IngerdientCost: Object {
    @objc dynamic var ingerdientName: Ingerdient? /// to-one relationships must be optional → https://realm.io/docs/swift/latest/#relationships
    @objc dynamic var amount = Double(0)
}

Most properties and methods of Array are available in List, like .count, and you can loop over it (for object in ingerdientList {}).

On a side note there's no reason to use ; at the end of each line.

Related