coreData only printing last entity (swift4) - ios

I am trying to call all of my entries of coreData .color. The problem is only 1 entry of coreData is being called to the label. I would like all of the entities of coreData to be printed on the label not just the latest one, which the code is currently doing.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
#IBOutlet var label: UILabel!
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.dataSource = self
if CDHandler.fetchObject() != nil {
users = CDHandler.fetchObject()!
tableView.reloadData()
}
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = users[indexPath.row].username
for c in users {
label.text = c.color
}
return cell
}
}

Actually your current loop sets the last item of the array to the label text , so Try this to append values together
for c in users {
label.text = "\((label.text)!)+\((c.color)!)"
}

Related

Getting a EXC_BAD_ACCESS when trying to initialize my custom Cell in TableViewController

My application fetches data from a mock API.
Using a custom cell, I display the names of authors on my landing page viewController.
When I click on a cell, it takes that author's book information to display on a 2nd TableViewController.
But even though the implementation is the same as for the landing page. My app freezes until I get a EXC_BAD_ACCESS error
It seems like it's stuck in an infinite loop, but without a proper error, it's hard to know why.
Infinite Loop?
I can get this to work without using a custom cell, but then I cannot display all the information I want (only book title or release date), so the data is there.
import UIKit
class BooksTableViewCell: UITableViewCell {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var pages: UILabel!
#IBOutlet weak var release: UILabel!
// #IBOutlet var coverImage: UIImageView!
static let cellIdentifier = "BooksTableViewCell"
//
override func awakeFromNib() {
super.awakeFromNib()
}
static func nib() -> UINib {
return UINib(nibName: "BooksTableViewCell", bundle: nil)
}
//MARK: configure
public func configure(with viewModel: BooksCellViewModel) {
name.text = viewModel.name
pages.text = String(viewModel.pages)
release.text = viewModel.release
// coverImage.image = viewModel.image
}
}
import UIKit
class BooksTableViewController: UITableViewController {
var books: [Book] = []
var authorName: String = ""
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(BooksTableViewCell.nib(), forCellReuseIdentifier: BooksTableViewCell.cellIdentifier)
tableView.delegate = self
tableView.dataSource = self
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return authorName
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return books.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("Hello1")
let cell = tableView.dequeueReusableCell(withIdentifier: BooksTableViewCell.cellIdentifier, for: indexPath) as! BooksTableViewCell
print("Hello2")
let model = books[indexPath.row]
cell.configure(with: BooksCellViewModel(name: model.title, pages: model.pages, release: model.releaseDate))
return cell
}
}
The landing page controller and cell is similar but works with no problems
import UIKit
class LandingTableViewController: UITableViewController {
let parser = DataAPI()
var authors = [Author]()
var books = [Book]()
var authorName = ""
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(AuthorTableViewCell.nib(), forCellReuseIdentifier: AuthorTableViewCell.cellIdentifier)
tableView.delegate = self
tableView.dataSource = self
parser.getData {
data in
self.authors = data
//Reload UI on Main thread:
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "List of Authors"
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return authors.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: AuthorTableViewCell.cellIdentifier, for: indexPath) as! AuthorTableViewCell
let model = authors[indexPath.row]
cell.configure(with: AuthorCellViewModel(name: model.authorName))
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
books = authors[indexPath.row].books
authorName = authors[indexPath.row].authorName
performSegue(withIdentifier: "Show Books", sender: nil)
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
if (segue.identifier == "Show Books") {
let showBooksViewController: BooksTableViewController = segue.destination as! BooksTableViewController
showBooksViewController.books = books
showBooksViewController.authorName = authorName
}
}
}
I was able to fix the issue by correctly naming my variables. I needed to be using releaseDate not release as per my model object.

How to Update UITableView With Swift?

I'm trying to populate a table view from a SQlite database. Tickets get printed in the console, but nothings shows up on the table view. What's the proper way to update and refresh? Here is my code. Thanks!
import UIKit
import SQLite
class TicketTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var tickets = [String]()
#IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let dm = DatabaseManager.shared
let db = dm.db!
do {
for row in try db.prepare(dm.tickets) {
let ticket = row[dm.pick]
tickets.append(ticket)
debugPrint(ticket)
}
table.reloadData()
} catch {}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tickets.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ticket")!
cell.detailTextLabel!.text = tickets[indexPath.row]
return cell
}
}
Dynamic table views needs to know their delegate and datasource. If you didn't set the delegate and datasource, you can add them programmatically in your viewDidLoad function. Like this:
override func viewDidLoad() {
super.viewDidLoad()
//Set delegate and datasource
table.delegate = self
table.dataSource = self
let dm = DatabaseManager.shared
let db = dm.db!
do {
for row in try db.prepare(dm.tickets) {
let ticket = row[dm.pick]
tickets.append(ticket)
debugPrint(ticket)
}
table.reloadData()
} catch {}
}

Referencing core data attribute from declared variable

I'm following a swift development course for beginners and am trying to make a very simple app that creates new tasks with an entered text once a button is pressed, but I am encountering a few errors that I can't seem to understand.
The errors happen in my ViewController and the editor tells me my Core Data Entity does not possess an attribute named "corename" while it very well does.
Here is a screenshot of the errors : 3 errors
And here is my code :
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var tasks : [Taskentity] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
//Get the data from Core data
getData()
//Reload the table view
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return tasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath : IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let task = tasks[indexPath.row]
if (task.isImportant == true){
cell.textLabel?.text = "😅 \(tasks.corename!)"
} else {
cell.textLabel?.text = tasks.corename!
}
return cell
}
func getData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
tasks = try context.fetch(Taskentity.fetchRequest())
} catch {
print("Fetching Data")
}
}
}
Tasks is a Array of Taskentities, you probably meant to access task.corename not tasks.corename
if (task.isImportant == true){
cell.textLabel?.text = "😅 \(task.corename!)"
} else {
cell.textLabel?.text = task.corename!
}
And for the TableViewDelegate problem, just make sure to implement all necessary funcs... You are missing 1:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}

Swift 3 pass the cell data A view to B view, with fun didSelectRowAt indexPath crash after select row

I want to pass the data A view to B view, it can build and show data in A view, but after I selected the cell, it crashed. And it shows the problem on the code.
vcTwo.selectedzones.zones = [selectedCity]
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
my code
The struct mode:
struct Location {
var city: String!
var zones = [String]()
}
var city = ["KHT", "TPAP", "TNNY"]
let kh = Location.init(city: "KHT", zones: ["sami", "zami", "zomi", "komi", "shini"])
let tpa = Location.init(city: "TPAP", zones: ["mid", "east", "anci", "zochi"])
let tnn = Location.init(city: "TNNY", zones: ["TN1","TN2", "TN3", "TN4", "TN5"])
Here is the A viewController code:
import UIKit
class FirstViewTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return city.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FirstCell
cell.firstLabel.text = city[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCity = city[indexPath.row]
let vcTwo = self.storyboard?.instantiateViewController(withIdentifier: "secondVC") as! secondViewController
vcTwo.selectedzones.zones = [selectedCity]
self.navigationController?.pushViewController(vcTwo, animated: true)
}
}
The B viewController:
import UIKit
class secondViewController: UITableViewController {
var selectedzones: Location!
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return selectedzones.zones.count
}
Is there any part wrong in the func didSelectRowAt indexPath?
here is the problem
vcTwo.selectedzones.zones = [selectedCity]
you need to init the selectedZone in first Controller
let kh = Location.init(city: "KHT", zones: ["sami", "zami", "zomi", "komi", "shini"])
vcTwo.selectedzones = kh
Try this
class secondViewController: UITableViewController {
var selectedzones = Location()
}
you are try to accesss zones but you have not allocate Location so it will crash.
Hope it will help you
Instead of Optional ! use Optional ?
class secondViewController: UITableViewController {
var selectedzones: Location?
NOT
class secondViewController: UITableViewController {
var selectedzones: Location!

Gets number of rows but doesn't print

I have a program written in Swift 3, that grabs JSON from a REST api and appends it to a table view.
Right now, I'm having troubles with getting it to print in my Tableview, but it does however understand my count function.
So, I guess my data is here, but it just doesn't return them correctly:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, HomeModelProtocal {
#IBOutlet weak var listTableView: UITableView!
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
}
var feedItems: NSArray = NSArray()
var selectedLocation : Parsexml = Parsexml()
override func viewDidLoad() {
super.viewDidLoad()
self.listTableView.delegate = self
self.listTableView.dataSource = self
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier: String = "BasicCell"
let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
let item: Parsexml = feedItems[indexPath.row] as! Parsexml
myCell.textLabel!.text = item.title
return myCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feedItems.count
}
override func viewDidAppear(_ animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Are you by any chance able to see the error that I can't see?
Note. I have not added any textlabel to the tablerow, but I guess that there shouldn't be added one, when its custom?
Try this code:
override func viewDidLoad() {
super.viewDidLoad()
print(yourArrayName.count) // in your case it should be like this print(feedItems.count)
}

Resources