A couple of months ago, I undertook to learn iOS development. I was exclusively an Android developer before, and I wanted to improve my skills. I knew it would not be an easy job and the learning curve would be pretty steep. Especially, coming from an Android background, you are sometimes really surprised by the way you build things in iOS. You’re like “Come on dude, this could be more straightforward than that.”. Anyway. As Apple did with Objective-C, when releasing Swift, I feel confident in the fact they will release an upgraded version of Cocoa Touch in a short term.
Thus, I started this long journey by cutting my teeth on Swift. I am not going to talk about the Swift language here. However, if you are interested in learning Swift, I taught a couple of classes at the Rails School. You can find my notes here. In my opinion, Swift is a pretty good language, gathering smart concepts from C#, C++ and Ruby. However, the syntax is quite confusing and many improvements can be done. That’s why I appreciated this announcement from Apple about the upcoming open-sourcing of Swift.
To get a hand on this tech stack, I tried to port an existing Android app. About the business layer, everything is similar. I had no particular trouble in writing an iOS version of my algorithms.
About the service part (e.g. alarms, push notifications, application’s lifecycle), I was surprised by how Apple handles things. For instance, you cannot run a custom background service in iOS. The only types of services you are allowed to run are VoIP, localization or data background fetching. I was a bit disappointed but this method is arguable (saving battery, forcing developers to match good practices etc.).
My main complication was actually about the UI part. Of course, I started using Interface Builder, and I must say it, it’s such a mess. First, I do not like the fact you are forced to use XCode to design interfaces. Anyway, it’s not a new thing from Apple. They are not popular for portability.
However, IB is not easy to use. Well, it is ok when designing light interfaces but it tends to be terrible when building more complex ones. You are forced to use this constraint system which is entirely based on relative positionning. Moreover, when working with collaborators, merging those XIB files is a real challenge.
So I was like: How do iOS developers do things? I mean most of the iOS applications are really beautiful. I could not think they were all relying on solutions such as Cordova or Ionic. So I chatted with some senior developers and navigated all over the Internet to find they build interfaces in code, using libraries such as Pure Layout or Cartography. Directly in code. It would be the same than if a web developer was building his whole website within his JS code. That’s catastrophic.
Consequently, I kept searching alternatives and I finally found this great tool: Framework7. Its owners recreated all the iOS components into HTML and JS. Also, they offer you an API to use the device’s features. Then, using Cordova, you can wrap your HTML/JS app into a native application.
I was really interested in all the UI components they offered. Nevertheless, I was not that much excited by the API. It was similar to other tools I mentioned before. Then, I got this idea: would it be possible to engineer a native app (written in either Swift or Objective-C) and use this framework as a UI layer only?
Guess what? It’s absolutely possible.
How do I process? That’s super simple. I build my application in Swift. Then, in my storyboard, I create a
ViewController with a single element: a
UIWebView. I reference all my assets (js, css, html, imgs etc.) into my XCode project for integrating them when building the solution. Finally, I use the
loadRequest from my web controller to load my desired html page. And we are all set!
My presentation layer, which relies on HTML and JS thanks to Framework7, is then independent from my back-end part. I can easily design a cool UI using JS and HTML and I do not have to deal with IB anymore.
Alright mate, that’s clever. But how do you send data from your backend to the JS part? And vice versa?
That’s a fair point. Actually, Cocoa Touch offers developers two methods to ensure this communication process. To send data from Swift to JS, the
UIWebViewController has a
shouldStartLoadWithRequest from the
However, if you need to send complex data structures, it turns out those methods are tricky to use. For instance, I may be interested in sending a list or a hash from my backend. After snooping around, I found no existing tool to simplify the communication between these two buckets. Therefore I decided to create my own iOS WebView data interop library, named Caravel. It is a simple event bus system which allows you to send any basic data (including dictionaries and arrays) from and to Swift.
And here you go! You can skip Interface Builder from now on, and build your interface in an elegant way.
If you are still not convinced by this pattern, I advise you to glance at Framework7 anyway. It is worth the journey. These guys did a fantastic job: UI components, animations, popups, navigation bars, template engine etc. And this snickerdoodle is open-source :)