{"id":46193,"date":"2020-02-10T09:06:21","date_gmt":"2020-02-10T17:06:21","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/xamarin\/?p=46193"},"modified":"2020-03-04T02:23:56","modified_gmt":"2020-03-04T10:23:56","slug":"uiwebview-deprecation-xamarin-forms","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/uiwebview-deprecation-xamarin-forms\/","title":{"rendered":"UIWebView Deprecation and Xamarin.Forms"},"content":{"rendered":"<p><span data-contrast=\"auto\">A little while ago, Apple started sending out warning messages about the <\/span><code><span data-contrast=\"auto\">UIWebView<\/span><\/code> deprecation<span data-contrast=\"auto\">. This has\u00a0<\/span><a href=\"https:\/\/github.com\/xamarin\/Xamarin.Forms\/issues\/7323\"><span data-contrast=\"none\">not gone unnoticed<\/span><\/a><span data-contrast=\"auto\">\u00a0by our\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0users, who directly created an issue for it. Today we have some great news to\u00a0share:\u00a0we 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.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">The History of\u00a0UIWebView<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><a href=\"https:\/\/docs.microsoft.com\/xamarin\/ios\/user-interface\/controls\/webview#uiwebview-deprecated\"><span data-contrast=\"none\">UIWebView<\/span><\/a><span data-contrast=\"auto\"> has already been around since iOS 2.0 but <\/span><span data-contrast=\"auto\">has<\/span><span data-contrast=\"auto\">\u00a0been deprecated since iOS 8.0. Its successor, <\/span><a href=\"https:\/\/docs.microsoft.com\/xamarin\/ios\/user-interface\/controls\/webview#wkwebview\"><span data-contrast=\"none\">WKWebView<\/span><\/a><span data-contrast=\"auto\">,\u00a0<\/span><span data-contrast=\"auto\">of course,<\/span><span data-contrast=\"auto\">\u00a0does the same thing\u00a0<\/span><span data-contrast=\"auto\">functionally but<\/span><span data-contrast=\"auto\">\u00a0has some advantages over the old\u00a0<\/span><code><span data-contrast=\"auto\">UIWebView<\/span><\/code><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">As soon as the\u00a0<\/span><code><span data-contrast=\"auto\">UIWebView<\/span><\/code> <span data-contrast=\"auto\">deprecation became known, the\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0team\u00a0<\/span><span data-contrast=\"auto\">worked to make a replacement\u00a0<\/span><code><span data-contrast=\"auto\">WKWebViewRenderer<\/span><\/code><span data-contrast=\"auto\">. While it has been available in Forms for a long time now, the default was still the\u00a0<\/span><code><span data-contrast=\"auto\">UIWebViewRenderer<\/span><\/code><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Shortly after the introduction of iOS 13, Apple decided to send out warning messages about the <\/span><code><span data-contrast=\"auto\">UIWebView <\/span><\/code>deprecation<span data-contrast=\"auto\">. The warning would read:\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<blockquote><p>ITMS-90809: Deprecated API Usage &#8211; Apple will stop accepting submissions of apps that use\u00a0UIWebView\u00a0APIs. See\u00a0<a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uiwebview\">https:\/\/developer.apple.com\/documentation\/uikit\/uiwebview<\/a>\u00a0for more information.<\/p>\n<p>After you\u2019ve corrected the issues, you can use\u00a0Xcode\u00a0or Application Loader to upload a new binary to App Store Connect.<\/p><\/blockquote>\n<p><span data-contrast=\"auto\">This warning was still a warning and would not prevent you from publishing your app at the time. A few months after this,\u00a0<\/span><a href=\"https:\/\/developer.apple.com\/news\/?id=12232019b\"><span data-contrast=\"none\">Apple announced<\/span><\/a><span data-contrast=\"auto\">\u00a0that as of April 2020 they reject new apps still referencing\u00a0<\/span><code><span data-contrast=\"auto\">UIWebView<\/span><\/code><span data-contrast=\"auto\">. For updates to apps the deadline is December 2020. Of course, we want to be ready well before then, and we are.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Maintain Backwards Compatibility for\u00a0Xamarin.Forms<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">With\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0we 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\u00a0pretty 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.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Because of this, we thought the solution would be to simply switch the default renderer to the\u00a0<\/span><code><span data-contrast=\"auto\">WKWebViewRenderer<\/span><\/code><span data-contrast=\"auto\">. By doing that, there would be no reference to the\u00a0<\/span><code><span data-contrast=\"auto\">UIWebView<\/span><\/code><span data-contrast=\"auto\">\u00a0anymore and it would be taken out by the linker.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">While working on this, we discovered that the linker does\u00a0<\/span><span data-contrast=\"auto\">a fantastic<\/span><span data-contrast=\"auto\">\u00a0job, but the\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0binary was excluded from linking by default. That would mean\u00a0<\/span><span data-contrast=\"auto\">as long as<\/span><span data-contrast=\"auto\">\u00a0the\u00a0<\/span><code><span data-contrast=\"auto\">UIWebViewRenderer<\/span><\/code><span data-contrast=\"auto\">\u00a0file would exist in our codebase, ultimately apps would be rejected.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">This was a problem, because if we want to keep up our backwards compatibility game, we couldn\u2019t just delete the\u00a0<\/span><code><span data-contrast=\"auto\">UIWebViewRenderer<\/span><\/code><span data-contrast=\"auto\">. This would potentially break custom renderers or other code that referenced this class implemented by\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0users. Therefore, we went looking for another solution.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">Xamarin.iOS<\/span><span data-contrast=\"none\">\u00a0Team to the Rescue<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">During our quest for a solution we had multiple options. For example: making stubs or rewriting the\u00a0<\/span><code><span data-contrast=\"auto\">UIWebViewRenderer<\/span><\/code><span data-contrast=\"auto\">\u00a0to use\u00a0<\/span><code><span data-contrast=\"auto\">WKWebView<\/span><\/code><span data-contrast=\"auto\">\u00a0underneath. The most obvious\u00a0<\/span><span data-contrast=\"auto\">option,<\/span><span data-contrast=\"auto\">\u00a0however, would be to find out if we could make the linker work for\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0as well.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">We have worked closely with the\u00a0<\/span><span data-contrast=\"auto\">Xamarin.iOS<\/span><span data-contrast=\"auto\">\u00a0team to make that happen. On top of that, we are proud to say that we have a solution that does exactly that.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Because\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0has 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.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Prevent App Store Rejection, Today!<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">The solution only involves three steps:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Use the right versions of\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0and\u00a0Xamarin.iOS.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559737&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">Add a flag to the build configuration.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559737&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"3\" data-aria-level=\"1\"><span data-contrast=\"auto\">Build and submit your app to the App Store and celebrate!<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559737&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">On the\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a0side we also had to make some changes to make all this work correctly. These new changes are part of\u00a0<\/span><span data-contrast=\"auto\">Xamarin.Forms<\/span><span data-contrast=\"auto\">\u00a04.5, including the pre-releases. Make sure that you are using the <strong>Forms 4.5 or newer<\/strong> NuGet package in your projects.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">You also need to make sure that you are using\u00a0<\/span><strong>Xamarin.iOS\u00a013.10.0.17<\/strong><span data-contrast=\"auto\">. You can check this from\u00a0<\/span><span data-contrast=\"auto\">Visual<\/span><span data-contrast=\"auto\">\u00a0Studio.<\/span><span data-contrast=\"auto\">\u00a0This version of\u00a0<\/span><span data-contrast=\"auto\">Xamarin.iOS<\/span><span data-contrast=\"auto\">\u00a0is included with Visual Studio for Mac 8.4.1 and <a href=\"https:\/\/devblogs.microsoft.com\/xamarin\/visual-studio-2019-version-16-4\/\" target=\"_blank\" rel=\"noopener noreferrer\">Visual Studio 16.4.3<\/a> and up.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">With that in place, you can simply go to your iOS project, open the project properties and add this flag in the\u00a0<\/span><b><span data-contrast=\"auto\">additional\u00a0<\/span><\/b><b><span data-contrast=\"auto\">mtouch<\/span><\/b><b><span data-contrast=\"auto\">\u00a0arguments<\/span><\/b><span data-contrast=\"auto\"> field:<\/span> <code>--optimize=experimental-xforms-product-type<\/code> this flag works together with the <strong>Linker Behavior<\/strong> set to <strong>SDK Only <\/strong>or<strong> All<\/strong>. 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 <a href=\"https:\/\/docs.microsoft.com\/xamarin\/ios\/deploy-test\/linker\">the docs<\/a>.<\/p>\n<p>In the screenshot below you can see the end result in Visual Studio for Mac.<\/p>\n<p><figure id=\"attachment_46646\" aria-labelledby=\"figcaption_attachment_46646\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"wp-image-46646 size-large\" src=\"http:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2020\/02\/75816341-507b7580-5d95-11ea-84e0-badd6d376cdd-1024x751.png\" alt=\"Filling the additional mtouch arguments field in your iOS project in Visual Studio for Mac screenshot\" width=\"640\" height=\"469\" srcset=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2020\/02\/75816341-507b7580-5d95-11ea-84e0-badd6d376cdd-1024x751.png 1024w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2020\/02\/75816341-507b7580-5d95-11ea-84e0-badd6d376cdd-300x220.png 300w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2020\/02\/75816341-507b7580-5d95-11ea-84e0-badd6d376cdd-768x563.png 768w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2020\/02\/75816341-507b7580-5d95-11ea-84e0-badd6d376cdd-1536x1126.png 1536w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2020\/02\/75816341-507b7580-5d95-11ea-84e0-badd6d376cdd.png 1926w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"figcaption_attachment_46646\" class=\"wp-caption-text\">Filling the additional mtouch arguments field in your iOS project in Visual Studio for Mac screenshot<\/figcaption><\/figure><\/p>\n<p>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. Also make sure the Linker behavior is set to either SDKs only or Link All.<\/p>\n<h3>UIWebView Deprecation Fixed<\/h3>\n<p>That\u2019s it! Now create a new build, submit it to the App Store and all is good.<\/p>\n<p><span data-contrast=\"auto\">All of this is described with a bit more detail<\/span><span data-contrast=\"auto\">\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/xamarin\/xamarin-forms\/user-interface\/webview#uiwebview-deprecation-and-app-store-rejection-itms-90809\"><span data-contrast=\"none\">in the documentation<\/span><\/a><span data-contrast=\"auto\">.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Background about Apple started sending out warning messages about the UIWebView deprecation, and of course, how to avoid rejection to the Apple App Store. <\/p>\n","protected":false},"author":13350,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,367],"tags":[7775,6,7773,7774,7776],"class_list":["post-46193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-xamarin","category-xamarin-forms","tag-deprecation","tag-ios","tag-mtouch","tag-uiwebview","tag-wkwebview"],"acf":[],"blog_post_summary":"<p>Background about Apple started sending out warning messages about the UIWebView deprecation, and of course, how to avoid rejection to the Apple App Store. <\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/46193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/13350"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=46193"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/46193\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=46193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=46193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=46193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}