Cross-Platform mobile development with Swift

TL;DR, flip to the bottom for links…

Recently I was asked to evaluate SCADE, which is a new IDE, one that has an intriguing value proposition:

  • write your logic in Swift
  • create your mobile UI
  • test and deploy native iOS .ipa’s…
  • and native Android .apk’s…
  • from one codebase.

Yeah, I know there are others out there that do something similar, but this is Swift we’re talking about, not C#. And yes, you can use React to make a web SPA and turn it into an app with Cordova or Intel XDK, but those make a glorified web view so it’s not native and really slow and laggy.*

The attraction was for me to be able to use my favourite language, Swift, to create native iOS AND Android applications using one IDE and a single codebase.

I was really doubtful at first, but I could see the potential, however we’re dealing with a product that has not reached market yet so I was a skeptic.

For this evaluation I was asked to create a simple application to find out if it really was real, did it actually work or was it “vaporware” — basic, shallow and ultimately not very useful.

*Clarification: I am not referring to React Native — that’s completely different. I have direct experience of using React & Cordova/Intel XDK and it wasn’t positive.

The application

This was the premise:

  • Take some list and detail data from an API server and present it on the device.
  • It should include remotely loaded images, a map, transitions and basic common UI elements like a toolbar.
  • It should be able to work with various screen sizes and adapt to orientation.
  • It should be able to compile for Android and iOS, ready for each app store.

My first step was actually to build the backend. My natural choice was to use Perfect (full disclosure, I’m on the core Perfect development team), so I built the API, datastore, authentication and the web administration interface. I then loaded data that was from a real event that has just passed, because it feels more purposeful if you use real data.

The admin presenter list view
The admin presenter edit view

Next step: Design the flow. This was pretty simple… Splash screen, about, presenter list & detail, session list & detail, schedule.

Then the design: Well, OK this is a proof of concept, so I didn’t need to spend much time on this, apart from the acknowledgement that I didn’t want it to be an eyesore.

The deep dive into SCADE

OK so installing SCADE is not as smooth as installing Xcode. But we’re also coping with the Android side of life so that’s to be expected. I was on a newish laptop and I didn’t have any Android dev components installed yet so I sighed with relief when I saw they had really good docs on getting everything set up: https://scade.readme.io/docs/installation. That was a big win right away for me, because to be honest Google has failed with making Android dev environments easy as much as Apple has succeeded.

One day I hope they will automate the installation of this, but for now you have to follow the instructions and work through the command line (for the most part).

To my delight, it’s based on Eclipse!

To my surprise it wasn’t hard to get familiar with the UI — I immediately recognized SCADE’s Eclipse underpinnings as it was loading. The SCADE team’s choice to use Eclipse as a platform is fantastic because it means every user gets access immediately to all the great extras out there for Eclipse like excellent git integration, Mylyn, and hooks into a bunch of systems like Trac.

Xcode has the concept of “Storyboards”, with pages on the storyboard, and you have to manually assign a class to manage that page’s behaviour. SCADE goes straight to the concept of a page as an entity, and when you create a new page it couples both a visual UI for the page and an associated controlling Swift document. Another win.

Simple page with Toolbar & Banner

I started by creating a page, and throwing a few UI elements on it. SCADE’s box/container layout model took a bit of getting used to, but after a bit of experimentation and some Q&A with the devs I started to get it.

Then I created another page, and wanted to see how it handled transitions — because let’s get real here, the process of handling transitions in an iOS app is a little arcane. Not so with SCADE. The code to attach the action and transition to a button was really quite easy:

let btn1 = self.page.getWidgetByName("volunteersbtn") as! SCDWidgetsToolBarItem
btn1.onClick.append(
SCDWidgetsEventHandler{
_ in self.navigation.go(
“volunteer.page”,
transition:”FORWARD_PUSH”
)
}
)

Pretty clear: when “volunteersbtn” is clicked (more correctly, tapped) then go to volunteer.page.

Something that this code also reveals: SCADE has it’s own API that you have to learn. Actually not really an issue when you consider the benefits… behind the scenes their API maps these common events, handlers and objects to the appropriate code for the targeted system, Android or iOS. Props to the engineering team, that’s huge.

The next thing I wanted to get going was the list, so I made a list item and laid out the things I wanted in there. Photo, Name, company. Then I wanted to attach to data loaded from the API I built. In an iOS app right now I’d be immediately reaching for some CocoaPods but hey, thats not the point here — what’s the system capable of out of the box?

That’s when I discovered SCADE’s “Service”. I didn’t believe it at first. I kept thinking surely it should be more complicated.

FWIW, yes there’s a mismatch of “volunteer” vs “presenter” — I changed my mind part way through what they should be called, and didn’t go back and refactor.

Clicking “invoke request” makes the app go get the JSON response, and from there a few clicks later you have all the code generated for the interactions.

Preview of the response and its mapping

I also created a class for holding each Presenter (aka volunteer), a container array for results, and in the load function for the volunteer page 2 lines of code to set it up and a for loop to process the results into the array.

// Setting up the container array
dynamic var presenters : [Presenter] = []
// in the load function
let svc: presenterService =
SCDRuntime.loadService(“presenterService.service”)!
let presenterResponse = svc.getPresenters()
if let prs = presenterResponse?.presenters {
self.setupList(prs)
}
// in the class
func setupList(_ presenters: [Presenters]) {
for presenter in presenters {
self.presenters.append(
Presenter(
id: presenter.id,
firstname: presenter.firstname,
lastname: presenter.lastname,
photo: presenter.photo,
company: presenter.company,
companylogo: presenter.companylogo,
twitter: presenter.twitter,
linkedin: presenter.linkedin
bio: presenter.bio
)
)
}
}

Then came the challenge of hooking up the data to the list. After chatting with the devs at SCADE about this I was confused — they were telling me I didn’t need to write any code. Then I got what they meant: when viewing the “page gui” there’s a “design” tab as well as a “binding” tab. Flipping to that I immediately saw that it exposed the dynamic var presenters as [Presenter]. It also exposed all the properties of the items in the whole layout of the page. Have a look at the screenshot below — it shows how some of those properties “just map” by clicking a property on one side, then the target node & property on the other, then the little green “Create Binding” icon. When you run it in the simulator, boom, it’s just there.

Data binding as as easy as a few clicks

The only extra trick I had to do was something similar to what you do in iOS… to load a remote image I had to load the bytes and assign it to a var in the object, then assign that to the photo content — exactly the same as a text value. Easy eh?

Finally, to create the app, you pick your compilation target from the toolbar and start the compilation process.

SCADE uses the Apple Swift compiler to create both the Android and the iOS native binary. The compilation takes about 1.5 minutes for the initial build

and it results in native iOS and Android apps:

OK so there’s so much more I could discuss about the cool things I found in SCADE, but what I really hope is that you’ll try it for yourself.

I think this IDE has a strong future, and it’s in active development — there is so much more they have planned. The value proposition for this is only going to get stronger IMHO.

Next steps?

We were able to convince the SCADE team to offer a Private BETA to the Perfect community. If you are interested in being one of the first in history to create a full-stack, cross-platform (iOS and Android) App and give feedback to SCADE — join the Perfect community here:

Slack: http://www.perfect.ly (join channel #swift-android-ios)

From this channel, we’ll give you private access to a Beta version of SCADE as well as early access to the documentation. The SCADE developers will also be hanging out in this channel to answer any questions :)

See you there, and don’t forget to say hi!

Update: April 3rd

Check out part 2: https://medium.com/p/swift-for-cross-platform-client-server-side-development-3784466cb9f6