Vadim Nikolaev
Vadim Nikolaev

Reputation: 2132

Realm from JSON in async in background

I'd like to work to write Realm from JSON in async in background, but I can't understand why my code isn't work as must.

override func viewDidLoad() {
    super.viewDidLoad()

    myFunc()

}

and myFunc():

func myFunc() {

        let realm = try! Realm()

        // get file JSON from local device and write data from it to RealmDB
        if realm.isEmpty {

            //local file JSON
            let file = Bundle.main.path(forResource: "file", ofType: "json")!
            let url = URL(fileURLWithPath: file)
            let jsonData = NSData(contentsOf: url)!

            //Serialization JSON
            let json = try! JSONSerialization.jsonObject(with: jsonData as Data, options: [])


            DispatchQueue.main.async {

            realm.beginWrite()

            //Create data from JSON to our objects
            realm.create(DataRoot.self, value: json, update: true)

            try! realm.commitWrite()

            }
        }
    }

DB is creating, but next step (as I see) is in error:

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return (transport.filter("id == 1").first?.routes.count)!
    }

So, I'd like to wait full writing DB in background (show progress view, for example) and go next step.

Upvotes: 2

Views: 432

Answers (2)

jpsim
jpsim

Reputation: 14409

To generally answer your question: the high level Realm feature you want to be using here is notifications.

You should be architecting your app in such a way that the data you want to use to back a view controller can be represented in a Realm query or notification, so that when the underlying data for a view or controller changes, you can perform the relevant view update actions.

There are some other problems with your code, such as potentially accessing a Realm instance from a different thread than the one on which it was created. I suggest you read more about this in Realm's Threading documentation.

Upvotes: 1

jatin kumar malana
jatin kumar malana

Reputation: 321

You have to check for optional in numberOfRows Method and do it like this

    func myFunc() {
        let queue1 = DispatchQueue(label: "com.appname.queue")
        queue1.async {
            let realm = try! Realm()
            // get file JSON from local device and write data from it to RealmDB
            if realm.isEmpty {

                //local file JSON
                let file = Bundle.main.path(forResource: "file", ofType: "json")!
                let url = URL(fileURLWithPath: file)
                let jsonData = NSData(contentsOf: url)!

                //Serialization JSON
                let json = try! JSONSerialization.jsonObject(with: jsonData as Data, options: [])
                realm.beginWrite()

                //Create data from JSON to our objects
                realm.create(DataRoot.self, value: json, update: true)

                try! realm.commitWrite()

                DispatchQueue.main.async {

                    self.tableview.reloadData()

                }

            }
        }
    }


    override func tableView(_ tableView: UITableView,     numberOfRowsInSection section: Int) -> Int {
        if let routes = transport.filter("id == 1").first?.routes {
            return routes.count
        } 
            return 0
    }

Upvotes: 1

Related Questions