There are a lot of notable exceptions, but most WebRTC developers start with the web because well, Web RTC does start with web and development is much easier there. Market realities tells a very different story – there is more traffic on mobile than desktop and this trend is not going to change. So the next phase in most WebRTC deployments is inevitably figuring out how to support mobile. Unfortunately for WebRTC that has often meant finding the relatively rare native iOS and Android developer.
The team at eFace2Face decided to take a different route and build a hybrid plugin. Hybrid apps allows web developers to use their HTML, CSS, and JavaScript skills to build native mobile apps. They also open sourced the project and verified its functionality with the webrtc.org AppRTC reference. We asked them to give us some background on hybrid apps and to walk us through their project.
{“intro-by”, “chad hart“}
When deciding how to create a mobile application using WebRTC there is no obvious choice. There are several items that should be taken into consideration when faced with this difficult decision, like the existence of previous code base, the expertise, amount of resources and knowledge available. Maintenance and support are also a very important factors given the fragmentation of the mobile environment.
At eFace2Face we wanted to extend our service to mobile devices. We decided to choose our own path- exploring and filling in the gaps (developing new tools when needed) in order to create the solution that fitted us best.This post shares some of the knowledge and expertise we gained the hard way while doing so. We hope you find it useful!
What’s a hybrid application?
There are two main approaches on how hybrid apps are built:
- WebView: Put simply, this is an HTML5 web application that is bundled inside a native app and uses the device’s web browser to display it. The development framework for the application provides access to the device’s functions (camera, address book, accelerometers, etc.) in the form of JavaScript APIs through the use of plugins. It should also be totally responsive and use native-like resources to get a UX similar to a real app. Examples include Cordova/PhoneGap, Trigger.io, Ionic, and Sencha (the latter two being like Cordova with steroids).
- Compilation: You can choose from several different languages (like C#) and the code gets compiled to a native application for each supported platform. Examples are Xamarin, Appcelerator, Embarcadero FireMonkey, or RubyMotion.
Creating Hybrid HTML5 app is the most extensive alternative and the one we prefer because it uses web specific technologies. You can get a deeper overview about native vs. HTML5 (and hybrid applications) in a recent blog post at Android Authority.
Hybrid App Pros & Cons
Pros:
- Hybrid apps are as portable as HTML5 apps. They allow code reuse across platforms, with the framework handling all platform-specific differences.
- A hybrid app can be built at virtually the same speed at which an HTML5 app can be built. The underlying technology is the same.
- A hybrid app can be built for almost the same cost as an HTML5 app. However, most frameworks require a license, which adds an extra development cost.
- Hybrid apps can be made available and distributed via the relevant app store, just like native apps.
- Hybrid apps have greater access to native hardware resources than plain HTML5 apps, usually through the corresponding framework’s own APIs.
Cons:
- Not all native hardware resources are available to hybrid apps. The available functionality depends on the framework used.
- Hybrid apps appear to the end user as native apps, but run significantly slower than native apps. The same restriction on HTML5 apps being rejected for being too slow and not responsive on Apple’s App Store also applies to hybrid apps. Rendering complex CSS layouts will take longer than rendering a corresponding native layout.
- Each framework has its own unique idiosyncrasies and ways of doing things that are not necessarily useful outside of the given framework.
From our point of view, a typical WebRTC application is not really graphic-intensive (i.e. it is not, for instance, a game with lots of animations and 3D effects). Most of the complex processes are done internally by the browser, not in JavaScript, so a graphical UX interface should be perfectly doable on a hybrid application and run without any significant perceptible slowdown. Instagram is a good example of a well-known hybrid app that uses web technologies in at least some of its components.
WebRTC on native mobile: current status
Native support in Android and iOS is a bit discouraging. Apple do not support it at all, and has no public information about when are they going to do so, if they decide to support it at all. On Android, the native WebView supported WebRTC starting in version 4.4 (but be cautious as it is based on Chromium 36) then in 5.0 and onwards.
Note that there are no “native WebRTC” APIs on Android or iOS yet, so you will have to use Google’s WebRTC library. Justin Uberti (@juberti) provides a very nice overview of how to do this (go here to see the slides).
Solutions
Let’s take a look at the conclusions of our research.
Android: Crosswalk
In Android, using the native WebView seems like a good approach; in fact we used it during our first attempt to create our application. But then we decided to switch to Intel’s Crosswalk, which includes what’s best described as a “full Chrome browser”. It actually allows us to use a fully updated version of native Chromium instead of WebView.
These were our reasons for choosing Crosswalk:
- Fully compatible source code: You only have to handle a single Chromium version across all Android devices. More importantly, it has the latest, regularly updated WebRTC APIs.
- Backward compatibility: According to developer.android.com, approximately 48% of Android devices currently in use are running Android versions below 4.4. While most of them don’t have hardware powerful enough to run WebRTC (either native or hybrid), you shouldn’t exclude this market.
- Fragmentation: Different versions of Android mean different versions of WebView. Given the speed at which WebRTC is evolving, you will have difficulties dealing with version fragmentation and supporting old versions of WebView.
- Performance: It seems you can get up to 10x improvement of both HTML/CSS rendering and JavaScript performance and CSS correctness.
An advanced reader could think: “Ok, this is cool but I need to use different console clients (Cordova and Crosswalk) to generate my project, and I don’t like the idea of that.” You’re right, it would be a hassle, but we also found another trick here. This project allows us to add Crosswalk support to a Cordova project; it uses a new Cordova feature to provide different engines like any other plugin. This way we don’t need to have different baselines in the source code.
iOS: Cordova plugin
As explained before, there are frameworks that provide hybrid applications with the device functionality code via plugins. You can use them in your JavaScript code but they are implemented using native code. So, it should be possible to add the missing WebRTC JavaScript APIs.
There are several options available, but most of them provide custom APIs or are tightly coupled with some proprietary signaling from a service provider. That’s the reason that we released an open source WebRTC Cordova plugin for iOS.
The plugin is built on top of Google’s native WebRTC code and exposes the W3C WebRTC APIs. Also, as it is a Cordova plugin, it allows you to have the same Cordova application running on Android with Crosswalk, and on iOS with the WebRTC plugin. And both of them reuse all of the code base you are already using for your web application.
Show me the code!
“Yes, I have heard this already”, you might say, so let’s get some hands-on experience. In order to demonstrate that it’s trivial to reuse your current code and have your mobile application running in a matter of days (if not hours), we decided to take Google’s AppRTC HTML5 application and create a mobile application using the very same source code.
You can find the iOS code on github, Here are the steps required to get everything we’re talking about working in minutes:
- Get the source code: “git clone https://github.com/eface2face/iOSRTCApp; cd iOSRTCApp”
- Add both platforms; all required plugins are installed automatically because of their inclusion in the “config.xml” file: Cordova platform add iOS android
- Run as usual: “cordova run –device”
- Once running, enter the same room as the one that’s already been created via web browser at https://apprtc.appspot.com/ and enjoy!
We needed to make some minor changes in order to make it work properly in the Cordova environment. Each of these changes didn’t require more than a couple of js/html/css lines:
- Due to Cordova’s nature, we had to add its structure to the project. Some plugins are required to get native features and permissions. The scripts js/apprtc.debug.js and js/appwindow.js are loaded once Cordova’s deviceready event is fired. This is necessary since the first one relies on the existing window.webkitRTCPeerConnection and navigator.webkitGetUserMedia , which are not set by cordova-plugin-iosrtc until the event fires.
- The webrtcDetectedVersion global variable is hardcoded to 43 as the AppRTC JavaScript code expects the browser to be Chrome or Chromium, and fails otherwise.
- In order to correctly place video views (iOS native UIView elements), the plugin function refreshVideos is called when local or remote video is actually displayed. This is because the CSS video elements use transition effects that modify their position and size for a duration of 1 second.
- A new CSS file css/main_overrides.css changes the properties of video elements. For example, it sets opacity to 0.85 in local-video and remote-video so HTML call controls are shown even below the native UIView elements rendering the local and remote video.
- Safari crashes when calling plugin methods within WebSocket events (“onopen”, “onmessage”, etc.). Instead, you have to run a setTimeout within the WebSocket event if you need to call plugin methods on it. We loaded the provided ios-websocket-hack.js script into our Cordova iOS app and solved this.
- Polyfill for windows.performance.now() used on AppRTC code.
Conclusion
Deciding whether to go hybrid or native for your WebRTC app is up to you. It depends on the kind of resources and relevant experience your company has, the kind of application that you want to implement, and the existing codebase and infrastructure you already have in place. The good news is our results show that using WebRTC is not a key factor in this decision, and you can have the mobile app version of your WebRTC web service ready in much less time than you probably expected.
References
- Hybrid Mobile Apps: Providing A Native Experience With Web Technologies
- “Diego Ferreiro & Norbert Hu: Building a performant HTML5/Hybrid Ap”
- Your favourite app isn’t native
- Crosswalk comes to Ionic
{“authors”, [“Jesus Perez“,”Iñaki Baz“, “Sergio Garcia Murillo“]}
Christian Stredicke says
I totally agree that currently only a hybrid approach can deliver the experience that users expect. We have found that it is a major problem that the audio subsystem of the WebRTC works always in handsfree mode, probably because it thinks well this is the browser. Hopefully that will be addressed soon with the WebView. Then WebRTC can deliver a similar experience like making regular phone calls.
Sergio Garcia Murillo says
Hi,
It is already addressed in the plugin, check this thread:
https://github.com/eface2face/cordova-plugin-iosrtc/issues/13
It is a custom API you can use in the ios rtc plugin:
iosrtc.selectAudioOutput(‘earpiece’);
iosrtc.selectAudioOutput(‘speaker’);
https://github.com/eface2face/cordova-plugin-iosrtc/blob/master/docs/iosrtc.md#iosrtcselectaudiooutputoutput
Asad Khan says
The article is spot on regarding where apps should be going.
There are still some problems though. One of which has already been brought up regarding switching the audio device in WebRTC. Is there a solution for that in Android.
I know most of the discussion here is about the IOSRTC but do you or anybody else here know if such a solution, for switching the audio device (speaker and mic) is also available for WebRTC on Android WebView?
Mathieu Hofman says
The problem with the Cordova approach (at least with the regular WebView engine, which is mandatory on iOS) is that WebRTC video is rendered in a native view layered above the WebView. While you can do tricks like reflecting some properties like size and opacity, you won’t be able to apply most CSS styling or layer HTML elements on top of your video.
I actually think the approach for hybrid apps should focus on reusing the core JavaScript logic and use a UI layer that’s platform dependent, i.e. HTML for web, native stuff for iOS and Android). The JavaScript doesn’t have to be pre-compiled in this case as you can expose all the platform UI APIs needed to a JavaScript engine that runs your dynamically loaded JS code. This is the approach taken by NativeScript. I’m curious to see where they end up.
Sergio Garcia Murillo says
In fact, we have investigating and a way to put the video window below the WebView, that way it could be possible to put HTML/CSS elements on top. Will only require HTML background to be transparent in order to avoid completely this caveat.
https://github.com/eface2face/cordova-plugin-iosrtc/issues/38
Anyway, from my point of view it is a minor price you have to pay in order to be able to reuse the same app on android/iOS and web.
Chris says
If you want a clean native iOS implementation, I recommend the Doubango Telecom
idoubs implementation.
I’m in the midst of a project using this stack and it’s working out well.
Full disclosure, we use Doubango WebRTC libraries here for embedded devices as well.
Iñaki Baz Castillo says
Chris, “idoubs” is a SIP client. Nobody here is talking about specific wire protocols but about hybrid apps + WebRTC (which is just the media layer).
Shnigi says
I get no sound from my Android device using webrtc + crosswalk, how can I enable the android microphone to record sound during call? I guess this is due to the device permissions, because the app works fine on PC + chrome.
John says
How about receiving calls, is it achievable with hybrid apps? I mean receiving a call when the smartphone is not in use, in a similar way as Whatsapp calls.
Andrew Lindzon says
If anyone knows how to get an ionic app on ios and android doing push to talk and push to text, let me know happy to pay for the integration assistance.
George Campbell says
Things are looking up for hybrid WebRTC! Safari 11 is supporting it.
https://www.infoq.com/news/2017/06/safari-11-announced-with-webrtc
Pete says
I think it’s time to update this resource. Crosswalk hasn’t been updated in several years, as @George Campbell stated, Safari 11 is now supporting webrtc etc.