Search code examples
swiftrealm

Error while creating realm object in swift


import UIKit
import Realm
import RealmSwift

class Employee: Object {
    dynamic var name = ""
    dynamic var salary = 0
}
class Emp: Object{
    dynamic var name = ""
    dynamic var salary = ""
}

class RealMEx: UIViewController,UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var txt1: UITextField!
    @IBOutlet weak var txt2: UITextField!

    @IBOutlet weak var tblView: UITableView!

    var dataArry = [[String: Any]]()

    @IBAction func Submit(_ sender: UIButton) {
        let emp = Employee()
        emp.name = txt1.text!
        emp.salary = Int(txt2.text!)!

        let realm = try! Realm()

        try! realm.write {
            realm.deleteAll()
            realm.add(emp)
        }

        let data = realm.objects(Employee.self)

        for i in Array(data){
            let d = ["name":i["name"]!,"salary": i["salary"]!]
            dataArry.append(d as [String : Any])
        }
        print (Array(data))
        tblView.reloadData()
    }   

    override func viewDidLoad() {
        super.viewDidLoad()
        tblView.delegate = self
        tblView.dataSource = self
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArry.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)as! RealMTableCell
        cell.lbl.text = dataArry[indexPath.row]["name"] as? String
        cell.sallbl.text = dataArry[indexPath.row]["salary"] as? String
        return cell
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

I'm trying to create simple realm object to store and retrieve data so firstly I have written this code, firstly I took two different arrays to store my data but later I took associative array for that. But using associative array I can't print my "salary" in table view. So I took another class named "Emp" and run my code but after that it shows me this Error.

2017-09-25 10:54:07.218441+0530 NewLogin[2264:51915] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /Users/admin/Library/Developer/CoreSimulator/Devices/9F794470-A0F6-4D8F-8A4C-9CBF6852EE71/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles

2017-09-25 10:54:07.239924+0530 NewLogin[2264:51915] [MC] Reading from private effective user settings.

2017-09-25 10:54:18.146 NewLogin[2264:52118] Version 2.10.1 of Realm is now available: https://github.com/realm/realm-cocoa/blob/v2.10.1/CHANGELOG.md

fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=10 "Migration is required due to the following errors: - Property 'Employee.salary' has been changed from 'int' to 'string'." UserInfo={NSLocalizedDescription=Migration is required due to the following errors: - Property 'Employee.salary' has been changed from 'int' to 'string'., Error Code=10}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-802.0.53/src/swift/stdlib/public/core/ErrorType.swift, line 182


Solution

  • You need to define a migration block and perform a migration due to the fact that you have changed one of your Realm model classes. You don't actually need to do anything in the migration block, Realm can handle the migration itself, you just need to increase your schema version by 1.

    In AppDelegate.swift, define the migration inside the didFinishLaunchingWithOptions function:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        let config = Realm.Configuration(
            // Set the new schema version. This must be greater than the previously used
            // version (if you've never set a schema version before, the version is 0).
            schemaVersion: 1,
            // Set the block which will be called automatically when opening a Realm with
            // a schema version lower than the one set above
            migrationBlock: { migration, oldSchemaVersion in
                // We haven’t migrated anything yet, so oldSchemaVersion == 0
                if (oldSchemaVersion < 1) {
                    // Nothing to do!
                    // Realm will automatically detect new properties and removed properties
                    // And will update the schema on disk automatically
                }
        })
    
        // Tell Realm to use this new configuration object for the default Realm
        Realm.Configuration.defaultConfiguration = config
    
        // Now that we've told Realm how to handle the schema change, opening the file
        // will automatically perform the migration
        let realm = try! Realm()
        return true
    }
    

    The code is copied from the official documentation of Realm.