Populate NSTableView from viewDidLoad error (Swift)

I have a brand new project with all of about 30 lines of code. A NSViewController with an NSTableView in it and a button.
All the project does is load data from Backendless and populate the tableview with two columns.
I have examined other posts and the examples and they are a bit different situation and question.
Here’s the query to load the item

func loadItems() {
 let itemDataStore = backendless.persistenceService.of(ItemClass.ofClass())
itemDataStore.find(
{ (result: BackendlessCollection!) -> Void in
let items = result.getCurrentPage()
for item in items as! [ItemClass] {
self.arrayToDisplay.append(item)
}
self.myTableView.reloadData()
},
error: { (fault: Fault!) -> Void in //why is this executed?
print("app error: \(fault)")
})
}

If this code is called from the NSButtons action event, it loads the data correctly and populates the tableview. So we know the code works.
However, if that same code is called from viewDidLoad it crashes
override func viewDidLoad() {
super.viewDidLoad()

myTableView.setDelegate(self)
myTableView.setDataSource(self)

loadItems()
}
and the error
2016-07-27 19:59:46.703 Backendless Test[14198:2120873] Failed to set (contentViewController) user defined inspected property on (NSWindow): *** -[__NSArray0 objectAtIndex:]: index 3 beyond bounds for empty NSArray
What would be the difference between calling loadData() from a button and calling it in viewDidLoad()? This same code sequence works with other databases so the error is confusing.
As a test, I commented out the code in the loadItems() and the app does not generate an error from viewDidLoad. I also tried creating a couple of ItemClass objects within loadItems() and populating the tableViewDataSource (array) with those test items - that also works.
Something within this code

    { (result: BackendlessCollection!) -> Void in
causes the error block to execute, but then the block started but generates the above error.

Hi Jason,

Please, use sync method in viewDidLoad(), for example:

func loadItemsSync() {
        
        Types.tryblock({ () -> Void in
            let itemDataStore = backendless.persistenceService.of(ItemClass.ofClass())
            if let result = itemDataStore.find() {
                let items = result.getCurrentPage()
                for item in items as! [ItemClass] {
                    self.arrayToDisplay.append(item)
                }
                self.myTableView.reloadData()
            }
            },
            catchblock: { (exception) -> Void in
                print("error: \(exception as! Fault)")
            }
        )
    }

Regards,
Slava

Thank you for the response.

Can you explain why the asynchronous method cannot be used in viewDidLoad, and is there any other situations where the async method should not be used?

Also in the BlogFeatureDay-iOS-master, F21RetrievingAutolodedDataSwift, there’s an example of loading data asynchronously from viewDidLoad. Is that code viable?

and (these responses should be editable)

the code in the answer throws an error

Could not cast value of type 'NSException' (0x7fff73ea0d20) to 'Fault' (0x1000f3cf8).

Please check in a debugger what details are contained in the “exception” object on line 14. It looks like the cast problem is right there.

Well. It’s (AnyObject!) Some

http://support.backendless.com/public/attachments/1ab1d552852636d972fa2befca7bd8dd.png</img>

keep in mind that if I run the exact same code from a buttonAction, it works. However, it crashes from viewDidLoad.

I would need to defer to our iOS experts. I’ll have someone to look into it.

Regarding your question about F21RetrievingAutolodedDataSwift. The code from should definitely be valid and applicable.

Looks like this exception is not associated with backendless invoke.
Could you provide your full viewDidLoad() code?

The entire viewDidLoad function is in the original post.

As I mentioned the only other code in the app are the two required tableView delegate methods.

Again, the code works correctly when called from a button action but crashes when run from the viewDidLoad. It’s super simple to duplicate the issue as I’ve created 3 completely separate projects on two different Macs and they all crash in the same fashion.

Let me add there is additional code in the AppDelegate to set up the Backendless connection.

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {


    let APP_ID = "7BAC40E6-4F32-0F1D-FF13-87D6D051EB00"
    let SECRET_KEY = "hidden"
    let VERSION_NUM = "v1"
    
    var backendless = Backendless.sharedInstance()
    


    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
        
        backendless.initApp(APP_ID, secret:SECRET_KEY, version:VERSION_NUM)
        
    }


    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }
}

Hi Jason,

Please try this implementation:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        myTableView.setDelegate(self)
        myTableView.setDataSource(self)
        
        dispatch_async( dispatch_get_main_queue(), { () -> Void in
            self.loadObjectsAsync()
        })
    }

Regards,
Slava