Search code examples
arraysswiftuitableviewpropertiesrealm

How to effectively load the properties string for all rows of data from realm into UILabels in a UITableView


Within my realm I have RealmClassA, with many rows of information that the user can successfully add to whilst running in simulator.

I am trying to read the data from realm (technical term Query?!) to display some of the data into a TableViewController within a customCell that houses many UILabels. The customCell is of type TableViewCell.

For examples sake I have included only some of the properties and labels.

I would like to display the data from propertyA column, into the UIlabel's in alphabetical order, alongside the other data in propertyB column for that row entry. See image below.

Rough design of what is currently on Storyboard and What I would like to display during app run

The TableViewController is;

import UIKit
import RealmSwift


class TableViewController: UITableViewController {
      
    let realm = try! Realm()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
        //After solving this question, this numberOfSections return will return the count of the number of unique strings that the propertyB column that RealmClassA houses. 
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
      
  return realm.objects(RealmClassA.self).count
        // this DOES return a number of cells that matches the number of entries (rows) in RealmClassA. 

    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCellID", for: indexPath)

    // this is where I have hit a brick wall and guidance is needed.        

        return cell
    }
}

The customCell is of type TableViewCell;

import UIKit
import RealmSwift

class TableViewCell: UITableViewCell {
    
    @IBOutlet weak var propertyAGoesHere: UILabel!
    @IBOutlet weak var propertyBGoesHere: UILabel!
    @IBOutlet weak var propertyCGoesHere: UILabel!
//etc.
    
    let realm = try! Realm()
    

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

I am able to count the number of entries in the Output using the following;

print("The number of RealmClassA records in memory is",realm.objects(RealmClassA.self).count)

It prints out The number of RealmClassA in memory is 10

When I attempt to print just the names of the stings in propertyA column;

    let allEntriesArray = allEntriesList.map{$0.PropertyA}
            
    print("Querying all propertyA entries in realm \(allEntriesArray)")

it prints out

Querying all propertyA entries in realm LazyMapSequence<Results<RealmClassA>, String>(_base: Results<RealmClassA> <0x7fd2f8cb4f20> (
    [0] RealmClassA {
        propertyA = Random Words for Filler
        propertyB = More Random words to fill the property information;
        //etc. 
    },
// this repeats for all entries in the RealmClassA. 

Help needed with

  1. HOW to effectively access the data from realm to display in the table view. I'm clearly nearly there, as I can display the correct number of cells for the number of entries in RealmClassA.

  2. Whether I have over complicated something along the line.

I have used the following sources as help to no avail.

https://www.youtube.com/watch?v=0WOd6GVPMb0

UITableView with Multiple Sections using Realm and Swift

Querying Realm to populate numberOfRowsInSection and cellForRowAt with Multiple Sections using Realm and Swift

How to access properties of an object returned from primary key query in Realm Swift

And I have scoured the Realm.io documentation here

https://academy.realm.io/posts/realm-list-new-superpowers-array-primitives/

https://realm.io/docs/swift/latest/#getting-started in the List section

https://realm.io/docs/swift/latest/api/Classes/List.html

update

Changing any instances of ‘PropertyA’ to ‘propertyA’ throughout.

Main question for clarity. How to display all data from one column in saved in realm, in an alphabetical order inside a tableview cells’ UILabels.

Apologies for the length of post, I see a lot of questions commented with people asking for all the information so I have done my utmost!

update 2

Removing unnecessary information for clarity after answer posted


Solution

  • Thanks to @Jay's help plus this website;
    https://www.ralfebert.de/ios-examples/uikit/uitableviewcontroller/custom-cells/, I found I was missing as! customCell from the end of the cellForRowAt func.

    Here is how it should look if anyone is looking at this further down the line.

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCellID", for: indexPath) as! customCell
    
            let itemsToDisplay = realm.objects(RealmClassA.self).sorted(byKeyPath: "propertyA")[indexPath.row]
            
            cell.propertyADisaplyLabel?.text = itemsToDisplay.propertyA
            cell.propertyBDisplayLabel?.text = itemsToDisplay.propertyB
            cell.propertyCDisplayLabel?.text = itemsToDisplay.propertyC
            
    
            return cell
        }
    

    EDIT

    Setting up a tableView dataSource on macOS - iOS is very similar. This sets up a dataSource with 10 objects. This example is really to show a proper use of the dataSource.

    class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
        
        var dataArray = [String]()
        
        @IBOutlet weak var myTableView: NSTableView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            for i in 0...9 {
                let s = "row_\(i)"
                self.dataArray.append(s)
            }
            
            self.myTableView.delegate = self
            self.myTableView.dataSource = self
            self.myTableView.reloadData()
        }
    
        func numberOfRows(in tableView: NSTableView) -> Int {
            return self.dataArray.count
        }
        
        func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
           let identifier = NSUserInterfaceItemIdentifier("MyCellView")
           guard let cell = tableView.makeView(withIdentifier: identifier, owner: self) as? NSTableCellView else {return nil}
        
           cell.textField?.stringValue = self.dataArray[row]
        }
    

    Note the NSTableCellView (Table Cell View) identifier is set to MyCellView.