0

I have error __NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0] when I try to add second item with the same date.

I can't find where is the issue. I think problem is in getSectionItems function.

Someone can help me?

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var sumLabel: UILabel!

var costItems: NSMutableArray = NSMutableArray()
var accountIdentifier: NSString = NSString()
var costsSum:Int!

var sectionsInTable = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.delegate = self
    self.tableView.dataSource = self

    costsSum = getCostsSum()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewDidAppear(animated: Bool) {
    loadData()
    self.tableView.reloadData()
    costsSum = getCostsSum()
}


func loadData() {
    costItems.removeAllObjects()

    let moc:NSManagedObjectContext = SwiftCoreDataHelper.managedObjectContext()
    let predicate: NSPredicate = NSPredicate(format: "identifier == '\(accountIdentifier)'")!
    let results:NSArray = SwiftCoreDataHelper.fetchEntities(NSStringFromClass(Cost), withPredicate: predicate, managedObjectContext: moc)

    for cost in results{
        let singleCost:Cost = cost as Cost

        let costDict:NSDictionary = ["identifier":singleCost.identifier,"costName":singleCost.costName, "costValue":singleCost.costValue, "date":singleCost.date]

        costItems.addObject(costDict)

        // Date

        let dateFormatter: NSDateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "dd MMMM"
        let dateString: NSString = dateFormatter.stringFromDate(costDict.objectForKey("date") as NSDate)

        let sections: NSSet = NSSet(array: sectionsInTable)
        if !sections.containsObject(dateString) {
            sectionsInTable.append(dateString)
        }
    }

    self.tableView.reloadData()
}

func getSectionItems(section: Int) -> [Cost] {
    var sectionItems = [Cost]()
    let moc:NSManagedObjectContext = SwiftCoreDataHelper.managedObjectContext()
    let predicate: NSPredicate = NSPredicate(format: "identifier == '\(accountIdentifier)'")!
    let results:NSArray = SwiftCoreDataHelper.fetchEntities(NSStringFromClass(Cost), withPredicate: predicate, managedObjectContext: moc)

    for cost in results {

        let singleCost:Cost = cost as Cost

        let costDict:NSDictionary = ["identifier":singleCost.identifier,"costName":singleCost.costName, "costValue":singleCost.costValue, "date":singleCost.date]

        let dateFormatter: NSDateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "dd MMMM"
        let dateString: NSString = dateFormatter.stringFromDate(costDict.objectForKey("date") as NSDate)


        if dateString == sectionsInTable[section] as NSString {
            sectionItems.append(singleCost)
        }
    }

    return sectionItems
}

// UITableViewDataSource

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sectionsInTable[section]
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return sectionsInTable.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.getSectionItems(section).count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:DetailTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as DetailTableViewCell

    let costDict:NSDictionary = costItems.objectAtIndex(indexPath.row) as NSDictionary

    let costName = costDict.objectForKey("costName") as String
    let costValue = costDict.objectForKey("costValue") as Double

    cell.nazwaWydatkuLabel.text = costName

    // Date
    let dateFormatter: NSDateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd MMMM"
    let dateString: NSString = dateFormatter.stringFromDate(costDict.objectForKey("date") as NSDate)
    cell.dateLabel.text = dateString

    if (Int(costValue)) < 0 {
        cell.wartośćLabel.layer.cornerRadius = 8.0
        cell.wartośćLabel.layer.masksToBounds = true
        cell.wartośćLabel.backgroundColor = UIColor(red: 255.0/255.0, green: 59.0/255, blue: 48.0/255.0, alpha: 1.0)
    } else {
        cell.wartośćLabel.layer.cornerRadius = 8.0
        cell.wartośćLabel.layer.masksToBounds = true
        cell.wartośćLabel.backgroundColor = UIColor(red: 127.0/255.0, green: 207.0/255.0, blue: 77.0/255.0, alpha: 1.0)

    }

    cell.wartośćLabel.text = "  \(Int(costValue)) zł  "

    return cell
}

@IBAction func addCostButtonPressed(sender: UIBarButtonItem) {

   self.performSegueWithIdentifier("addCostVC", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "addCostVC" {
        let addCostVC: AddTableViewController = segue.destinationViewController as AddTableViewController
        let thisID = accountIdentifier
        addCostVC.accountIdentifier = thisID
    }
}

func getCostsSum() -> Int {

    let moc:NSManagedObjectContext = SwiftCoreDataHelper.managedObjectContext()
    let predicate: NSPredicate = NSPredicate(format: "identifier == '\(accountIdentifier)'")!
    let results:NSArray = SwiftCoreDataHelper.fetchEntities(NSStringFromClass(Cost), withPredicate: predicate, managedObjectContext: moc)

    var costSum: Int = 0
    for res in results {
        var costCount = res.valueForKey("costValue") as Int
        costSum += costCount
    }
    self.sumLabel.text = "\(costSum) zł"
    return costSum
}

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

    let moc:NSManagedObjectContext = SwiftCoreDataHelper.managedObjectContext()
    let results:NSArray = SwiftCoreDataHelper.fetchEntities(NSStringFromClass(Cost), withPredicate: nil, managedObjectContext: moc)


    let thisCost: AnyObject = results.objectAtIndex(indexPath.row)
    moc.deleteObject(thisCost as NSManagedObject)
    //costsValues = getAccountCountSum()

    SwiftCoreDataHelper.saveManagedObjectContext(moc)

    loadData()
    getCostsSum()
    self.tableView.reloadData()
}
Maselko
  • 4,028
  • 2
  • 22
  • 21
  • better show only the relevant code where the crash happens. currently one has to go through a lot of code. Th abetter you can show where exactly the crash happens, the better answers can be given. – Volker Jan 13 '15 at 11:32
  • 1
    I know, but Xcode does not show the place where the error occurs. – Maselko Jan 13 '15 at 11:36
  • Add an NSException breakpoint and it will: http://stackoverflow.com/questions/1163981/how-to-add-a-breakpoint-to-objc-exception-throw/3633921#3633921 (for Xcode 4 but gives a good idea) – Volker Jan 13 '15 at 11:42
  • Sorry not to answer your problem directly, but I would encourage you to use an `NSFetchedResultsController` - it will work out for you which items appear in which section. Check the [Apple Docs](https://developer.apple.com/library/ios/documentation/CoreData/Reference/NSFetchedResultsController_Class/). The complication is your section names being "dd MMMM" format, but Apple provide a [sample project](https://developer.apple.com/library/ios/samplecode/DateSectionTitles/Introduction/Intro.html) which does exactly that. – pbasdf Jan 14 '15 at 00:49
  • Maselko, we are having a very similar issue. As this has been a year now, have you figured this out yet? If so, could you please post it? – David Sanford Jul 27 '16 at 10:15
  • I can't remember but I think I added unique identifier to each item. – Maselko Jul 27 '16 at 10:48

0 Answers0