Search code examples
swiftrealm

swift Lost data from the realm database in another country


I use the realm database for my application (to-do list), everything works fine, BUT once I flew to another country and noticed that the records in the database are empty (the application gives out an empty list), upon arrival back to my country everything returned to normal ... Now I am again in a different country and the situation repeats again (database is empty), for some reason the database gives an empty list result, can you please explain why this is happening and how to fix that?

Output example

var dbToDoList = DBrealmToDoList()
var arrayToDoList: Results<RealmToDoList> {
    get {
        return dbToDoList.getArray()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()    
    let realm = try! Realm()
    dbToDoList.realm = realm

    let current = arrayToDoList.filter { (_todo) -> Bool in
        return _todo.date == date
    }.first
    self.selectedDate = date
    if current != nil {
        self.selectedLists = current?.lists
        self.selectedListsSorted =     self.selectedLists?.sorted(by: { (val, val2) -> Bool in
            return (!val.value && val2.value)
            })
    }
}

And then in tableView I display the data from the selectedListsSorted

// MARK: UITableView
extension ToDoListViewController : UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return  selectedListsSorted?.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ToDoListTableViewCell
        let current = selectedListsSorted?[indexPath.row]
        cell.nameLabel.text = current?.key
        cell.checkBox.isSelected = current?.value ?? false
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 90
    }
 
}

Here is a class for working with db

class RealmToDoList: Object {
    @objc private dynamic var dictionaryData: Data?
    var lists: [String: Bool] {
        get {
            guard let dictionaryData = dictionaryData else {
                return [String: Bool]()
            }
            do {
                let dict = try JSONSerialization.jsonObject(with: dictionaryData, options: []) as? [String: Bool]
                return dict!
            } catch {
                return [String: Bool]()
            }
        }

        set {
            do {
                let data = try JSONSerialization.data(withJSONObject: newValue, options: [])
                dictionaryData = data
            } catch {
                dictionaryData = nil
            }
        }
    }
    
    @objc dynamic var date : Date?
}

class DBrealmToDoList {
    var realm: Realm!
    
    func write(_ data: RealmToDoList) throws -> Bool {
        var result = false
        
        if (realm != nil) {
            try! realm.write {
                realm.add(data)
                result = true
            }
            return result
        } else {
            throw RuntimeError.NoRealmSet
        }
        
    }
    
    func getArray() -> Results<RealmToDoList> {
        return realm.objects(RealmToDoList.self)
    }
    
    func delete(_ data: RealmToDoList) throws -> Bool {
        var result = false
        if (realm != nil) {
            try! self.realm.write {
                self.realm.delete(data)
                result = true
            }
            return result
        } else {
            throw RuntimeError.NoRealmSet
        }
    }
    
    func update(ofType:Object,value:AnyObject,key:String)->Bool{
        do {
            let realm = try Realm()
            try  realm.write {
                ofType.setValue(value, forKeyPath: key)
            }
            
            return true
        }catch let error as NSError {
            fatalError(error.localizedDescription)
        }
        
        
    }
    
    func filter(id:Int) -> RealmToDoList? {
        let match = realm.objects(RealmToDoList.self).filter("id == %@",id).first
        return match
    }
  
    func newToDoList(date : Date?,lists: [String: Bool]) -> RealmToDoList{
        let pill = RealmToDoList()
        pill.date = date
        pill.lists = lists
        return pill
    }
}

I doubt that the matter is in the database, but I cannot understand what it is, because I don’t do a filter by country, etc.


Solution

  • The issue is the date because the date will change based on time zone and if you're selecting today's date/time in one time zone, it will be different that's what's in the database. So if a filter is based on this date

    @objc dynamic var date : Date?
    

    then that date will be "today" for whatever time zone you're in but a "today" date that was created this morning in a different time zone will not return the current time zones date.

    e.g. if you create a new date/time it will be today in this timezone but could be yesterday in a different time zone.