Realm updating model with a response?


#1

Hi guys,

So I have an API from which I am getting Cases for a user a typical response looks like this:

User {
	id = 37;
	name = name;
	email = [email protected];
	createdAt = 2018-08-10 13:59:34 +0000;
	updatedAt = 2019-03-11 12:36:09 +0000;
	token = (null);
	cases = List<Case> <0x282a30fc0> (
		[0] Case {
			id = 32;
			title = caseTitle;
			subject = (null);
			solicitor = (null);
			company = (null);
			createdAt = 2018-08-10 14:24:27 +0000;
			updatedAt = 2018-12-12 09:07:32 +0000;
			organisation = Organisation {
				id = 1;
				name = CompanyName;
				telephone = 14704870078;
				latitude = 51.53123;
				longitude = 31.94404;
			};
			updates = List<Update> <0x282a09830> (
			
			);
			processes = List<Process> <0x282a095f0> (
			
			);
		},
		[1] Case {
			id = 59;
			title = Sale of something;
			subject = (null);
			solicitor = (null);
			company = (null);
			createdAt = 2019-01-16 16:58:23 +0000;
			updatedAt = 2019-01-16 16:58:23 +0000;
			organisation = Organisation {
				id = 1;
				name = CompanyName;
				telephone = 14704870078;
				latitude = 51.53123;
				longitude = 31.94404;
			};
			updates = List<Update> <0x282a09b00> (
			
			);
			processes = List<Process> <0x282a09740> (
			
			);
		}
	);
}

Now what I need is to update the cases from the api with local realm database because sometimes they get out of sync. For example api returns cases with id 0,1,2,3 however realm in db has 0,1,2,3,4,5 so 4,5 need to be removed.

Currently I just add them like this

            case .success(let item):

                print(item)

                let realm = try! self.db.realm()
                let cases = realm.objects(Case.self)
                try? realm.safeWrite {
                    realm.add(item, update: true)
                }

                return item

where item is the above print.

User model:

class User: Object, ImmutableMappable {
  
  @objc dynamic var id: Int = 0
  @objc dynamic var name: String? = nil
  @objc dynamic var email: String? = nil
  @objc dynamic var createdAt: Date? = nil
  @objc dynamic var updatedAt: Date? = nil
  @objc dynamic var token: String? = nil
  
  static var currentUser: Int {
    get{
      let defaults = UserDefaults.standard
      return defaults.integer(forKey: "ICCurrentUserID")
    }
    set{
      let defaults = UserDefaults.standard
      defaults.set(newValue, forKey: "ICCurrentUserID")
      defaults.synchronize()
    }
  }
  
  var isCurrentUser: Bool {
    return self.id == User.currentUser
  }
  
  var cases = List<Case>()
  
  override static func primaryKey() -> String? {
    return "id"
  }
  
  convenience required init(map: Map) throws {
    self.init()
    self.id = try map.value("id")
    self.name = try? map.value("name")
    self.email = try map.value("email")
    self.createdAt = try? map.value("created_at", using: ISODateTransform())
    self.updatedAt = try? map.value("updated_at", using: ISODateTransform())
    
    self.token = try? map.value("token")
    
    if(map["cases"].isKeyPresent){
      self.cases = try map.value("cases", using: ListTransform<Case>())
    }
  }
  
  func mapping(map: Map) {
    id >>> map["id"]
    name >>> map["name"]
    email >>> map["email"]
    createdAt >>> (map["created_at"], using: ISODateTransform())
    updatedAt >>> (map["updated_at"], using: ISODateTransform())
    cases >>> (map["cases"], ListTransform<Case>())
  }
}

Cases model:

class Case: Object, ImmutableMappable {
  
  @objc dynamic var id: Int = 0
  @objc dynamic var title: String? = nil
  @objc dynamic var subject: String? = nil
  @objc dynamic var solicitor: String? = nil
  @objc dynamic var company: String? = nil
  @objc dynamic var createdAt: Date? = nil
  @objc dynamic var updatedAt: Date? = nil
  
  @objc dynamic var organisation: Organisation? = nil
  
  var updates = List<Update>()
  var processes = List<Process>()
  
  static var selectedCase: Int {
    get{
      let defaults = UserDefaults.standard
      return defaults.integer(forKey: "ICSelectedCaseID")
    }
    set{
      let defaults = UserDefaults.standard
      defaults.set(newValue, forKey: "ICSelectedCaseID")
      defaults.synchronize()
    }
  }
  
  override static func primaryKey() -> String? {
    return "id"
  }
  
  convenience required init(map: Map) throws {
    self.init()
    self.id = try map.value("id")
    self.title = try map.value("title")
    self.createdAt = try? map.value("created_at", using: ISODateTransform())
    self.updatedAt = try? map.value("updated_at", using: ISODateTransform())
    
    self.organisation = try? map.value("organisation")
    
    if(map["updates"].isKeyPresent){ // checks if present before mapping
      self.updates = try map.value("updates", using: ListTransform<Update>())
    }
    
    if(map["processes"].isKeyPresent){ // checks if present before mapping
      self.processes = try map.value("processes", using: ListTransform<Process>())
    }
  }
  
  func mapping(map: Map) {
    id >>> map["id"]
    title >>> map["title"]
    createdAt >>> (map["created_at"], using: ISODateTransform())
    updatedAt >>> (map["updated_at"], using: ISODateTransform())
    updates >>> (map["updates"], ListTransform<Update>())
    processes >>> (map["processes"], ListTransform<Process>())
  }
}