Chrome 62 for iOS supports the Payment Request API. That in itself is interesting and important for a number of reasons. I’ve tweeted about this last week, but I think this is interesting enough to warrant a whole article with additional background information. So here goes…
iOS means WebKit
If you compare any other version of Chrome with the iOS version you will notice something weird. Chrome is based on Chromium, but Chrome for iOS is not. In fact, Chrome for iOS uses the iOS WebView which is based on WebKit. But it’s not just Chrome. If you look at Edge for iOS or Firefox for iOS, you will see the same thing. Edge is not based on EdgeHTML and Firefox is not based on Gecko. All of them use the WebView that is provided by the operating system and that WebView uses WebKit.
Now, this may seem weird, but it all stems from the rules of the App Store. Apple does not allow third-party rendering engines in the App Store. All browsers on iOS must use the WebView that is build into the OS.
Some seem to think the reason for this decision is Apple trying to stifle competition, but most likely this is because of security reasons. A third party rendering engine needs to be able to execute arbitrary code and not just the precompiled code of the application. If you allow applications to execute arbitrary code you basically allow the app to bypass the app review process, because the developer can change what the app does after it is approved. It may also open up the application to security problems like remote execution of code. So Apple does not allow third-party applications to do that.
This was also the reason why initially the system WebView didn’t support Just-In-Time compilation of JavaScript and was instead relying on the much slower interpreter. The WebView initially ran in the same process of the application and allowing JIT meant, the whole application was allowed to execute arbitrary code. Nowadays, this isn’t an issue anymore, because the WebView is now running in a separate process and only that process is allowed to execute arbitrary code, not the whole application.
Whatever the reason is, this is a decision that is not very popular by some, because it effectively doesn’t allow proper competition between browsers on iOS. Every browser is pretty much the same as Safari, except for the user interface. The rendering is pretty much identical. And this isn’t good for iOS users, because Safari is lagging behind with implementing new standards. In fact a French open source vendor called Nexedi has filed a lawsuit against Apple in 2016, just because of this.
Payment Request in Safari
When Apple Pay on the web was released with iOS 10, it was based on a proprietary API. That was kind of disappointing to people who were following the work on the Payment Request API specification. But to be honest, the spec was not quite ready yet. Thankfully Apple immediately said that they were going to look at the new standard API and work with the working group to align the two, so using Payment Request for Apple Pay was going to be possible at a later moment.
In fact, Apple has recently started implementing Payment Request in WebKit and is expected to ship it in a later release of Safari. If you download the Safari Technical Preview, you can see the beginnings of an initial implementation, but from looking at the code it is quite apparent that it is not yet finished. It’s difficult to say when this feature will be ready. Perhaps iOS 12, or maybe a minor upgrade to iOS 11, who knows? But right now Payment Request is not yet supported in Safari.
Payment Request in Chrome for iOS
But Payment Request is supported by Chrome for iOS today. What? How did Google do that? And why didn’t they wait for Apple to finish their implementation instead?
First we need to consider that when Apple releases a version of Safari that supports Payment Request, that does not mean that other apps like Chrome also that get access to that API. Safari and the WebView are pretty much the same, but they are not identical. Apple might decide that Payment Request is only available to Safari itself. In fact, if you look at Apple Pay on the web right now, that too is not available in other apps that use the WebView.
That may sound anti-competitive, but might actually be the opposite, because Google might not want to integrate with Apple Pay. Instead they probably will want to integrate with their own infrastructure and allow their users to do payments with the payment cards that are stored in the users Google account.
But how did Google add a new API to the existing WebView provided by the operating system?
Extending the WebView
Because the WebView is provided by the operating system it is pretty obvious that Google can’t simply add any new APIs to the rendering engine. It can’t modify the version of WebKit that is used by the WebView. It must use some other mechanism to extend the WebView.
Luckily Apple provides a method in the WebView to do exactly that. Originally that method was intended for allowing communication between the code that runs in the WebView and native code. Take for example a native app that uses a WebView to show some content. If the user clicks on that content, it must tell the native app that the user initiated some action. And vice-versa the code that runs in the WebView might need to adapt to changes made in the native app.
This communication mechanism is also used by Cordova and its cousin PhoneGap. Cordova allows you to build native apps using web technologies. The apps created by Cordova are basically just a small wrapper that uses the system WebView with an embedded web app. So you can write your app in HTML, CSS and JavaScript and still submit it to the App Store. Cordova apps have access to all the APIs and features of the WebView, but sometimes you may want to add some native code to integrate with the operating system. Cordova provides a plugin framework to do just that. And plugins can register new APIs in the WebView that your app can use.
Now, the bridge between the WebView and the native code is pretty basic. You can’t just add any API you want from the native app. But you can inject your own JavaScript code in a WebView and pass simple messages between both sides.
And this mechanism is also what Chrome is using for their implementation of Payment Request. It is extending the WebView by basically injecting a polyfill written in JavaScript in the WebView that passes messages to native code that handles the actual UI for selecting payment methods and the communication to the Google servers for retrieving the payment card information from your account.
How far can we take this?
The Payment Request API is actually an ideal candidate for extending the WebView. It is mostly a JavaScript API that shows a native user interface and then gives back information to the WebView. It is fairly isolated from the rendering engine and doesn’t interact with any other APIs.
Chrome isn’t the first to try this approach. Take WebRTC for example, which other browser have supported for a couple of years now. But users of iOS were left behind, because Safari didn’t support this standard, at least not until last month when iOS 11 was released. But that is not actually the whole truth. iOS users could download an experimental browser created by Ericsson, called Bowser that fully supported WebRTC.
And more recently we’ve seen features like WebBluetooth appear in the desktop version of Chrome and Chrome for Android. And again Safari does not support this, but iOS users can download a browser called WebBLE, which just like Bowser is a build on top of the system WebView and extends it with one specific new API that Safari doesn’t support.
But what about more complicated features like… Service Workers?
Service Workers is probably the most invasive feature added to the web platform in the last couple of years. It is impossible to polyfill and interacts with a lot of things all over the rendering engine. Definitely not simple, so, probably not. Right?
Actually, Yes. With a lot of caveats that is also possible. In fact, there is a working proof of concept created by Alastair Coote. While it is certainly not ready for production it does show us that we can actually fake a whole lot more than just a simple API like Payment Request.
But I don’t expect Chrome for iOS to get Server Worker support before Safari. Apple already started work on their own implementation and I expect Google to just wait for that. There is just too many things that can go wrong and too many caveats. Too much work and risk, especially when Apple will likely ship it in the next major iOS update anyway.
Browser competition
Up until this point, the only competition between browser on iOS has been on the user interface side. Things like syncing bookmarks and integration of password managers. If you’re using Chrome on your desktop machine, you may want to use Chrome for iOS too, because all your favourites are there too. And likewise for Firefox and Edge.
But actual competition on web platform features? That didn’t really happen so far.
We’ve had Bowser and WebBLE, but those are experimental browsers, and really not suited for day-to-day use. Chrome is the first major browser on iOS that started competing with Safari by adding new web platform features.
Some might consider extending the WebView a bad move. Because that would lessen the pressure on Apple to implement that feature themselves. If Chrome would implement a certain feature, that would satisfy the users who need that feature and they are less likely to complain about that feature missing in Safari.
I don’t believe that. In fact, I think the opposite is true. The only way to get Apple to implement a feature is to convince them that users need that feature. And the best way to do that is to show them that developers are already using it and users are loving it. If users are moving to other browsers on iOS because some website uses a killer feature that is not available in Safari, that will get their attention.
I am very curious what Google is going to do with Chrome for iOS. They started on this path and for the sake of competition I hope they are going to add other specifications too.
Take for example the WebBluetooth API. I just love this API and the opportunities it creates for the web. There already is a browser available that implements this specification on iOS, so it is definitely possible for other browsers to add it to the system WebView. Furthermore, this is something that Chrome is actively promoting and rolling out on other platforms. And Apple has indicated that they are not interested in implementing this themselves. So for me this is an ideal candidate for Google to add to Chrome for iOS. For users this is a win-win scenario. iOS users get a major browser that supports a very cool API and with the uptake of that API, Apple might reconsider implementing it themselves in Safari.
Ever since the first browsers the web has been a platform that thrived from the competition between browsers. We wouldn’t be here today if it weren’t for the wars between Mosaic and Netscape, and later Netscape and Internet Explorer, and even later Internet Explorer, Firefox and Chrome. Competition is good for the web. Proper competition between rendering engines won’t happen on iOS, so this is the best we’ve got.