UIWebView Deprecation and Xamarin.Forms

Gerald Versluis

Gerald

A little while ago, Apple started sending out warning messages about the UIWebView deprecation. This has not gone unnoticed by our Xamarin.Forms users, who directly created an issue for it. Today we have some great news to share: we have a solution for you! This post will give you a bit of background about our considerations and of course, how to avoid rejection to the Apple App Store. 

The History of UIWebView 

UIWebView has already been around since iOS 2.0 but has been deprecated since iOS 8.0. Its successor, WKWebViewof course, does the same thing functionally but has some advantages over the old UIWebView. 

As soon as the UIWebView deprecation became known, the Xamarin.Forms team worked to make a replacement WKWebViewRenderer. While it has been available in Forms for a long time now, the default was still the UIWebViewRenderer. 

Shortly after the introduction of iOS 13, Apple decided to send out warning messages about the UIWebView deprecation. The warning would read:  

ITMS-90809: Deprecated API Usage – Apple will stop accepting submissions of apps that use UIWebView APIs. See https://developer.apple.com/documentation/uikit/uiwebview for more information.

After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to App Store Connect.

This warning was still a warning and would not prevent you from publishing your app at the time. A few months after this, Apple announced that as of April 2020 they reject new apps still referencing UIWebView. For updates to apps the deadline is December 2020. Of course, we want to be ready well before then, and we are.  

Maintain Backwards Compatibility for Xamarin.Forms 

With Xamarin.Forms we strive to maintain backwards compatible the best we can. This issue challenged that quite a bit. As you might know, or maybe have experienced, the linker for the iOS platform can be pretty aggressive. What it does is strip out any APIs that are not referenced from your code in order to make the resulting binary of your app smaller. 

Because of this, we thought the solution would be to simply switch the default renderer to the WKWebViewRenderer. By doing that, there would be no reference to the UIWebView anymore and it would be taken out by the linker. 

While working on this, we discovered that the linker does a fantastic job, but the Xamarin.Forms binary was excluded from linking by default. That would mean as long as the UIWebViewRenderer file would exist in our codebase, ultimately apps would be rejected. 

This was a problem, because if we want to keep up our backwards compatibility game, we couldn’t just delete the UIWebViewRenderer. This would potentially break custom renderers or other code that referenced this class implemented by Xamarin.Forms users. Therefore, we went looking for another solution. 

Xamarin.iOS Team to the Rescue 

During our quest for a solution we had multiple options. For example: making stubs or rewriting the UIWebViewRenderer to use WKWebView underneath. The most obvious option, however, would be to find out if we could make the linker work for Xamarin.Forms as well. 

We have worked closely with the Xamarin.iOS team to make that happen. On top of that, we are proud to say that we have a solution that does exactly that. 

Because Xamarin.Forms has been excluded from the linker since forever, we first want to make sure that everything continues to work as expected. Because of that, this new linker behavior is behind a feature flag for now. 

Prevent App Store Rejection, Today! 

The solution only involves three steps: 

  • Use the right versions of Xamarin.Forms and Xamarin.iOS. 
  • Add a flag to the build configuration. 
  • Build and submit your app to the App Store and celebrate! 

On the Xamarin.Forms side we also had to make some changes to make all this work correctly. These new changes are part of Xamarin.Forms 4.5, including the pre-releases. Make sure that you are using the Forms 4.5 or newer NuGet package in your projects. 

You also need to make sure that you are using Xamarin.iOS 13.10.0.17. You can check this from Visual Studio. This version of Xamarin.iOS is included with Visual Studio for Mac 8.4.1 and Visual Studio 16.4.3 and up. 

With that in place, you can simply go to your iOS project, open the project properties and add this flag in the additional mtouch arguments field: --optimize=experimental-xforms-product-type this flag works together with the Linker Behavior set to SDK Only or All. If for any reason you see errors when setting the Linker Behavior to All, this is most likely a problem within the app code or a 3rd party library that is not linker safe. For more information on the linker, please refer to the docs.

In the screenshot below you can see the end result in Visual Studio for Mac.

Filling the additional mtouch arguments field in your iOS project. Shown in Visual Studio for Mac. To prevent UIWebView deprecation.
This setting can be applied per build configuration so make sure that you put it in the right one. That will probably be the iPhone/Release build configuration which is typically used for distribution builds.

UIWebView Deprecation Fixed

That’s it! Now create a new build, submit it to the App Store and all is good.

All of this is described with a bit more detail in the documentation.

Gerald Versluis
Gerald Versluis

Software Engineer II, Xamarin.Forms

Follow Gerald   

9 comments

Leave a comment

  • Avatar
    Andrew Bailie

    I’ve just tried this on my app and just got a completely black screen after the launch screen.
    If I take out the argument everything works as expected again. Would this be the expected behaviour if one of the included nugets referenced UIWebView directly, or should the linker just include the UIWebView and allow everything to work on?
    I’ve tried this on the simulator and an iPhone.

    Visual Studio Community 2019 for Mac Version 8.4.4 (build 91)
    Xamarin.iOS Version: 13.10.0.17
    Xamarin.Forms Version 4.5.0.282-pre4

    other nugets:

    CarouselView.FormsPlugin Version 5.2.0
    Com.Airbnb.Xamarin.Forms.Lottie Version= 3.0.4Microsoft.AppCenter Version= 2.6.4
    Microsoft.AppCenter.Analytics Version= 2.6.4
    Microsoft.AppCenter.Crashes Version= 2.6.4
    Newtonsoft.Json Version 12.0.3
    Plugin.Fingerprint Version= 2.0.0-alpha.6
    Prism.Plugin.Popups Version 7.2.0.759
    SkiaSharp Version 1.68.2-preview.29
    Xam.Plugin.Connectivity Version 4.0.0.190-beta
    Xam.Plugin.DeviceInfo Version 4.2.0-beta
    Xamarin.FFImageLoading.Svg Version 2.4.11.982
    Xamarin.FFImageLoading.Svg.Forms Version 2.4.11.982
    Xamarin.FFImageLoading.Transformations Version 2.4.11.982
    Prism.Unity.Forms Version 7.2.0.1422
    ZXing.Net.Mobile Version 2.4.1
    ZXing.Net.Mobile.Forms Version 2.4.1
    Xamarin.Essentials Version 1.4.0-pre2

        • Joshua Camaioni
          Joshua Camaioni

          I am having a similar issue as Juan Cadena. This is very frustrating.

          Default constructor not found for type Xamarin.Forms.Platform.iOS.SwitchRenderer

          Please help!! I’ll keep looking for a solutions as well and post back if I find something. Thanks.

        • test 1
          test 1

          Hi Gerald Versluis,
          Note : 1. Linker Behaviour – Link All” – Worked fine with Blank and getting issue with Shell.
          2. Linker Behaviour – Don’t Link” – Getting warning mail from Apple when trying to upload to test flight.
          1. I too have an similar issue, its because of using Xamarin forms(4.5.0.356) with Shell and UIWebView Depreciation solution.
          2. So i tried with an empty shell application and its the
          error :System.MissingMethodException: ‘Default constructor not found for type Xamarin.Forms.Platform.iOS.ShellRenderer’
          3. And also i tried with blank application with UIWebView Depreciation Solution by keeping “Linker Behaviour – Link All” it’s Working fine.

          I think some issue with shell, So please help me out from this, Thanks in advance.

      • Avatar
        Andrew Bailie

        Hi Gerald,

        Sorry for the delay in getting back to you, but I was on vacation for a few weeks.

        I’m not sure if this was the same issue but it’s quite likely. I know that in debug build I just got a black screen and looking at the threads showed pretty much nothing was running, while a release build caused a full out crash.

        I just updated my Xamarin Forms and tried again and now all is good in the world.

        Visual Studio Community 2019 for Mac Version 8.4.7 (build 17)
        Xamarin.iOS Version: 13.10.0.21
        Xamarin.Forms Version 4.5.0.356

        other packages:

        CarouselView.FormsPlugin Version 5.2.0
        Com.Airbnb.iOS.Lottie Version 2.5.10
        Com.Airbnb.Xamarin.Forms.Lottie Version 3.0.4
        Microsoft.AppCenter.Analytics Version 2.6.4
        Microsoft.AppCenter.Crashes Version 2.6.4
        Microsoft.Azure.Mobile.Client Version 4.1.2
        Plugin.Fingerprint Version 1.4.9
        Prism.Plugin.Popups Version 7.2.0.759
        SkiaSharp Version 1.68.2-preview.29
        Xam.Plugin.Connectivity Version 4.0.0.190-beta
        Xam.Plugin.DeviceInfo Version 4.2.0-beta
        Xam.Plugins.Forms.KeyboardOverlap Version 1.0.0.4
        Xamarin.FFImageLoading.Svg Version 2.4.11.982
        Xamarin.FFImageLoading.Svg.Forms Version 2.4.11.982
        Xamarin.FFImageLoading.Transformations Version 2.4.11.982
        Prism.Unity.Forms Version 7.2.0.1422
        ZXing.Net.Mobile Version 2.4.1
        ZXing.Net.Mobile.Forms Version 2.4.1
        Xamarin.Essentials Version 1.5.0

        Thanks,

        Andrew