H. Tan
H. Tan

Reputation: 21

Using Realm in Swift with generics

I am new to programming and am having trouble trying to manage data in an iOS app using Realm with generics. To separate MVC model clearly I made three swift classes as below

ModelLocator.swift

import UIKit
import RealmSwift

class ModelLocator : NSObject {

    class var sharedInstance : ModelLocator {
        struct Singleton {
            static var instance = ModelLocator()
        }
        return Singleton.instance
    }

    var tasks = TaskModel<Object>()

    override init() {
        print("ModelLocator init!")
    }

    func getTask() -> TaskModel<Object> {
        return tasks
    }

    func setTask(array:TaskModel<Object>) -> TaskModel<Object> {
        tasks = array
        return tasks
    }

}

ModelData.swift

import UIKit
import RealmSwift

let realm = try! Realm()

class TaskModel <T: Object>: NSObject {

    var resources : Results<T>!

    func getResources() -> Results<T> {
        return resources
    }

    func fetchData(database: T) {
        self.resources = try! Realm().objects(database.dynamicType).sorted("date", ascending: false)
    }

    func saveTaskData(number : Int, item : T ){
        let taskData:TaskData = TaskData()
        try! realm.write {
            switch number {
            case 0:
                taskData.id = item as! Int
                break
            case 1:
                taskData.title = item as! String
                break
            default:
                break
            }
        }
    }

}

TaskData.swift

import RealmSwift

class TaskData: Object {

    dynamic var id = 0    
    dynamic var title = ""
    dynamic var category: Category?
    // category.id:Int, category.name:String, category.priority:Int
    dynamic var contents = "" 
    dynamic var date = NSDate()

    /* set id as primary */
    override static func primaryKey() -> String {
        return "id"
    }

}

and called it in ViewController.swift as below

ViewController

import UIKit
import RealmSwift

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tbView: UITableView!

    var taskModel: TaskModel<Object> = TaskModel()
    var taskArray: Results<TaskData>?
    var category: Category = Category()

    override func viewDidLoad() {
        super.viewDidLoad()

        let modelLocator = ModelLocator()
        taskModel = modelLocator.getTask()
        let database = "TaskData"
        taskArray = taskModel.fetchData(TaskData) // <- Where there is error in line  
        print(taskArray)

On Build, the line above shows an error saying

"cannot convert value of type'(TaskData).Type' (aka 'TaskData.Type') to expected argument type 'Object'"

I know that the type in left and right does not match, but can't figure out how to correct it. (The meaning aka is unfamiliar to me and googling it did not help me as well)

Can anyone tell me how I should fix this code?

Upvotes: 1

Views: 2615

Answers (1)

marius
marius

Reputation: 7806

TaskModel.fetchData expects an argument of type Object in that case, because you parametrized the class with that as type T.

You pass in instead a value of type TaskData.Type, which is the metatype / class value, instead of an actual instance.

What you want instead is that fetchData doesn't have an argument at all. You can get the results by calling realm.objects(T.self) instead.

Upvotes: 2

Related Questions