Unable to find NIB in bundle only after adding an object to CoreData? - swift

This has been stumping me for a few hours and after looking through all kinds of related questions, I can't seem to figure out an answer.
I am getting a strange NSInternalInconsistencyException error. The error states that it cannot load an NIB with the name CountTableViewController. However, when I first run the app (in both simulator and physical device), I can segue to that view controller just fine. It loads and looks just as it does in the Main.storyboard file. Then, when I navigate back and activate another view controller that loads some test data into the Core Data Stack that I am using, things go very wrong. Using breakpoints and console logs, I can see that the single object has been successfully added into the Core Data Stack. But, when I click on the CountTableViewController again, the app crashes with the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Could not load NIB in bundle: 'NSBundle <FILEPATH> (loaded)' with name
'CountTableViewController''
I have read through every related question I could find, here's a quick list of things I have already tried that were unsuccessful:
Check spelling/case of related files and any place they are referenced
(CountTableViewController.swift, CountTableViewCell.swift, CountReuseCell [reuse id])
Delete references to related files, re-drag into Xcode
Delete references to Main.storyboard and LaunchScreen.storyboard, re-drag into Xcode
Verify that every file is listed correctly under 'Compile Sources' in 'Build Phases' of Project
Verify that storyboards are listed correctly under 'Copy Bundle Resources' in 'Build Phases' of Project
Rewrite as a totally new view controller from scratch (still got same error)
I'm pretty sure it's CoreData related since that seems to be the only difference between when the view controller does and does not work, but I'm pretty new to Swift and iOS dev, so I could be way off target.
I have the stack trace that I will post below. I will try to post some concise parts of the code that I think will be helpful. Thank you in advance for your help!
StackTrace:
0 CoreFoundation 0x000000010721912b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000102a78f41 objc_exception_throw + 48
2 CoreFoundation 0x000000010728e245 +[NSException raise:format:] + 197
3 UIKit 0x00000001043fd098 -[UINib instantiateWithOwner:options:] + 501
4 UIKit 0x00000001040b2687 -[UITableView _dequeueReusableViewOfType:withIdentifier:] + 590
5 UIKit 0x0000000120c4f79d -[UITableViewAccessibility dequeueReusableCellWithIdentifier:] + 147
6 UIKit 0x00000001040b2b6b -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:] + 148
7 UIKit 0x00000001040b2aa3 -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 89
8 UIKit 0x0000000120c4f8e0 -[UITableViewAccessibility dequeueReusableCellWithIdentifier:forIndexPath:] + 285
9 BSA Inventory Control 0x00000001018d35d6 _T021BSA_Inventory_Control24CountTableViewControllerC05tableF0So07UITableF4CellCSo0iF0C_10Foundation9IndexPathV12cellForRowAttF + 774
10 BSA Inventory Control 0x00000001018d3c4c _T021BSA_Inventory_Control24CountTableViewControllerC05tableF0So07UITableF4CellCSo0iF0C_10Foundation9IndexPathV12cellForRowAttFTo + 92
11 UIKit 0x00000001040ce484 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 778
12 UIKit 0x00000001040cea2a -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
13 UIKit 0x00000001040941f6 -[UITableView _updateVisibleCellsNow:isRecursive:] + 3031
14 UIKit 0x00000001040b62e6 -[UITableView layoutSubviews] + 176
15 UIKit 0x000000010403ea6d -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1439
CountTableViewController.swift
import UIKit
import CoreData
class CountTableViewController: UITableViewController {
let coreDataStack = CoreDataStack.shared
var moc: NSManagedObjectContext! = nil
var counts: [Count] = []
override func viewDidLoad() {
super.viewDidLoad()
moc = coreDataStack.viewContext
tableView.register(CountTableViewCell.self, forCellReuseIdentifier: "CountReuseCell")
let nib = UINib(nibName: "CountTableViewController", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "CountReuseCell")
}
func reload() {
counts = Count.items(for: moc, matching: nil, sortedBy: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
reload()
tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return counts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "CountReuseCell", for: indexPath) as? CountTableViewCell else {
fatalError("The dequeued cell is not an instance of CountTableViewCell")
}
let count = counts[indexPath.row]
cell.nameLabel.text = count.name
return cell
}
}
The CountTableViewCell.swift file is just a default Cocoa Touch Class with a subclass of UITableViewCell and a single outlet linking to the nameLabel in the storyboard.
A few quick afterthoughts... please let me know if there's any info you need that I didn't include here. I'm using a Core Data Stack Class and an extension adapted by a professor in an iOS dev class I took a year ago that provides the easy to use .items() functionality... I can also post that if you think that's causing any issues. This is so strange because I have another Core Data entity (Product instead of Count) using almost the exact same code that works perfectly. I can't seem to figure out what is different about this scenario...
Xcode Version 9.2 (9C40b), iOS Version 11.2 (15C107)

Just to wrap things up and hopefully help someone in the future, the issue seems to have been in these lines within the CountTableViewController.swift:
tableView.register(CountTableViewCell.self, forCellReuseIdentifier: "CountReuseCell")
let nib = UINib(nibName: "CountTableViewController", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "CountReuseCell")
As usual, it seems this was a mixture of reusing old code and copy/pasting. It's strange that this code seems to work fine in almost an identical scenario with the Product entity in the same project. Nevertheless, I removed the last two lines above, leaving me with only:
tableView.register(CountTableViewCell.self, forCellReuseIdentifier: "CountReuseCell")
Sure enough, the NSInternalInconsistencyException error was gone!
Last night, I was able to rewrite the CountTableViewController entirely programatically and it is working correctly, so I plan to use that for now. However, it is good to know what was causing this error for the future.
Thanks to #pbasdf for the comment/answer!

Related

NSTableView not appearing at all

I've just started working on my first project for macOS and am having trouble setting up a NSTableView. When I run it the window will appear but there is nothing in it. I've made sure all the objects have the correct class in the identity inspector and can't seem to find what I'm doing wrong.
The goal of the app is to make a notes app. I want a tableView which displays the titles of all the notes in the database, in a single column, so when you click on the cell the note will then be displayed in the rest of the window.
Here's the code:
import Foundation
import AppKit
import SQLite
class NoteCloudVC: NSViewController {
// Declare an array of Note objects for populating the table view
var notesArray: [Note] = []
// IBOutlets
#IBOutlet weak var tableView: NSTableView!
// ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// set the tableViews delegate and dataSource to self
tableView.delegate = self
tableView.dataSource = self
//Establsih R/W connection to the db
do {
let path = NSSearchPathForDirectoriesInDomains(
.applicationSupportDirectory, .userDomainMask, true
).first! + "/" + Bundle.main.bundleIdentifier!
// create parent directory iff it doesn’t exist
try FileManager.default.createDirectory(
atPath: path,
withIntermediateDirectories: true,
attributes: nil
)
let db = try Connection("\(path)/db.sqlite3")
//Define the Notes Table and its Columns
let notes = Table("Notes")
let id = Expression<Int64>("ID")
let title = Expression<String>("Title")
let body = Expression<String>("Body")
/*
Query the data from NotesAppDB.sqlite3 into an array of Note objs
Then use that array to populate the NSTableView
*/
for note in try db.prepare(notes) {
let noteToAdd = Note(Int(note[id]), note[title], note[body])
notesArray.append(noteToAdd)
}
} catch {
print(error)
}
}
// viewWillAppear
override func viewWillAppear() {
super.viewWillAppear()
tableView.reloadData()
}
}
// NSTableViewDataSource Extension of the NoteCloudVC
extension NoteCloudVC: NSTableViewDataSource {
// Number of rows ~ returns notesArray.count
func numberOfRows(in tableView: NSTableView) -> Int {
return notesArray.count
}
}
// NSTableViewDelegate extension of the NoteCloudVC
extension NoteCloudVC: NSTableViewDelegate {
// Configures each cell to display the title of its corresponding note
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
//configure the cell
if tableColumn?.identifier == NSUserInterfaceItemIdentifier(rawValue: "NotesColumn") {
let cellIdentifier = NSUserInterfaceItemIdentifier(rawValue: "NotesCell")
guard let noteCell = tableView.makeView(withIdentifier: cellIdentifier, owner: self) as? NotesCell else { return nil }
let note = notesArray[row]
noteCell.noteTitle.stringValue = note.title
return noteCell
}
return nil
}
}
// NotesCell class
class NotesCell: NSTableCellView {
// IBOutlet for the title
#IBOutlet weak var noteTitle: NSTextField!
}
I'm pretty familiar with UIKit so I thought the learning curve of AppKit would be a little better than SwiftUI, so if anyone could provide some guidance about where I've gone wrong that would be very much appreciated. Also if it will be a better use of my time to turn towards SwiftUI please lmk.
Here's the values while debugging:
It's reading the values from the table correctly, so I've at least I know the problem lies somewhere in the tableView functions.
The most confusing part is the fact that the header doesn't even show up. This is all I see when I run it:
Here are some images of my storyboard as well:
This is for an assignment for my software modeling and design class where my professor literally doesn't teach anything. So I'm very thankful for everyone who helps with this issue because y'all are basically my "professors" for this class. When I move the tableView to the center of the view controller in the story board I can see a little dash for the far right edge of the column but that's it, and I can't progress any further without this tableView because the whole app is dependant upon it.
So, it turns out that the code itself wasn't actually the problem. I had always used basic swift files when writing stuff for iOS so it never occured to me that I'd need to import Cocoa to use AppKit but that's where the problem lied all along. Using this code inside the auto-generated ViewController class that had Cocoa imported did the trick. Also I got rid of the extensions and just did all the Delegate/ DataSource func's inside the viewController class.

How to populate TableView cell from datasource? I am currently receiving error

I am trying to return an array of Geocoded Placemarks from Mapbox Geocoder to TableView cells, but I am receiving an error (assertion failure in UITableView and failed to obtain a cell). Am I doing something incorrectly with the delegate or index path? I am have looked at similar questions, but I am unable to solve it.
I am using a storyboard; I have triple checked the cell identifier in my storyboard to make sure it aligned to 'with identifier'.
EDIT: I was able to remove the error by changing 'cellForRowAt indexPath: NSIndexPath' to 'cellForRowAt indexPath: IndexPath'.
Now when I enter text into the SearchBar it is returning the array, but the cells are empty even with data. Empty Cells Picture
import UIKit
import MapboxGeocoder
class LocationSearchTable: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var placemarkResults: [GeocodedPlacemark] = []
func forwardGeocoding(addressQuery: String) {
let geocoder = Geocoder(accessToken: "//OMITTED//")
let options = ForwardGeocodeOptions(query: addressQuery)
options.allowedScopes = [.address]
options.allowedISOCountryCodes = ["US"]
options.autocompletesQuery = true
let _ = geocoder.geocode(options) { (placemarks, attribution, error) in
guard let placemarks = placemarks, !placemarks.isEmpty else {
return
}
self.placemarkResults = placemarks
}
print(placemarkResults)
}
}
extension LocationSearchTable: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let searchBarText = searchController.searchBar.text else { return }
let _ = forwardGeocoding(addressQuery: searchBarText)
self.tableView.reloadData()
}
}
extension LocationSearchTable {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return placemarkResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
let selectedItem = placemarkResults[indexPath.row].place
cell.textLabel?.text = selectedItem?.name
cell.detailTextLabel?.text = ""
return cell
}
}
2019-06-26 00:45:22.179129-0700 Ride Sharing App[91152:18783310] *** Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3698.103.12/UITableView.m:9655
2019-06-26 00:45:22.186549-0700 Ride Sharing App[91152:18783310] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView (<UITableView: 0x7f8fb398e200; frame = (0 0; 414 896); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x6000018395c0>; layer = <CALayer: 0x60000161fca0>; contentOffset: {0, -144}; contentSize: {414, 44}; adjustedContentInset: {144, 0, 34, 0}>) failed to obtain a cell from its dataSource (<Ride_Sharing_App.LocationSearchTable: 0x7f8fb2d69660>)'
*** First throw call stack:
(
0 CoreFoundation 0x000000010e2196fb __exceptionPreprocess + 331
1 libobjc.A.dylib 0x000000010b3b7ac5 objc_exception_throw + 48
2 CoreFoundation 0x000000010e219482 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010ae05927 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
4 UIKitCore 0x0000000115f0799f -[UITableView _configureCellForDisplay:forIndexPath:] + 433
5 UIKitCore 0x0000000115f1a6bf -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 911
6 UIKitCore 0x0000000115f1ab65 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 73
7 UIKitCore 0x0000000115ee2d20 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2870
8 UIKitCore 0x0000000115f02e37 -[UITableView layoutSubviews] + 165
9 UIKitCore 0x00000001161af9c1 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1417
10 QuartzCore 0x000000010ec85eae -[CALayer layoutSublayers] + 173
11 QuartzCore 0x000000010ec8ab88 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 396
12 QuartzCore 0x000000010ec96ee4 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 72
13 QuartzCore 0x000000010ec063aa _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 328
14 QuartzCore 0x000000010ec3d584 _ZN2CA11Transaction6commitEv + 608
15 QuartzCore 0x000000010ec3dede _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 76
16 CoreFoundation 0x000000010e1800f7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
17 CoreFoundation 0x000000010e17a5be __CFRunLoopDoObservers + 430
18 CoreFoundation 0x000000010e17ac31 __CFRunLoopRun + 1505
19 CoreFoundation 0x000000010e17a302 CFRunLoopRunSpecific + 626
20 GraphicsServices 0x00000001112542fe GSEventRunModal + 65
21 UIKitCore 0x0000000115ce1ba2 UIApplicationMain + 140
22 Ride Sharing App 0x0000000108ac21ab main + 75
23 libdyld.dylib 0x000000010ca4c541 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
your problem could be because you're not setting the delegate & datasource.
so try this :
in your class:
class LocationSearchTable: UITableViewController, UITableViewDelegate, UITableViewDataSource {
//Then set the delegate and dataSource in ViewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
Also make sure you have an outlet for your TableView named tableView

swift UIViewController for a button in a custom cell

I've a custom table view cell which has a label view. I added tapGesture to invoke a function when that view is clicked.
Currently my custom view cell is in it's own swift file. I added following code to enable 'Share extension' when clicked on that label.
CustomCellView.swift
10 myLabel.isUserInteractionEnabled = true
11 let tap = UITapGestureRecognizer(target: self, action: #selector(tapLabelGesture))
12 myLabel.addGestureRecognizer(tap)
13 func tapLabelGesture() {
14 print("Clicked on Label ")
let url="www.google.com"
15 let activityVC = UIActivityViewController(activityItems: [url], applicationActivities: nil)
16 activityVC.popoverPresentationController?.sourceView = self.view
17 self.present(activityVC, animated: true, completion: nil)
18 }
I get compiler error on line 16 for self.view and 17 for self.present(). Question is how do I provide view for the popup?
This code I used for another view (without table view or cell) as a test and it worked fine. So I'm trying do the same technique for a tableview/cell. How do I resolve this issue? Any help is appreciated.
For line 16:
You are getting an error which says your class CustomCellView has no member view because your class is subclass of UITableViewCell not UIViewController because UIViewController has that property and your CustomCellView have contentView for that.
For line 17:
same as above your class is not subclass of UIViewController thats why you can not use self.present for that.
Solution:
Instead of using UITapGestureRecognizer you can use UIButton which you can place on UILabel and in your UIViewController class add button.tag and button.addTarget in your cellForRowAt method.
Then you can add your code in your button method and present UIActivityViewController.
Hope this will help.
As #DharmeshKheni mentioned you cannot use a subclass of UITableViewCell like UIViewController. It doesn't provide view property and present method.
Answering your question, you could store a closure in the CustomCellView:
var onLabelTappedCallback: (() -> Void)?
call it in your selector:
#objc private func tapLabelGesture() {
onLabelTappedCallback?()
}
and finally implement in the cellForRowAt method:
cell.onLabelTappedCallback = {
print("Label tapped")
//Present additional vc
}
This solution will work with UIButton as well.
I got more ideas from this thread on SO,
how to recognize label click on custom UITableViewCell - Swift 3
With the an extension, I was able to solve this issue.

Opening a new window on a different storyboard

I am developing an OS X app with storyboards. I get the Preview.storyboard with an Entry Point on an anonymous window with a custom ViewController. In the AppDelegate class, I get the following function.
func newPreviewWindow(sender: AnyObject) {
let storyboard = NSStoryboard.init(name: "Preview", bundle: nil)
let initialController = storyboard.instantiateInitialController()
initialController!.showWindow(nil)
initialController!.makeKeyAndOrderFront(nil)
}
When running the code, the window shows, but I get the following exception:
2016-08-11 10:27:12.434 MyApp[1090:290439] -[NSWindowController makeKeyAndOrderFront:]: unrecognized selector sent to instance 0x60000008c350
2016-08-11 10:27:12.434 MyApp[1090:290439] -[NSWindowController makeKeyAndOrderFront:]: unrecognized selector sent to instance 0x60000008c350
2016-08-11 10:27:12.440 MyApp[1090:290439] (
0 CoreFoundation 0x00007fff926284f2 __exceptionPreprocess + 178
1 libobjc.A.dylib 0x00007fff97c0ef7e objc_exception_throw + 48
2 CoreFoundation 0x00007fff926921ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff92598571 ___forwarding___ + 1009
4 CoreFoundation 0x00007fff925980f8 _CF_forwarding_prep_0 + 120
5 MyApp 0x0000000100005617
...
Based on the exception message and search on Google and StackOverflow, I tried sending a Selector to the makeKeyAndOrderFront function this way :
func newPreviewWindow(sender: AnyObject) {
let storyboard = NSStoryboard.init(name: "Preview", bundle: nil)
let initialController = storyboard.instantiateInitialController()
let selector = #selector(AppDelegate.newPreviewWindow(_:))
initialController!.showWindow(nil)
initialController!.makeKeyAndOrderFront(selector) // [A]
}
But then I get the following compile error on line [A]: Cannot call value of non-function type '((AnyObject?) -> Void)!'
How is the proper way to open the new window or to pass the Selector?
Thanks! :)
initialController!.makeKeyAndOrderFront(nil) is causing a problem because makeKeyAndOrderFront: is not an NSWindowController method - it belongs to NSWindow (hence the unrecognized selector error). Cast your initial controller to your NSWindowController subclass, then bring the window to the front via the controller's window property:
var windowController: NSWindowController!
#IBAction func showOtherWindow(sender: AnyObject) {
windowController = storyboard.instantiateInitialController() as! NSWindowController
windowController.window?.makeKeyAndOrderFront(nil)
}

Delete UITableViewCell row with NSMutableArray throws exception

I have a tableview and the data inside each cell is an NSMutableArray. I want to delete a row of the tableview each time I swipe left and press the delete button. However it is difficult with an NSMutableArray. I get a Sigabrt everytime I input the code toDoItems.removeObjectAtIndex(indexPath.row).
The error I get is
Terminating with uncaught exception of type NSException 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'
Any help on this problem?
Here is code relating to the problem.
ViewDidLoad code containing toDoItems:
let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let itemListFromUserDefaults:NSMutableArray? = userDefaults.objectForKey("itemList") as? NSMutableArray
if ((itemListFromUserDefaults) != nil){
toDoItems = itemListFromUserDefaults!
}
My NSMutableArray variable
var toDoItems:NSMutableArray! = NSMutableArray()
My commitEditingStyle function:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){
if(editingStyle == UITableViewCellEditingStyle.Delete){
//This code gives me the error and Sigabrt
toDoItems.removeObjectAtIndex(indexPath.row)
tbl?.reloadData();
}
My numberOfRowsInSection function:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return toDoItems.count
}
My cellForRowAtIndexPath function:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView
let toDoItem:NSDictionary = toDoItems.objectAtIndex(indexPath.row) as! NSDictionary
cell.lbl.text = toDoItem.objectForKey("itemTitel") as? String
return cell
}
Here is the error
MyPlanner[12373:461118] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'
* First throw call stack:
(
0 CoreFoundation 0x0000000109df3d85 exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000109867deb objc_exception_throw + 48
2 CoreFoundation 0x0000000109df3cbd +[NSException raise:format:] + 205
3 CoreFoundation 0x0000000109de9dae -[__NSCFArray removeObjectAtIndex:] + 94
4 MyPlanner 0x0000000109210c53 _TTSf4dg_n_g_n___TFC9MyPlanner14ViewController9tableViewfTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 131
5 MyPlanner 0x000000010920fc3d _TToFC9MyPlanner14ViewController9tableViewfTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 61
6 UIKit 0x000000010ac124c0 -[UITableView animateDeletionOfRowWithCell:] + 205
7 UIKit 0x000000010abe7a3e __52-[UITableView _swipeActionButtonsForRowAtIndexPath:]_block_invoke + 80
8 UIKit 0x000000010ac13eaa -[UITableView _actionButton:pushedInCell:] + 172
9 UIKit 0x000000010ae3aae6 -[UITableViewCell _actionButtonPushed:] + 82
10 UIKit 0x000000010aab4a8d -[UIApplication sendAction:to:from:forEvent:] + 92
11 UIKit 0x000000010ac27e67 -[UIControl sendAction:to:forEvent:] + 67
12 UIKit 0x000000010ac28143 -[UIControl _sendActionsForEvents:withEvent:] + 327
13 UIKit 0x000000010ac27263 -[UIControl touchesEnded:withEvent:] + 601
14 UIKit 0x000000010af9cc52 _UIGestureRecognizerUpdate + 10279
15 UIKit 0x000000010ab2748e -[UIWindow _sendGesturesForEvent:] + 1137
16 UIKit 0x000000010ab286c4 -[UIWindow sendEvent:] + 849
17 UIKit 0x000000010aad3dc6 -[UIApplication sendEvent:] + 263
18 UIKit 0x000000010aaad553 _UIApplicationHandleEventQueue + 6660
19 CoreFoundation 0x0000000109d19301 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
20 CoreFoundation 0x0000000109d0f22c __CFRunLoopDoSources0 + 556
21 CoreFoundation 0x0000000109d0e6e3 __CFRunLoopRun + 867
22 CoreFoundation 0x0000000109d0e0f8 CFRunLoopRunSpecific + 488
23 GraphicsServices 0x000000010ec78ad2 GSEventRunModal + 161
24 UIKit 0x000000010aab2f09 UIApplicationMain + 171
25 MyPlanner 0x00000001092134fd main + 125
26 libdyld.dylib 0x000000010d43d92d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Here is the code where I put in the information(add items) in toDoItems.
#IBAction func ClickedforSelection(sender: AnyObject) {
if delegate != nil {
let information : NSString = txt1.text!
delegate!.userDidEntredInformation(information)
}
let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var itemList:NSMutableArray? = userDefaults.objectForKey("itemList") as? NSMutableArray
let dataSet:NSMutableDictionary = NSMutableDictionary()
dataSet.setObject(txt.text!, forKey: "itemTitel")
if ((itemList) != nil){ // data already available
let newMutableList:NSMutableArray = NSMutableArray();
for dict:AnyObject in itemList!{
newMutableList.addObject(dict as! NSDictionary)
}
userDefaults.removeObjectForKey("itemList")
newMutableList.addObject(dataSet)
userDefaults.setObject(newMutableList, forKey: "itemList")
}else{ // This is the first todo item in the list
userDefaults.removeObjectForKey("itemList")
itemList = NSMutableArray()
itemList!.addObject(dataSet)
userDefaults.setObject(itemList, forKey: "itemList")
}
userDefaults.synchronize()
NSUserDefaults objectForKey will always return immutable objects. Simply down casting it won't make it mutable. You need to create a mutable array from the immutable array that is returned:
let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
if let itemListFromUserDefaults = userDefaults.objectForKey("itemList") as? NSArray
toDoItems = itemListFromUserDefaults.mutableCopy()
}