How do you change a fetchRequest to an Array to use in a UITableView

dscrown Source

I am tying to put fetched data from coredata in a UITableView but I get this "EXC_BAD_INSTRUCTION" .
Using the let swiftBlogs Array works just fine, so can someone show my how to convert the fetch to an Array or is that not the correct way?

UITableView enter image description here

import UIKit import CoreData

class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var scrollView: UIScrollView!

@IBOutlet var timeStampTextField: UITextField!
@IBOutlet var quickQuoteTextField: UITextField!

@IBOutlet var tableViewQuickQuote: UITableView!


let swiftBlogs = ["Ray Wenderlich", "NSHipster", "iOS Developer Tips", "Jameson Quave", "Natasha The Robot", "Coding Explorer", "That Thing In Swift", "Andrew Bancroft", "iAchieved.it", "Airspeed Velocity"]

var tableViewCellArray : Array<AnyObject> = []
var quickQuoteArray : Array<AnyObject> = []


override func viewDidLoad() {
    super.viewDidLoad()

}


override func viewDidAppear(animated: Bool) {
    var appDel: AppDelegate            = UIApplication.sharedApplication().delegate as! AppDelegate
    var context:NSManagedObjectContext = appDel.managedObjectContext!
    var request                        = NSFetchRequest(entityName: "QuickQuote" )
        request.returnsObjectsAsFaults = false
        tableViewCellArray             = context.executeFetchRequest(request, error: nil)!


}

override func viewWillAppear(animated: Bool) {
    quickQuoteTextField.text = ""
    timeStampTextField.text = ""
}

@IBAction func clearButton(sender: AnyObject) {
    quickQuoteTextField.text = ""
    timeStampTextField.text = ""
}

@IBAction func addToQuickQuoteButton(sender: AnyObject) {

    let appDel: AppDelegate            = UIApplication.sharedApplication().delegate as! AppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext!
    let ent                            = NSEntityDescription.entityForName("QuickQuote", inManagedObjectContext: context)
    var newQuickQuote                  = QuickQuote(entity: ent!, insertIntoManagedObjectContext: context)
        newQuickQuote.quickQuote       = quickQuoteTextField.text
    context.save(nil)
}


@IBAction func timeStampButton(sender: AnyObject) {
    timeStamp()

    let appDel: AppDelegate            = UIApplication.sharedApplication().delegate as! AppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext!
    let ent                            = NSEntityDescription.entityForName("Time", inManagedObjectContext: context)
    var newTime                        = Time(entity: ent!, insertIntoManagedObjectContext: context)
        newTime.time  = timeStampTextField.text
        newTime.quote = quickQuoteTextField.text
    context.save(nil)
}


func timeStamp (){
     timeStampTextField.text = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: NSDateFormatterStyle.FullStyle,
     timeStyle: NSDateFormatterStyle.ShortStyle)
}

// MARK: - Table view data source
 func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}


 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return swiftBlogs.count  // return quickQuoteArray.count
}


private let stampCellID: NSString = "cell"  //This is the cell itself's identifier.    
 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(stampCellID as String, forIndexPath: indexPath) as! UITableViewCell

    var data: NSManagedObject = quickQuoteArray[indexPath.row] as! NSManagedObject
        cell.textLabel?.text    = data.valueForKey("quickQuote") as? String

// let row = indexPath.row // cell.textLabel?.text = swiftBlogs[row]

    return cell

}

/* func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { return true }

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {

    var appDel: AppDelegate            = UIApplication.sharedApplication().delegate as! AppDelegate
    var context:NSManagedObjectContext = appDel.managedObjectContext!
    if editingStyle == UITableViewCellEditingStyle.Delete {
        let tv = tableView
        context.deleteObject(quickQuoteArray.self[indexPath.row] as! NSManagedObject)
        tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)

    }

    context.save(nil)
}

*/

 func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

}

swiftuitableviewcore-datansfetchrequest

Answers

answered 2 years ago Jameson #1

You're mixing up your arrays swiftBlogs and quickQuoteArray. Whether or not the table view tries to access an array element quickQuoteArray[indexpath.row] is dependent on if it thinks that index is populated, based on the result from numberOfRowsInSection. In the numberOfRowsInSection method, you are returning the count of swiftBlogs, which is always the 10 or so strings you hand-typed in. So before your request is ever even executed, or the view even has a chance to populate anything else, it's trying to show elements that aren't present in the array you're using in cellForRowAtIndexPath.

In short: Always use the same array in cellForRowAtIndexPath as you are using in numberOfRowsInSection. Here, you've mixed two different arrays, quickQuoteArray and swiftBlogs.

comments powered by Disqus