Realm + Alamofire + Codable: Everything you need to play with data in IOS app

Realm

Why Realm so fast

Traditional ORM/Core Data/etc

Workflow:

  1. translate the request into a series of SQL
  2.  create a database connection (if it hasn’t already been created)
  3. send it to the disk, perform the query, read all the data from the rows that match the query
  4. bring all of that into memory (that’s the memory allocation)

zero‑copy architecture

The are two tricks I can see in realm to achieve Zero-Copy.

  1. Properties are accessors
    All dynamic properties in Realm Object classes are just accessors to some memory addresses. They don’t store values by themselves. (This is the reason why Realm Objects are auto-updating objects also)
  2. The database file is always memory‑mapped
    Realm accesses any offset in the file as if it were already in memory even though it’s not – it’s virtual memory

Why can’t Realm objects be passed across thread boundaries?

Since Realm is based upon a zero‑copy architecture, all objects are live and auto‑updating. If Realm allowed objects to be passed across threads, Realm would not be able to ensure data consistency because various threads could be attempting to change an object’s data at undetermined points in time then the data could become inconsistent.

Auto-Updating Objects & Queries

 

let puppies = realm.objects(Dog).filter("age == 2")
puppies.count // = 0 because no dogs have been added to the Realm yet


let myDog = Dog()
myDog.name = "Rex"
myDog.age = 1

try! realm.write {
realm.add(myDog)
}

puppies.count // = 1 updated in real-time

Getting Notified When Realm Data Changes

let stepCounter = StepCounter()
let realm = try! Realm()
try! realm.write {
    realm.add(stepCounter)
}
var token : NotificationToken?
token = stepCounter.observe { change in
    switch change {
    case .change(let properties):
        for property in properties {
            print (property.name)
        }
    case .error(let error):
        print("An error occurred: \(error)")
    case .deleted:
        print("The object was deleted.")
    }
}

Codable + Realm

enum UserProperty: String {
    case id, name, email
}
class User: Object, Codable {
   @objc dynamic var id:Int = 0
    @objc dynamic var name:String?
    @objc dynamic var email:String?
    private enum CodingKeys: String, CodingKey {
        case id, name, email = "mail"
    }
    override static func primaryKey() -> String? {
        return UserProperty.id.rawValue
    }
    //avoid realm storing properties
    override static func ignoredProperties() -> [String] {
        return [UserProperty.email]
  }
    //when type of data you received from server not match with 
    //type you declared
    required convenience init(from decoder: Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try Int(container.decode(String.self, forKey: .id))!
        name = try? container.decodeIfPresent(String.self, forKey: .name)
        email = try? container.decodeIfPresent(String.self, forKey: .email)
    }
}

Fetch data from server with Alamofire and store to Realm database

extension JSONDecoder {
    func decodeResponse<T: Decodable>(from response: DataResponse<Data>) -> T? {
        guard response.error == nil, let responseData = response.data else {
           return nil
        }
        do {
            let item = try decode(T.self, from: responseData)
            return item
        } catch {
            print(error)
            return nil
        }
    }
}


func fetchData(callback: @escaping (Bool)-> Void){
        Alamofire.request("url").responseData(completionHandler: {response in
            if let users :[User] = JSONDecoder().decodeResponse(from: response){
                let realm = try! Realm()
                try! realm.write {
                    realm.add(users, update: .all)
                }
            }
        })
    }

A nature, universe, science, music, love lover

Leave a Reply

Your email address will not be published. Required fields are marked *

Bitnami