Clients often want their website available in the app store, mostly just for app store presence. I got asked to do app wrapping at work a while ago, because the client purchased a tool that did not have a native app available, only a mobile website. It just had to be made available in the internal app store. Colleagues had to be able to install it by themselves and use it on their own devices without too much fuzz.
In this post I want to show you some of the hurdles while developing a website wrapper and how to overcome them.
What is app wrapping?
It’s how I call packaging a website into an app. Wrapping a website into an app. Or just wrapping an app around a website. Hence, app wrapping. It’s actually just a form of hybrid app where you make a website available as an app.
When you are dealing with internal apps, you often have an internal app store available that is provided by an MDM (Mobile Device Management) solution. A few examples of these are Mobile Iron, AirWatch, Microsoft Intune and many more. In my case there is a mobile browser available, provided by the MDM solution as well, which sets up a secure tunnel to the intranet website that the client wanted to package as an app.
So you can already see that internal apps have to deal with different constraints than public apps.
There is only a requirement to support iOS in this case, so I’m using Xamarin.iOS for this one. You could easily extend the solution to Xamarin Forms by creating the appropriate renderers.
Show the website full screen
First thing to do when app wrapping is show the website in a full screen browser. You don’t get a navigation bar like a normal browser in this case, so this poses a few requirements on your mobile website:
- Supply navigation on all pages
- Show a back button at all times
In the main Storyboard, you need to create a Web View (UIWebView) that spans the whole screen, so set the constraints accordingly. Then in the controller, use the ViewDidLoad method to load the website:
In this snippet, you can see I did some other settings as well. First is supplying a background color that matches the background of the website that is loaded. This is to prevent a white flash while loading the website. Secondly, I disable the bouncing of the default browser, so the website feels more like an actual app.
This is an internal website, so there are 2 different kind of links available:
- Intranet pages – these need to be handled by our MDM browser
- Internet pages – these can be handled by the normal browser
The UIWebView has a method ShouldStartLoad that can check which link is about to be opened, and allow you to handle the request yourself.
You can notify the UIWebView that you handled the request yourself, by returning false from this method. In that case, the UIWebView won’t handle the request anymore.
To open a different app on iOS, you can leverage app schemes:
In the snippet above, I did a naive implementation to change http:// and https:// to the required app scheme. The mdmbrowser:// scheme is different depending on the app you want to open. A different MDM provider, means a different scheme.
So if you want to open a URL in Safari, outside of your app, you can do the same thing but leave the http:// or https:// scheme.
Dealing with impossible requests
It’s not all about opening links though. Sometimes theres an action that’s you want to prevent or leverage in your app. In my case I had to prevent users from changing their password through the app wrapper. For this, you can once again leverage the ShouldStartLoad method:
This example shows that you can actually do whatever you want, depending on the request that comes in. In my case, that’s just showing an alert to the user that the action is not possible. And in the end returning false so that the UIWebView won’t deal with the request.
Apple App Store rejection?
If you try to submit these kinds of apps to the public App Store without a lot of added functionality, Apple will most likely reject it based on their Minimum Functionality rule which states:
Your app should include features, content, and UI that elevate it beyond a repackaged website. If your app is not particularly useful, unique, or “app-like,” it doesn’t belong on the App Store.
— App Store Review Guidelines, by Apple Developer
But for internal purposes you don’t have to deal with Apple’s review process, so you have more opportunities and no risk for rejection there.
There are still some other things to keep in mind. On iOS, you can’t open http:// schemes in an app without configuring ATS. If you have a file upload somewhere, make sure that you include the permissions to use the camera and/or photo library in your Info.plist. If you don’t, your app will crash.
Checking the reachability of the website is an important part as well. You should show the users an appropriate message when they don’t have an internet connection, the VPN tunnel isn’t available or the website they’re trying to open is down.
So it is certainly possible to do app wrapping with Xamarin, but I’m not sure if using Xamarin is actually the best possible approach. Which techniques do you use for app wrapping? Please leave a comment!