In Xcode Swift, how do we properly catch errors on the connect to a server

How should we code in Xcode Swift 2.2 to catch the error when connecting to a server and the connection encounters a problem such as url is incorrect or server is not started? And how should be catch on the table operations also?

Currently, I have been unable to catch the error and the IOS application just terminates.

Thanks ahead of time.

Below is how I think it should be coded but Xcode says that the code “catch” block is unreachable because there is no errors thrown the the “do” block.

    do {
       rda = DARemoteDataAdapter(targetURL: vServerUrl!, dataServiceName: vServerDataService)
    } catch {
        print(error)
    }

Swift cannot catch actual objc runtime exceptions. I recommend using the async APIs, which have an explicit exception callback.

Are there any Swift examples of this anywhere?
Thanks.

Hold on Marc. I am looking again at the last Swift DASample that you sent me. It has some async code in there. Let me see if I can figure it out myself. I will post what I find.

Thanks.

1 Like

Marc,

Got my program working with the async beginGetTable. Pulls one of my tables fine that I tested with. But if I turn off server or put in an incorrect url ( which my customers will do ), I do not get any errors logged. Good thing is that it fails but does not terminate the IOS app.

Went back to the DASample app (Swift) from 3/25/2016 and modified url ( port 8099 to 8098 ) to make it incorrect. Ran and it also failed silently.

I assume that the delegate code fun remoteDataAdapter is the code that would log the connect error. I get no logging from this function of the connect error.

Any suggestions on what I am not including in the code.

Below is the code from the DataAccess.swift file.

@objc class DataAccess : NSObject, DARemoteDataAdapterDelegate {

let rda: DARemoteDataAdapter

private override init() {
    rda = DARemoteDataAdapter(targetURL: NSURL(string: "http://sample.remobjects.com:8098/bin")!)
    super.init()
    rda.delegate = self
    rda.username = "Test"
}

@objc func remoteDataAdapterNeedsLogin(adapter: DARemoteDataAdapter) -> Bool {
    return rda.loginWithUsername("Test", password: "Test")
}

@objc func remoteDataAdapter(adapter: DARemoteDataAdapter, didFailWithException exception: NSException, forAsyncRequest request: DAAsyncRequest) {
    NSLog("An error occured: %@", exception);
}

static let sharedInstance = DataAccess()

func beginGetUsers(callback: (DADataTable) -> ()) {


    // DA SQL:   
    rda.beginGetDataTable("Clients", withSQL: "SELECT * FROM Clients where ClientName LIKE '%n'") { table in
        callback(table);
    }
    
}

}

hmm, so

@objc func remoteDataAdapter(adapter: DARemoteDataAdapter, didFailWithException exception: NSException, forAsyncRequest request: DAAsyncRequest) {

never triggers for you?

Nope. Does it have to be hooked up anywhere. Being a delegate function, I did not expect so.

I ran from the DASample IOS sample app and also in my IOS app. No logging of the error on the invalid url connection.

I had planned on catching the error there and popping up an alert to the user.

Just assigning the delegate SHOULD be enough. I’ll have a look tomorrow or Monday. Meanwhile, can you try attaching the delegate to the DAasyncRequest and see if that on triggers? I assume the login event does trigger?

This method did not work.

func remoteDataAdapter(adapter: DARemoteDataAdapter, didFailWithException exception: NSException, forAsyncRequest request: DAAsyncRequest) {
    print("An error occurred: \(exception)" );    
}

Found one possible solution. Went to a different delegate method. And removed the “@objc” from the function. With the “@objc”, the method would not call. I am looking into that more but I guess it has something to do with optional methods.

func remoteDataAdapter(adapter: DARemoteDataAdapter, requestDidFailWithException exception: NSException) {
    let url = adapter.dataService?.channel.targetUrl!
    let errormessage = "An error occurred: \n\n \(exception) \n\n Server address: \n\n \(url!)"
    print( errormessage );
    callAlertController( "Connection Error", xMessage: errormessage )
}

Calling the alert from within the delegate is not a good scenario but wanted to show something today. Could not determine how to pass the exception from within the class back to where I was calling the rda.

Pops up this message as the error on the device.