Search code examples
iosswiftuitableviewrealmrealm-mobile-platform

Realm Platform Data not loading into TableView with Storyboard- Swift 4


Hey guys so here is my problem, I have been following along in the Realm Platform todo list app, but I am customizing it for my needs as I develop. The project originally was built with out storyboards, but I want to use storyboards. I can't get the tableView to display the data form the realm platform. The data writes the add to the platform but doesn't pass through into the tableView. Any suggestions?

Thanks,

Cole.

Here's the code:

import UIKit
import RealmSwift
import SVProgressHUD
import SwipeCellKit

class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet var tableView: UITableView!
    @IBOutlet weak var quickNotes: UITextView!

    //Create our Realm File
    let realm = try! Realm(configuration: SyncConfiguration.automatic())
    var items: Results<Items>?
    var notificationToken: NotificationToken?
    var subscriptionToken: NotificationToken?
    var subscription: SyncSubscription<Items>!
    var notes: Results<Notes>?

    override func viewDidLoad() {
        super.viewDidLoad()



        //Load our Realm Object into the view

        tableView.rowHeight = 70.0
        tableView.delegate = self
        tableView.dataSource = self
        tableView.reloadData()
        loadCategory()
        subscription = items?.subscribe(named: "my-projects")

        subscriptionToken = subscription.observe(\.state, options: .initial) { state in
            if state == .complete {

            } else {
                print("Subscription State: \(state)")
            }
        }


        notificationToken = items?.observe { [weak self] (changes) in
            guard let tableView = self?.tableView else { return }
            switch changes {
            case .initial:
                // Results are now populated and can be accessed without blocking the UI
                tableView.reloadData()
            case .update(_, let deletions, let insertions, let modifications):
                // Query results have changed, so apply them to the UITableView
                tableView.beginUpdates()
                tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
                                     with: .automatic)
                tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
                                     with: .automatic)
                tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
                                     with: .automatic)
                tableView.endUpdates()
            case .error(let error):
                // An error occurred while opening the Realm file on the background worker thread
                fatalError("\(error)")
            }
        }
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "categoryCell", for: indexPath)

        cell.textLabel?.text = items?[indexPath.row].name ?? "There were no categories added"

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let item = items?[indexPath.row]
        let listItemsVC = CloudListViewController()
        listItemsVC.project = item
        performSegue(withIdentifier: "segueToCloudLists", sender: self)
        tableView.deselectRow(at: indexPath, animated: true)
    }

    //Add List Item to Database
    @IBAction func quickAdd(_ sender: UIBarButtonItem) {
        let alertController = UIAlertController(title: "Add New Project", message: "", preferredStyle: .alert)

        alertController.addAction(UIAlertAction(title: "Save", style: .default) { _ in
            let textField = alertController.textFields![0]
            let item = Items()
            item.name = textField.text ?? "Nothing was added"

            try! self.realm.write {
                self.realm.add(item)

                let user = self.realm.object(ofType: PermissionUser.self, forPrimaryKey: SyncUser.current!.identity!)!
                let permission = item.permissions.findOrCreate(forRole: user.role!)
                permission.canRead = true
                permission.canUpdate = true
                permission.canDelete = true
            }
        })
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        alertController.addTextField() { textField in
            textField.placeholder = "New Item Text"
        }
        self.present(alertController, animated: true, completion: nil)
    }
}

Solution

  • I suppose you are loading items in your loadCategory function (cannot tell for sure, since you left out the definition of that function).

    You need to call tableView.reloadData() after you retrieve the data into the data source structures (items in your case) and not before that.

    ...
    loadCategory()
    subscription = items?.subscribe(named: "my-projects")
    tableView.reloadData()
    ...