Disclaimer: I am the CEO and founder of Creolabs, a startup that aims to reinvent how native cross-platform software is developed. Most of the technologies I mention in this post are currently under development for the upcoming Creo 3. This post intends to set a goal and a vision for what I think cross-platform development should be.
I am a bit obsessed with cross-platform development mainly because I find the inefficiency of the current tools and the huge amount of time required to go to market with a cross-platform product annoying.
I built several “complex” applications during my career. Creo written in ObjC/Swift/C (some million lines of code), CubeSQL (written in C) and also the Gravity programming language. There is one thing I learned very well: The Cross-platform problem is a UI problem. When you solve the cross-platform UI problem you can be sure to have practically solved the cross-platform development problem entirely.
Thanks to modern auto-layout technologies we are now able to create UI that can be automatically adapted to any device/resolution. I strongly believe that a solution to cross-platform development must include both desktop and mobile targets because nowadays, they are virtually the same thing.
In the past, I worked for some companies that offered cross-platform development tools. And they were all doing the same mistake. They thought that to be able to solve the cross-platform requirements they needed to create huge frameworks to add a level of indirection to the underline OS differences.
This approach has several disadvantages, the most important one is that you need to maintain a huge amount of code and you need to chase the OS vendor for all the changes that it will do in the future. Another important aspect is efficiency, to abstract the OS differences a lot of boilerplate code must be added most of the time.
What I am looking for is a way to create native quality software for iOS, Android, macOS, Windows, and Linux. Some big companies offer a solution: Flutter from Google, React Native from Facebook and Xamarin from Microsoft.
Flutter (release date: May 2017) At the time of this writing, Flutter is available for iOS and Android, it is in alpha release for macOS and technology preview for Windows and Linux. Flutter uses Dart as a programming language.
React Native (release date: March 26, 2015) React Native is available for iOS and Android and there are some community-supported projects for other platforms (more here), they all seem experiments and some of them are abandoned project. React Native could be fine for mobile-only projects even if I don’t like the web approach to solve non-web problems.
Xamarin (release date: May 16, 2011) Xamarin is available for both mobile and desktop and it is probably the most complete in terms of OS coverage. Xamarin is a .NET developer platform made up of tools, programming languages (mostly C#), and libraries for building many different types of applications. Xamarin Forms offers a WYSIWYG editor but it offers only a limited subset of all the native controls an OS can offer.
You can find tons of articles about which is better between any of these technologies, their pros and cons, the performance and or the bottleneck of each solution. It is really out of the scope of this post to compare them, what I’d like to present here is a completely different approach, much more natural, maintainable and not bound to a particular vendor who can change idea about a supported technology at any time.
How cross-platform development works today
- Designer(s) designs the UI of the apps in a designer tool like Figma/Sketch/Adobe XD. Unless the app uses the same custom design for all platforms, a different design is required for each supported OS.
- Developer(s) replicate the design using specific development tools, one for each supported platform (Xcode, Visual C, Visual Studio, etc.)
- Developer(s) write code for each supported platform using different languages
This is the most time-consuming (and expensive) way to proceed but it is also the one that guarantees the best and most efficient result. Different tools for different tasks (design and development) and different languages for each different platform (Swift for iOS, Kotlin for Android, C# for Windows, C++ for Linux and Swift/Objc for macOS).
Even if I am not a designer, I am a big fan of the WYSIWYG approach, it is the most natural and most efficient way to create and innovate. It would be wonderful to be able to have a real-time preview of each UI for each supported platform. Even better side by side. It would be a dream to being able to create pixel perfect UI, taking into consideration the differences in size and behavior of each platform. This is exactly what we are trying to accomplish with Creo 3.
Here you go a preview of our work:
Adding support for true WYSIWYG for each supported platform is a huge task. We did a gigantic work in the past rewriting the UIKit for macOS to be able to have real-time UIKit preview inside Creo. In Creo 3, we found a way to use UIKitForMac in a macOS app to be able to offer a preview for both iOS and Android native controls (this complex technical trick should deserve a separate article).
When you drop a control you should be able to set universal properties (values that affect all platforms) and individual properties so you can control the pixel-perfect position and OS-specific settings.
How cross-platform development should work
Designer(s) designs the UI of the apps in a designer tool like Figma/Sketch/Adobe XD. Unless the app uses the same custom design for all platforms, a different design is required for each supported OS. Designer tools should offer more than rectangles and triangles. They are the building block for any UI but developers and modern designers need more semantic information. Designer tools should offer ready to use components like NavigationBars for iOS or SegmentedControls for macOS. When I use a NavigationBar I’d like to be able to think in terms of LargeTitles (for iOS) or navigation bar items and how to customize behaviors and properties. The same applies to Buttons, Sliders and all the controls available for those platforms. I’d like to drop a Slider on the iOS board and see how it looks under iOS. I’d like to be able to switch OS and see how that slider looks under Android or macOS or Windows. I’d like to see how much bigger or smaller than control is under a different OS and be able to make changes that affect that OS only. That would be a true WYSIWYG modern experience. A game changer.
Developer(s) replicate the design using specific development tools, one for each supported platform (Xcode, Visual C, Visual Studio, etc.). This task must be automated! Designer tools should export native code for each supported platform: XIB/Storyboard code with Swift for iOS/macOS. XML with Kotlin code for Android. XAML with C# code for Windows. GTK/C++ code for Linux. UI code is the most difficult one to handle correctly and it is also the most time consuming one. IT MUST BE AUTOMATED! User interfaces must be constructed visually, must use native languages and compilers and no human interaction should be allowed in the generated code.
Developer(s) write code for each supported platform using different languages. By using a common true multi-platform programming language developers can focus on backend and model code. UI code is already automatically generated and it is guaranteed to work on all platforms/resolutions. By supporting one language for all platforms one developer can support multiple targets and multiple OS.
There is a need to drastically reduce time-to-market and to help designers/developers to perform as much realistic UI experiments as possible. Current design tools offer basic elements like rectangles, ovals, triangles and more. These basic elements are the perfect building blocks if you want to create vector graphics but they are the wrong answer to the UI problem.
Some tools offer ready-to-use templates for mobile app development, so instead of using rectangles and ovals, you can start thinking about NavigationBar or TabBar. This is a very good starting point but they are still rectangles under the hood and they lack the most important information: Semantic information.
I dreamed about a tool that offers ready to use complete templates for iOS, Android, macOS, Windows, and Linux. Each OS-specific template should have built-in constraints and each OS layer should be treated as a separate layer that can override the default behavior.
That would be a huge increase in the efficiency and correctness of the process. Developing a truly native cross-platform application should be reduced to graphically design its UI and manually write code for the backend ONLY.
I am a learn-by-doing person so in the next part of this article I’ll present a real cross-platform application using some of the technology we are developing with Creo 3.