How to get Stadia running on iOS
Everyone is pretty frustrated that Apple doesn’t allow services like Stadia on the Appstore. It’s a nice service that should be allowed to run everywhere.
Luckily I have found a workaround to get Stadia running on your iOS device. Today I will explain how it works and provide you guys with a sample project that you can tinker with.
It’s also possible to create a custom controller overlay so you can play on the device without a controller.
Note: this source is not pretty. It serves as a proof of concept for others to build upon.
But first, we need to overcome these main challenges;
- We can access stadia only from specific browsers so we need to alter our user-agent so we can access the stadia service.
- We need someway to login to our Google Account and redirect to stadia
- WKWebView has crappy controller support its a hit or miss situation, we need to come up with a “better” way to support the Gamepad API.
The first problem is easily solvable we check the user-agent of a device that is allowed to visit stadia.google.com and we copy that specific user-agent in our browser.
The controller was a hard problem. Safari on iOS supports the Gamepad API natively but on my device, it would never connect; and if it did it would stop working randomly.
My current solution is to provide the data to javascript myself and hijack the Navigators.getGamepads()
function and emulate a controller so we can decide when it is connected/disconnected.
Taking Control
First, we will make a model so that we can represent the controller as the Navigator.getGamepads()
function would normally do.
We can now build our custom controller script. We can read our controllers using GameController
framework provided by Apple. We then parse that into our models. Since the buttons need to be in a certain order we construct it in the following way.
*We assume that we want to take control over the first connected controller, we also only support one controller.
In my testing, the timestamp
isn’t needed so I left it blank. Feel free to create the implementation to fully emulate the official API. We have our controller data ready all that’s left is create a bridge of communication between our iOS app and a WKWebView
that runs Stadia.
Using WKWebView
in iOS14, we can add an addScriptMessageHandler
this allows us to communicate with Javascript and return a Promise
this will help us in hijacking the Navigators.getGamepads()
function and return our custom data.
Using the following javascript we can emulate a fake controller. We hijack the method. Every time it’s accessed we call a messageHandler
that will give us our controller data over a Promise
and override the last known state. (This means that we are out of sync for one frame but we won’t notice this in-game)
We will create a class with a method that can load up a file (as String) and a method that can setup a WKWebView so that it can run our custom code
Generally what happens is whenever we call setup(webview: WKWebView)
we execute the javascript we wrote earlier overriding the Navigators.getGamepads()
function. Whenever this function is called we now call our app code and land in the usercontentController
callback where we return our current controller state.
Voila, we should have a consistent working controller in any WKWebView
.
Back to Stadia
Getting Stadia to work now isn’t a lot of work anymore we first start by creating a UIViewController
with a WKWebView
. In my tests we need to have a valid iOS user-agent to login our Google account. Using a custom agent only is needed to access Stadia. Luckily WKWebView
has us covered.
We create a custom configuration adding our controller as a ScriptMessageHandler
make sure that the name cross matches with the name used in our javascript script earlier!
Using the WKNavigationDelegate
we can check if we are currently logged in or that we are currently still busy trying to login.
Whenever we are logged in we navigate to Stadia automatically, if we are on our destination we start the javascript magic and voila stadia runs in full screen on iOS with controller support.
There you have it a working solution on playing your Stadia games right on iOS device. There are some things that could be done to make it nicer but the core functionality is there.
This touches a different subject than I normally do on Medium. It was a fun problem to figure out.
I opened up the repo here: https://github.com/Plnda/Gradia please submit any PR’s if you’d like so we can collaborate together on this app
Here at Pinch, we experiment to make our apps even better. Do you have any questions or remarks? Let us know in the comments.