Search code examples
iosswiftalljoyn

Alljoyn initialising bus attachment throws EXC_BAD_ACCESS


I am trying to create an iOS app using the alljoyn library. However when I try to create a bus attachment in swift by calling busAttachment = AJNBusAttachment.init(applicationName: "BusName", allowRemoteMessages: true); I get an EXC_BAD_ACCESS error during runtime.

This is the class I am using to create and use the bus attachment

class HostController: UIViewController {

var hostApi: HostApi!

var busAttachment: AJNBusAttachment!

var sessionOpts: AJNSessionOptions!

var CONTACT_PORT: AJNSessionPort = 12345

var serviceName: String = "org.company.appname.HelloWorld"


override func viewDidLoad() {
    super.viewDidLoad();
    NSLog("HostController viewDidLoad");


    var status: QStatus!

    busAttachment = AJNBusAttachment(applicationName: "BusName", allowRemoteMessages: true);

    busAttachment.registerBusListener(BusListener());


    hostApi = HostApi.init(busAttachment: busAttachment, onPath: "/HostService");

    status = busAttachment.start();

    if (status != ER_OK) {
        NSLog("busAttachment.start, Status: %s", QCC_StatusText(status));
    }

    status = busAttachment.registerBusObject(hostApi);

    if (status != ER_OK) {
        NSLog("busAttachment.registerBusObject, Status: %s", QCC_StatusText(status));
    }


    status = busAttachment.connectWithArguments(nil);

    if (status != ER_OK) {
        NSLog("busAttachment.connectWithArguments, Status: %s", QCC_StatusText(status));
    }


    status = busAttachment.requestWellKnownName(serviceName, withFlags: kAJNBusNameFlagReplaceExisting | kAJNBusNameFlagDoNotQueue)

    if (status != ER_OK) {
        NSLog("busAttachment.requestWellKnownName, Status: %s", QCC_StatusText(status));
    }


    sessionOpts = AJNSessionOptions.init(trafficType: kAJNTrafficMessages, supportsMultipoint: true, proximity: kAJNProximityAny, transportMask: kAJNTransportMaskTCP);



    status = busAttachment.bindSessionOnPort(CONTACT_PORT, withOptions: sessionOpts, withDelegate: nil);

    if (status != ER_OK) {
        NSLog("busAttachment.bindSessionOnPort, Status: %s", QCC_StatusText(status));
    }


    status = busAttachment.advertiseName(serviceName, withTransportMask: sessionOpts.transports);

    if (status != ER_OK) {
        NSLog("busAttachment.advertiseName, Status: %s", QCC_StatusText(status));
    }


    NSLog("Done");
}



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


class BusListener: NSObject, AJNBusListener {}

class SessionPortListener: NSObject, AJNSessionPortListener {

    func shouldAcceptSessionJoinerNamed(joiner: String!, onSessionPort sessionPort: AJNSessionPort, withSessionOptions options: AJNSessionOptions!) -> Bool {
        if (sessionPort == 12345) {
            NSLog("New peer joining session: %s", joiner);
            return true;
        } else {
            return false;
        }
    }

}

}

One thing I could be missing, on java we had to call org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(context); before we could use bus attachments, however in the samples provided for iOS there does not seem to be an equivalent call. Maybe I just missed it and it is put somewhere else, or maybe on iOS there is no equivalent.


Solution

  • Like Java you need to init AllJoyn before you can use it. To fix this I added #import "AJNInit.h" to my bridging header and added this to my swift to initialise AllJoyn.

    AJNInit.alljoynInit();
    AJNInit.alljoynRouterInit();
    

    You should also call these methods to release resources used by AllJoyn.

    AJNInit.alljoynShutdown();
    AJNInit.alljoynRouterShutdown();