Configuring Alljoyn on iOS
Have you ever played Spaceteam on Android or iOS? It’s a local (cross-platform) multiplayer only game, based on a really cool concept. The players are… you guessed it… a space team, and they need to cooperate to keep the spaceship they are traveling on intact through space. This means that you’ll be shouting at your friends commands, and activating various weirdly named knobs and switches.
While I was researching the tech behind it, I stumbled upon Alljoyn, by Qualcomm.
Spaceteam uses HHServices and AsyncSocket, so the networking protocol was built almost from the ground up by its creator. Alljoyn on the other hand promises an opensource “universal (cross-platform) software framework that enables interoperability among connected products and software applications across manufacturers to create dynamic proximal networks.” And I’m all for that.
The cool thing about it is its ability to seamlessly operate over wifi or over bluetooth (losing the cross-platform ability).
If you login on the Alljoyn site you’ll come across the free, opensource, SDK and a bunch of samples. I downloaded the iOS SDK, and started working on my sample.
What I found out is that the walkthroughs and guides are either not up to date or just wrong. So I figured I could write down what I did to make everything work.
In this day and age, where cocoapods eases our mind when we need to integrate a third party library, it was a harsh throwback in the world of missing headers and wrong architecture builds.
Compiling openssl
If you take a look at Alljoyn’s SDK readme you’ll notice that the first thing you need to do is compile Openssl for iOS. That’s quite easy, and fairly well documented, just head to Github and clone the openssl-xcode project.
As stated in the readme you need to download the openssl sources and place them in your openssl-xcode project.
That’s how the folder structure should look:
To compile it just open the .xcodeproj file and use XCode’s Product –> Build For –> Release, or stay in your terminal window and compile it with xctool or xcodebuild, either:
1
|
|
or:
1
|
|
You’ll find the built library in your derived data:
Just grab Debug-iphoneos
and Debug-iphonesimulator
, and place them under a build
folder, inside your openssl sources. It should look something like this:
1 2 3 4 |
|
Cool, now download and unzip the Alljoyn’s SDK.
New Alljoyn project
With that out of the way it’s time to start working on our project. Fire up Xcode and create a new project.
Object Model
We’ll start by creating the object that will travel the bus. Alljoyn uses its own XML format to define the object structure. I’m not a fan of this format, but that’s what we have to work with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
This is the basic object that you’ll find in the official guide, it defines a simple method that returns two input strings concatenated:
1
|
|
Cool, now we should run the code generator bundled in the Alljoyn’s SDK to generate the Objective-c code. The generator needs to be compiled, so we’ll do that in a couple of clicks.
Compiling the generator
Building the generator is pretty straightforward, just head to <AllJoyn SDK Root>/alljoyn_objc/AllJoynCodeGenerator
and build with XCode the AllJoynCodeGenerator.xcproj. This will create a /bin folder with the generator excecutable file.
Now the good Alljoyn folks suggest to setup a new target that will allow us to generate with XCode the code. Since I like to keep my targets tidy, and since we have a perfectly fine console, I just skip this step and go the old fashioned way. Just copy the bin/AllJoynCodeGenerator wherever you like, as well with our trusty XML object, and run:
1
|
|
This will generate:
AJNSampleObject.h
AJNSampleObject.mm
SampleObject.h
SampleObject.m
Copy these file to your project and add them to your target.
Build settings
Now the fun part. We’ll need to configure the build settings of our project. What I really like to do is move the AllJoyn’s SDK bins and openssl build in the project’s root. Two reasons for that:
I don’t have to configure environment variables and link the relative paths
The project is self contained, so everyone can just clone the project and compile it without firther hassles
So, here’s my folder structure:
☺ ~/code/git/alljoynsample ll
drwxr-xr-x 16 Andrea staff 544 25 Gen 15:14 AlljoynSample
drwxr-xr-x 5 Andrea staff 170 25 Gen 15:14 AlljoynSample.xcodeproj
drwxr-xr-x 5 Andrea staff 170 25 Gen 15:14 AlljoynSampleTests
drwxr-xr-x 5 Andrea staff 170 25 Gen 15:14 alljoyn-sdk
drwxr-xr-x 4 Andrea staff 136 25 Gen 15:14 openssl
Remmeber to remove the unused samples and openssl sources.
Next step, head to your project’s build settings tab, and set Build Active Architecture Only
to YES.
Below that field, look for Other Linker Flags
and set it to -lalljoyn -lajdaemon -lBundledDaemon.o -lssl -lcrypto
.
That’s where I needed to stop following the official guide, since the path described are wrong.
Head to the Header Search Paths
field and enter these:
$(inherited)
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
"$(SRCROOT)/alljoyn-sdk/alljoyn_core/build/darwin/arm/$(PLATFORM_NAME)/$(CONFIGURATION)/dist/cpp/inc"
"$(SRCROOT)/alljoyn-sdk/alljoyn_core/build/darwin/arm/$(PLATFORM_NAME)/$(CONFIGURATION)/dist/cpp/inc/alljoyn"
Then in Library Search Paths
:
$(inherited)
"$(SRCROOT)/openssl/build/$(CONFIGURATION)-$(PLATFORM_NAME)"
"$(SRCROOT)/alljoyn-sdk/alljoyn_core/build/darwin/$(CURRENT_ARCH)/$(PLATFORM_NAME)/$(CONFIGURATION)/dist/cpp/lib"
The $(CURRENT_ARCH) var was key to make the project compile on armv7s devices. That took a while to figure out.
We can now get back to the official guide, setting Enable C++ Exceptions
and Enable C++ Runtime Types
to NO.
Add -DQCC_OS_GROUP_POSIX -DQCC_OS_DARWIN
to Other C Flags Debug and -DNS_BLOCK_ASSERTIONS=1 -DQCC_OS_GROUP_POSIX -DQCC_OS_DARWIN
to Other C Flags Release.
Frameworks
Almost done. We need to take care of the frameworks. Just copy the AllJoynFramework
folder from the Alljoyn’s SDK in your folder and your project, and make sure to remove the AJNPasswordManager
class or you won’t be able to compile.
Finish up by linking the static frameworks SystemConfiguration
and libstdc++.dylib
and we are done.
Hit the trusty ⌘B
and you should see a succesful build.
Well, that wasn’t fun at all, and it sure made me appreciate Cocoapods even more. Hope this helps anyway.
Until next time.
Andrea