Class 'TableViewController' has no initializers [duplicate] - ios

This question already has answers here:
Class 'ViewController' has no initializers in swift
(8 answers)
Closed last month.
import UIKit
import CoreData
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var titleArray = [String]()
var idArray = [UUID()]
var chosenTitle = ""
var chosenTitleID : UUID
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(addButtonClicked))
tableView.delegate = self
tableView.dataSource = self
getData()
}
func getData() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Places")
request.returnsObjectsAsFaults = false
do {
let results = try context.fetch(request)
if results.count > 0 {
self.titleArray.removeAll(keepingCapacity: false)
self.idArray.removeAll(keepingCapacity: false)
for result in results as! [NSManagedObject] {
if let title = result.value(forKey: "title") as? String {
self.titleArray.append(title)
}
if let id = result.value(forKey: "id") as? UUID {
self.idArray.append(id)
}
tableView.reloadData()
}
}
} catch {
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = titleArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titleArray.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
chosenTitle = titleArray[indexPath.row]
chosenTitleID = idArray[indexPath.row]
performSegue(withIdentifier: "toDetailsVC", sender: nil)
}
I have a problem with Swift class. I have a swift file for UITableViewController class. I had "Class 'TableViewController' has no initializers" problem.
I didn't find anything but the code says TableViewController has no initializers. I don't understand this problem. I have version 14.2.
Thanks for your responses.

You can make chosenTitleID property optional(var chosenTitleID: UUID?) or provide the default value to chosenTitleID because TableViewController class contains non-optional property.

Related

Use of undeclared type 'TrailViewController' - trying to handle item details from list in iOS app

Another issue with learning.
I found this in Apple Dev documentation: THIS
My target is to handle one tap on my list of items. When I click I need to open edit window and handle which row I selected. I trying to put that solution into my code but I have no idea what is TrailViewController (I getting Chinese links at first Google search page). So I decided to put my code there. I getting error:
Use of undeclared type 'TrailViewController'.
They appear after I adding this into my code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedTrail = elements[indexPath.row]
if let viewController = storyboard?.instantiateViewController(identifier: "TrailViewController") as? TrailViewController {
viewController.trail = selectedTrail
navigationController?.pushViewController(viewController, animated: true)
}
}
Full code from file below:
import UIKit
import Firebase
import FirebaseFirestore
class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var listOfItemsTableView: UITableView!
var elements: [Element] = []
override func viewDidLoad() {
super.viewDidLoad()
let db = Firestore.firestore()
db.collection("recipes").whereField("uid", isEqualTo: Auth.auth().currentUser!.uid).addSnapshotListener({ (snapshot, error) in
if let snapshot = snapshot {
var elementsTemp = [Element]()
for doc in snapshot.documents {
if let itemName = doc.get("name") as? String {
elementsTemp.append(Element(name: itemName))
}
}
self.elements = elementsTemp
self.listOfItemsTableView.reloadData()
} else {
if let error = error {
print(error)
}
}
})
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.listOfItemsTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return elements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "elementCell", for: indexPath) as! ElementCell
cell.elementNameLabel.text = elements[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedTrail = elements[indexPath.row]
if let viewController = storyboard?.instantiateViewController(identifier: "TrailViewController") as? TrailViewController {
viewController.trail = selectedTrail
navigationController?.pushViewController(viewController, animated: true)
}
}
#IBAction func addItemButtonClicked(_ sender: Any) {
self.performSegue(withIdentifier: "toAddItemView", sender: self)
}
}
class Element {
var name = ""
convenience init(name: String) {
self.init()
self.name = name
}
}
Update 1
Ok, I made some progress, but at this moment I can't navigate to EditItemViewController. This is how my code looks now:
import UIKit
import Firebase
import FirebaseFirestore
class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var listOfItemsTableView: UITableView!
var elements: [Element] = []
var element: Element?
override func viewDidLoad() {
super.viewDidLoad()
let db = Firestore.firestore()
db.collection("recipes").whereField("uid", isEqualTo: Auth.auth().currentUser!.uid).addSnapshotListener({ (snapshot, error) in
if let snapshot = snapshot {
var elementsTemp = [Element]()
for doc in snapshot.documents {
if let itemName = doc.get("name") as? String {
elementsTemp.append(Element(name: itemName))
}
}
self.elements = elementsTemp
self.listOfItemsTableView.reloadData()
} else {
if let error = error {
print(error)
}
}
})
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.listOfItemsTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return elements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "elementCell", for: indexPath) as! ElementCell
cell.elementNameLabel.text = elements[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedElement = elements[indexPath.row]
if let viewController = storyboard?.instantiateViewController(identifier: "EditItemViewControllerID") as? MainViewController {
viewController.element = selectedElement
self.navigationController?.pushViewController(viewController, animated: true)
}
}
#IBAction func addItemButtonClicked(_ sender: Any) {
self.performSegue(withIdentifier: "toAddItemView", sender: self)
}
}
class Element {
var name = ""
convenience init(name: String) {
self.init()
self.name = name
}
}
And how my storyboard looks at this moment:
Maybe I missed something?
Make a UIViewController named TrailViewController and add it as the class for a new UIViewController in your storyboard and you'll no longer get this error:
class TrailViewController: UIViewController {
var trail: Element?
// ...
}
Note: Also, don't forget to add the identifier for the new TrailViewController added in the storyboard as "TrailViewController" to get the UIViewController when calling instantiateViewController(identifier: in didSelectRow and perform navigation successfully.

How can I get an array to an NSManagedObject

I am sorry if I put out silly questions but I am new to Swift. I am building an app and so far it goes quite well. But now I want to delete some rows from my tableview which gets feeded from an Array with Strings. And then I want to save/fetch that using core data. I believe I have the code for it but the problem is that I am trying to save an array full of Strings. so I get error message saying: Cannot convert value of type 'String' to expected argument type 'NSManagedObject'. And therefore I am wondering, how can I solve this? Is there any way to "add those Strings to an NSManagedObject somehow?
Here are my code:
the array :
and here are the code:
import UIKit
import CoreData
class tableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (List.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = List.self[indexPath.row]
cell.textLabel?.textColor = UIColor.white
cell.backgroundColor = UIColor.clear
return(cell)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
if editingStyle == .delete{
let rows = List[indexPath.row]
context.delete(rows)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do{
List = try context.fetch(MealsMenu.fetchRequest()) as! [String]
}
catch{
print(error)
}
}
myTableView.reloadData()
}
#IBOutlet weak var myTableView: UITableView!
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
CoredataClass.saveItems()
CoredataClass.loadData()
}
}
You will need to create a function like this
Imagine that your Entity is Recipe which has an string attribute recipeName which contains the name of the recipe.
func fetchPersistentData() -> [String] {
var recipes = [String]()
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return recipes
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<Recipe>(entityName: "Recipe")
do {
let fetchedResults = try managedContext.fetch(fetchRequest)
if fetchedResults.count > 0 {
recipes = fetchedResults.map { ("\($0.recipeName)")}
return recipes
}
} catch let error as NSError {
// Wrong handling
print(error.description)
}
return recipes
}

searching and filter array firebase data swift3

My app crashing while search a text in a searchbar with error: thread1:signal SIGABRT probably the problem updateSearchResults() method?
or type of array? I'm beginner with swift any idea?
#IBOutlet weak var tableView: UITableView!
var data = [Any]()
var ref:FIRDatabaseReference!
// Filter Data from Firebase
var filteredData = [Any]()
// Declare searchBar
let searchController = UISearchController(searchResultsController: nil)
//is the device landscape or portrait
var isPortraid = true
#IBOutlet weak var bannerView: GADBannerView!
func fetchDataFromFirebase(){
EZLoadingActivity.show("caricamento...", disableUI: true)
ref = FIRDatabase.database().reference()
ref.observe(.value, with: { (snapshot) in
let dataDict = snapshot.value as! NSDictionary
self.data = dataDict["data"] as! [Any]
self.filteredData = self.data
print ("Sacco di merda:\(self.filteredData)")
self.tableView.reloadData()
EZLoadingActivity.hide()
})
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
fetchDataFromFirebase()
// Implement searchBar
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.orientationChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
//TableView Data Source and Delegate
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for:indexPath) as! MainScreenTableViewCell
let rowData = self.filteredData[indexPath.row] as! NSDictionary
let imageName = rowData["imageName"] as! String
cell.backgroundImageView.image = UIImage(named: imageName)
let label = rowData["categoryName"] as! String
cell.mealCategoryLabel.text = label
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let categoryViewController = storyboard.instantiateViewController(withIdentifier: "CategoryViewController") as! CategoryViewController
let rowData = self.data[indexPath.row] as! NSDictionary
categoryViewController.categoryTitle = rowData["categoryName"] as! String
let categoryData = rowData["category"] as! [Any]
categoryViewController.data = categoryData
self.navigationController?.pushViewController(categoryViewController, animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if isPortraid {
return UIScreen.main.bounds.height/3
} else {
return UIScreen.main.bounds.height/1.2
}
}
//Method for update search
func updateSearchResults(for searchController: UISearchController) {
if searchController.searchBar.text! == ""{
filteredData = data
} else {
filteredData = data.filter{($0 as AnyObject).contains(searchController.searchBar.text!)}
}
self.tableView.reloadData()
}
if searchController.searchBar.text! == ""
This is almost certainly the offender. The text property on UI objects is typically nil when it's empty, so when you force unwrap it your app crashes. You should never force unwrap something unless you are absolutely certain it will never be nil at that point.
There's a couple different ways you can handle this, which basically amount to making sure text isn't nil before you do anything with it.
Personally I would rewrite the if statement to unwrap the optional for the non-empty case:
if let text = searchController.searchBar.text, text != "" {
filteredData = data.filter{($0 as AnyObject).contains(text)}
} else {
filteredData = data
}
You could also use nil-coalescing:
if (searchController.searchBar.text ?? "") == ""
but personally I prefer to write it to avoid force unwrapping even when you're sure it isn't nil, so I would recommend the first one.

An empty cell on tableView + CoreData

Can someone tell me why it don't return cell for me? I really don't now why. On "cellTableViewCell" I have only outlets with label's.
Or I need to read at func viewWillAppear?
var nazwaTab:[String] = []
func getContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as? AppDelegate
return (appDelegate?.persistentContainer.viewContext)!
}
func wczytaj(wartosc:String) -> String {
var wartosc2 = wartosc
let request: NSFetchRequest<Ostatnie> = Ostatnie.fetchRequest()
do {
let result = try getContext().fetch(request)
for liczby in result {
if let str = liczby.value(forKey: "nazwa") as? String
{
wartosc2 = str
nazwaTab.append(wartosc2)
nazwaTab.last
}
print(nazwaTab)
}
} catch {
print(error)
}
return wartosc2
}
}
extension tabViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nazwaTab.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! cellTableViewCell
cell.dlugoscLabel.text = dlugoscTab[indexPath.row] as! String
cell.nazwaLabel.text = nazwaTab[indexPath.row]
cell.szerokoscLabel.text = szerokoscTab[indexPath.row] as! String
return cell
}
}
I think you should set UITableViewDelegate like this :
class tabViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
and in viewDidLoad:
tableView.delegate = self
tableView.dataSource = self

TableView definition conflict with previous using CoreData in Mutable array

I am trying to access the CoreData and putting it into the TableView so i have the data into the Mutable array but when i try to access it into the TableView then i got this error.
My code is as follows:
import UIKit
import CoreData
class TableView: UIViewController, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
var desc_arr: [String] = []
var amt_arr: [String] = []
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
let request = NSFetchRequest(entityName: "Expense")
request.returnsObjectsAsFaults = false
do {
let results = try context.executeFetchRequest(request)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let desc = result.valueForKey("desc") as? String {
print(desc)
desc_arr.append(desc)
}
if let amt = result.valueForKey("amt") as? String{
print(amt)
amt_arr.append(amt)
}
}
}
} catch {
print("Fetch Failed")
}
print(desc_arr)
print(amt_arr)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return desc_arr.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = desc_arr[indexPath.row]
return cell
}
}
}

Resources