Web Views in Xamarin.iOS
Over the lifetime of iOS Apple has released a number of ways for app developers to incorporate web view functionality in their apps. Most users utilize the built-in Safari web browser on their iOS device, and therefore expect that web-view functionality from other apps is consistent with this experience. They expect the same gestures to work, the performance to be on par, and the functionality the same.
iOS 11 introduced new changes to both
SFSafariViewController. For more information on these, see the Web changes in iOS 11 guide guide.
WKWebView was introduced in iOS 8 allowing app developers to implement a web browsing interface similar to that of mobile Safari. This is due, in part, to the fact that
WKWebView should always be used over UIWebView where possible due to the increased performance, built in user-friendly gestures, and the ease of interaction between the web page and your app.
WKWebView can be added to your app in an almost identical way to UIWebView, however as the developer you have much more control over the UI/UX and functionality. Creating and displaying the web view object will display the requested page, however you can control how the view is presented, how the user can navigate, and how the user exits the view.
The code below can be used to launch a
WKWebView in your Xamarin.iOS app:
WKWebView webView = new WKWebView(View.Frame, new WKWebViewConfiguration()); View.AddSubview(webView); var url = new NSUrl("https://docs.microsoft.com"); var request = new NSUrlRequest(url); webView.LoadRequest(request);
It is important to note that
WKWebView is in the
WebKit namespace, so you will have to add this using directive to the top of your class.
WKWebView can also be used in Xamarin.Mac apps, and you should use it if you are creating a cross-platform Mac/iOS app.
SFSafariViewController is the latest way to provide web content from your app and is available in iOS 9 and later. Unlike
SFSafariViewController is a View Controller and so cannot be used with other views. You should present
SFSafariViewController as a new View Controller, in the same way you would present any View Controller.
SFSafariViewController is not accessible to your app. Your app will not have access to any of the default Safari features.
It also, by default, implements a Done button, allowing to user to easily return to your app, and forward and back navigation buttons, allowing your user to navigate through a stack of web pages. In addition, it also provides the user with an address bar giving them the peace of mind that they are on the expected web page. The address bar does not allow the user to change the url.
These implementations cannot be changed, so
SFSafariViewController is ideal to use as the default browser if your app wants to present a webpage without any customization.
The code below can be used to launch a
SFSafariViewController in your Xamarin.iOS app:
var sfViewController = new SFSafariViewController(url); PresentViewController(sfViewController, true, null);
This produces the following web view:
It is also possible to open the mobile Safari app from within your app, by using the code below:
var url = new NSUrl("https://docs.microsoft.com"); UIApplication.SharedApplication.OpenUrl(url);
This produces the following web view:
Navigating users away from your app to Safari should generally always be avoided. Most users will not expect navigation outside of your application, so if you navigate away from your app, users may never return it, essentially killing engagement.
iOS 9 improvements allow the user to easily return to your app through a back button that is provided in the top left corner of the Safari page.
App Transport Security
App Transport Security, or ATS was introduced by Apple in iOS 9 to ensure that all internet communications conform to secure connection best practices.
For more information on ATS, including how to implement it in your app, refer to the App Transport Security guide.
UIWebView is Apple's legacy way of providing web content in your app. It was released in iOS 2.0, and has been deprecated as of 8.0.
UIWebView is deprecated. New apps using this control will not be accepted into the
App Store as of April 2020, and apps updates using this control will not be accepted by December 2020.
If you are looking for resources in regard to the
UIWebView deprecation warning (ITMS-90809) while using Xamarin.Forms, please refer to the Xamarin.Forms WebView documentation.
Developers who submitted iOS applications in the last six months (or so) might have received a warning from the App Store, about
UIWebView being deprecated.
Deprecations of APIs are common. Xamarin.iOS uses custom attributes to signal those APIs (and suggest replacements when available) back to the developers. What is different this time, and much less common, is that the deprecation will be enforced by Apple's App Store at submission time.
Unfortunately, removing the
UIWebView type from
Xamarin.iOS.dll is a binary breaking change. This change will break existing 3rd party libraries, including some that might not be supported or even re-compilable anymore (for example, closed source). This will only create additional problems for developers. Therefore, we are not removing the type yet.
Starting with Xamarin.iOS 13.16 new detection and tools are available to help you migrate from
If you have'nt recently submitted an iOS application to the Apple App Store, you might wonder if this situation applies to your application(s).
To find out, you can add
--warn-on-type-ref=UIKit.UIWebView to your project's Additional mtouch arguments. This will warn of any reference to the deprecated
UIWebView inside your application (and all its dependencies). Different warnings are used to report types before and after the managed linker has executed.
The warnings, like others, can be turned into errors using
-warnaserror:. This can be useful if you want to ensure a new dependency to
UIWebView is not added after your verifications. For example:
-warnaserror:1502will report errors if any references are found in pre-linked assemblies.
-warnaserror:1503will report errors if any references are found in post-linked assemblies.
You can also silence the warnings if either the pre/post linking results are not useful. For example:
-nowarn:1502will not report warnings if any references are found in pre-linked assemblies.
-nowarn:1503will not report warnings if any references are found in post-linked assemblies.
Every application is unique. Removing
UIWebView from your application can require different steps depending on how and where it is used. The most common scenarios are as follows:
- There is no use of
UIWebViewinside your application. Everything is fine. You should not have warnings when submitting to the AppStore. Nothing else is required from you.
- Direct usage of
UIWebViewby your application. Start by removing your use of
UIWebView, for example, replace it with the newer
WKWebView(iOS 8) or
SFSafariViewController(iOS 9) types. Once this is completed the managed linker should not see any reference to
UIWebViewand the final app binary will have no trace of it.
- Indirect usage.
UIWebViewcan be present in some third party libraries, either managed or native that is used by your application. Start by updating your external dependencies to their latest versions since this situation might already be solved in a newer release. If not, contact the maintainer(s) of the libraries and ask about their update plans.
Alternatively, you could try the following approaches:
- If you're using Xamarin.Forms, then read this blog post.
- Enable the managed linker (on the whole project or, at least, on the dependency using
UIWebView) so it might be removed, if not referenced. That will solve the problem but might required additional work to make your code linker-safe.
- If you are unable to change the managed linker settings, see the special cases below.
Applications cannot use the linker (or change its settings)
If for some reason you are not using the managed linker (for example, Don't link) then the
UIWebView symbol will remain in the binary app you submit it to Apple and it might be rejected.
A forceful solution is to add
--optimize=force-rejected-types-removal to your project's Additional mtouch arguments. This will remove traces of
UIWebView from the application. However, any code that refers to the type will not work properly (expect exceptions or crashes). This approach should be used only if you're sure that the code is not reachable at runtime (even if it was reachable through static analysis).
Support for iOS 7.x (or earlier)
UIWebView has been part of iOS since v2.0. The most common replacements are
WKWebView (iOS 8) and
SFSafariViewController (iOS 9). If your application still supports older iOS versions you should consider the following options:
- Make iOS 8 your minimum target version (a build time decision).
- Only use
WKWebViewif the app is running on iOS 8+ (a runtime decision).
Applications not submitted to Apple
If your application isn't submitted to Apple, you should plan to move away from the deprecated API since it can be removed in future iOS releases. However, you can do this transition using your own timetable.