How to get the name list on Realm database and display on my stimulator? - ios

Here I have a Realm Database which is have some data in it and I want to display it on my Stimulator but it turn out display some other thing. What's wrong in my code?
This is the data of my Realm Database and I also marked the data which I want to display it.
The stimulator which display something like this.
And here is my ViewController.swift code's.
import UIKit
import RealmSwift
class ViewController: UIViewController,UITableViewDataSource { //UITableViewDataSource
#IBOutlet weak var mytableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let realm = try! Realm()
let theItem = realm.objects(Item.self).filter("itemid >= 1")
return theItem.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let realm = try! Realm()
let theItem = realm.objects(Item.self).filter("itemid >= 1")
print(theItem)
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1")
//I suspect the problem is at here...
cell?.textLabel?.text = "\(theItem)"
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
class Category: Object {
#objc dynamic var name: String?
#objc dynamic var caid: Int = 0
}
class Item: Object {
#objc dynamic var name: String?
#objc dynamic var itemid: Int = 0
#objc dynamic var cateid: Int = 0
}

Your problem is that you need to get the string from the Item object. try something like
"\(theItem.name)".

func getNames() -> [String]{
let items = realm.objects(Item.self).filter("itemid >= 1").toArray(ofType: Item.self ) as [Item]
return items.map { $0.name }
}
extension Results {
func toArray<T>(ofType: T.Type) -> [T] {
var array = [T]()
for i in 0 ..< count {
if let result = self[i] as? T {
array.append(result)
}
}
return array
}
}

I found a way to display the data already. I just need to add indexPath.row in my code and it can handle the data already.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let realm = try! Realm()
let theItem = realm.objects(Item.self).filter("itemid >= 1")
//I only add below this indexpath
let cellData = theItem[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1")
//and change this part and it's done.
cell?.textLabel?.text = cellData.name
print(theItem)
return cell!
}

Related

Filtering query for Realm

I have a function which prints all the objects in my realm table to a table view. I would like to be able to filter these objects by their "muscle" property.
Here's my DB helper functions:
func getMusclesCount()-> Int {
let storedExercise = realm.objects(StoredExercise.self)
return storedExercise.count
}
//MARK:- getAllMuscelsNames
func getAllMusclesNames()-> [String] {
var musclesName = [String]()
let storedExercise = realm.objects(StoredExercise.self)
for exercise in storedExercise {
print("Muscle = \(exercise.muscle)")
musclesName.append(exercise.name)
}
return musclesName
}
Here's my Table View Controller class :
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return DBHelper.shared.getAllMusclesNames().count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
let muscle = DBHelper.shared.getAllMusclesNames()[indexPath.row]
cell.textLabel?.text = muscle
return cell
}
I've tried adding .Filter to 'let storedExercise' but I'm not sure how to set it up correctly. Any assitance would be greatly appreciated, thanks.
If your StoredExercise model looks like this
class StoredExercise: Object {
#objc dynamic var muscle = ""
}
then to get all of the exercises that are for the biceps, it's this
let bicepResults = realm.objects(StoredExercise.self).filter("muscle == 'biceps'")

How to Sort TableViewCells by date string

As shown below I want to sort my TableViewCells by the date. For this I have the time which is also called timestampName.
Right before I reload the data, I tried to sort it, but somehow this has no effect. It also throws me a warning, that I dont use the result of the sorted by. I understand this, but I dont know how to fix that.
import UIKit
import Firebase
class popularViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet var table: UITableView!
// var models = [PhotoPost]()
var texttt = [TextPost]()
override func viewDidLoad() {
super.viewDidLoad()
gettingPosts()
table.register(popularTableViewCell.nib(), forCellReuseIdentifier: popularTableViewCell.identifier)
table.register(featuredTableViewCell.nib(), forCellReuseIdentifier: featuredTableViewCell.identifier)
table.register(textTableViewCell.nib(), forCellReuseIdentifier: textTableViewCell.identifier)
table.delegate = self
table.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return texttt.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: self.texttt[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
func gettingPosts(){
let db = Firestore.firestore()
let postsRef = db.collection("posts")
postsRef.addSnapshotListener { (querySnapshot, error) in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added){
let data = diff.document.data()
let Name = data["username"] as! String
let text = data["description"] as! String
let likes = data["likes"] as! Int
let typ = data["postType"] as! Int
let pfp = data["profileImage"] as! String
let uid = data["uid"] as! String
let pic = data["picture"]
let time = data["time"] as! String
if typ == 0{ // Text post
let dasDing = TextPost(numberOfComments: 0, username: Name, timestampName: time, userImageName: pfp, textName: text)
self.texttt.append(dasDing)
self.texttt.sorted(by: { $0.timestampName < $1.timestampName }) //WARNING: Result of call to 'sorted(by:)' is unused
self.table.reloadData()
}
struct TextPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
}
Use sort instead of sorted. The sorted method returns a new sorted array, on the other hand, the sort method sorts the array on which it was called.
self.texttt.sort(by: { $0.timestampName < $1.timestampName })
This should also work, using sorted:
self.texttt = self.texttt.sorted(by: { $0.timestampName < $1.timestampName })

How to reload TableVIew Using Model NSObject Class with MVVM

I want to reload TableView without tableview.reloadData() method for that i have used MVVM structure so i have attach model class to storyboard and the issue is that my tableview is reload first and then i get all data how should i solved this issue please help me if any one have a solution !!
This is storyboard model attach
Model Code :-
class MovieModel: Decodable{
var artistName: String = ""
var trackName: String = ""
init(artistName: String, trackName: String){
self.artistName = artistName
self.trackName = trackName
}
}
class ResultModel: Decodable{
var results = [MovieModel]()
init(results: [MovieModel]) {
self.results = results
}
}
My ViewModel File code :-
class MovieViewModel: NSObject {
var artistName: String = ""
var trackName: String = ""
var movieModel: MovieModel?
var movieData = [MovieViewModel]()
override init() {
}
init(movie: MovieModel) {
self.artistName = movie.artistName
self.trackName = movie.trackName
}
func getData(){
Service.shareInstance.getAllMovieData { (movie, error) in
if error == nil{
self.movieData = movie?.map({return MovieViewModel(movie: $0)}) ?? []
print(self.movieData)
}else{
print("\(String(describing: error))")
}
}
}
func numberOfRow(section:Int) -> Int{
return movieData.count
}
func cellForRow(indexPath: IndexPath) -> MovieViewModel{
return self.movieData[indexPath.row]
}
}
My ViewController Code :-
class ViewController: UIViewController {
#IBOutlet var movieVM: MovieViewModel?
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.movieVM?.getData()
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return movieVM?.numberOfRow(section: section) ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let movie = movieVM?.cellForRow(indexPath: indexPath)
cell?.textLabel?.text = movie?.artistName
cell?.detailTextLabel?.text = movie?.trackName
return cell!
}
}
In my case i am not reload tableview all this is done using ModelClass ! Thank You !!

How to get the child from a parent in a parent child relationship for realm in swift

What i am trying to do is access a child when I have the parent in realm. In this example I have a simple table view that I want to populate with the child when accessing the parent. The part I am struggling with is trying to find the child when accessing the parent.
This is the viewController that i am trying to access the children:
import UIKit
import Realm
import RealmSwift
class OtherViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var otherTableView: UITableView!
var realm: Realm!
var realmedData = ""
var realmList: Results<Realmed> {
get {
return realm.objects(Realmed.self)
}
}
var realmTwoList: Results<RealmTwo> {
get {
return realm.objects(RealmTwo.self)
}
}
override func viewDidLoad() {
super.viewDidLoad()
realm = try! Realm()
self.otherTableView.delegate = self
self.otherTableView.dataSource = self
// Do any additional setup after loading the view.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var counted = realm.objects(RealmTwo.self).filter("realmLbl == %#", realmedData)
return counted.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "otherCell", for: indexPath) as! OtherTableViewCell
var celledItem = realm.objects(Realmed.self)
for item in celledItem {
for items in item.realmTwo {
cell.otherLbl.text = "\(items.spanish)"
}
}
return cell
}
}
this is another method I tried for the cell for row at:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "otherCell", for: indexPath) as! OtherTableViewCell
var celledItem = realm.objects(Realmed.self)
for item in celledItem {
for items in item.realmTwo {
cell.otherLbl.text = "\(items.spanish)"
}
}
return cell
}
this is the parent realm class:
import Foundation
import Realm
import RealmSwift
class Realmed: Object {
#objc dynamic var label = ""
#objc dynamic var romanNum = ""
#objc dynamic var txt = ""
let realmTwo = List<RealmTwo>()
override static func primaryKey() -> String {
return "label"
}
convenience init(label: String, romanNum: String, txt: String) {
self.init()
self.label = label
self.romanNum = romanNum
self.txt = txt
}
}
and this is the realm class for the child:
import Foundation
import UIKit
import Realm
import RealmSwift
class RealmTwo: Object {
#objc dynamic var realmLbl = String()
#objc dynamic var spanish = String()
#objc dynamic var french = String()
let realmed = LinkingObjects(fromType: Realmed.self, property: "realmTwo")
convenience init(realmLbl: String, spanish: String, french: String) {
self.init()
self.realmLbl = realmLbl
self.spanish = spanish
self.french = french
}
}
When I run this as is, the only thing that populates the tableview is the last value saved to realm.
In this example the children are the strings: "Uno" and "Un", and I want them both to populate the tableView, but the tableView is only populated by the last value in realm, in this case, "Un".
Through research I found out that it is because I am looping through the realm value to get the child. The problem with that is that the only way to get to the child is with the loop but then it can't populate a tableView. It seems like a lose-lose situation.
What I am curious about is how to access the child when you have a parent in realm so that I am able to populate a tableView.
If you need anything please ask. Thank you
i think I got something. I figured that what I needed was an array, and it seems that it is unwise to change List to an Array, so what i did was get the content from the List and put it in an array, since it is easier to put data in a tableview from an array.
This is the array that i created:
var realmArr = [String]()
and this is the cell for row at for the tableView:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "otherCell", for: indexPath) as! OtherTableViewCell
var celledItem = realm.objects(Realmed.self)
for item in celledItem {
for items in item.realmTwo {
self.realmArr.append(items.spanish)
}
}
cell.otherLbl.text = "\(realmArr[indexPath.row])"
return cell
}
I am not sure if this is okay, but it is the only thing that I can think of.
Thank you for all the help.
Let me address this at a high level with a few code snippets. The question is using Objects so let's take a more concrete example of Person and Dog. In this example we have a list of Person Objects each one owning one dog. So we have a single direction relationship
First we have a Person and Dog class
class DogClass: Object {
#objc dynamic var name: String = ""
}
class PersonClass: Object {
#objc dynamic var name: String = ""
#objc dynamic var dog: DogClass?
}
Here's a viewController class that contains a tableView of people
class peopleVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
var peopleResults: Results<PersonClass>!
override func viewDidLoad() {
super.viewDidLoad()
let realm = RealmService //or however you talk to your realm
self.tableView.delegate = self
self.tableView.dataSource = self
self.peopleResults = realm.objects(PersonClass.self) //loads Person objects
self.tableView.reloadData() //shows the list
}
and within that class, the tableView delegate methods that populate our tableview and handle a tap on a row
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return peopleResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: textCellIdentifier, for: indexPath as IndexPath)
let row = indexPath.row
let person = self.peopleResults[row]
cell.textLabel?.text = person.name
return cell
}
//when a row is tapped we need to determine the row, which will be included
// in the indexPath property with indexPath.row
// From there get the object from the dataSource array via it's row index
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = indexPath.row
let person = self.peopleResults[row]
let dog = person.dog
//at this point you have the dog object and you could print the name
print(dog.name)
//or pass it to a detail view via a segue etc
}

Convert JSON to a Array with struct

I am trying to make a IOS app that is a home automation thing. I am using TableViewCell to display information.
My problem is that I have no idea how to get JSON to an Array with struct because I have to have struct I think.
My JSON is:
[{"namea":"TV","statea":"up_tv"},{"namea":"test","statea":"test"}]
My code is:
struct cellData {
let nameLabel : String!
let stateLabel : String!
}
class Main: UITableViewController {
var array = [cellData]()
override func viewDidLoad() {
array = [cellData(nameLabel: "tv", stateLabel: "up_tv"),
cellData(nameLabel: "tv", stateLabel: "down_tv")]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("TableViewCell", owner: self, options: nil)?.first as! TableViewCell
cell.nameLabel.text = array[indexPath.row].nameLabel
cell.stateLabal.text = array[indexPath.row].stateLabel
return cell
}
You need jsonDecoder
struct cellData : Decodable {
let nameLabel : String
let stateLabel : String
enum CodingKeys:String,CodingKey {
case nameLabel = "namea"
case stateLabel = "statea"
}
}
//
let str = """
[{"namea":"TV","statea":"up_tv"},{"namea":"test","statea":"test"}]
"""
do {
let cellArr = try JSONDecoder().decode([cellData].self, from: str.data(using:.utf8)!)
print(cellArr) //// check this
} catch {
}
//
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "id") as TableViewCell
}

Resources