locked
Xamarin Forms: Custom webview is not working in IOS RRS feed

  • Question

  • User351573 posted

    I am using Custom Webview for solving ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs. and parsing HTML data.

    My Code:

    MyWebView.cs

    using Xamarin.Forms;
    
    namespace CustomWebview
    {
        public class MyWebView : WebView
        {
            public static readonly BindableProperty UrlProperty = BindableProperty.Create(
            propertyName: "Url",
            returnType: typeof(string),
            declaringType: typeof(MyWebView),
            defaultValue: default(string));
    
            public string Url
            {
                get { return (string)GetValue(UrlProperty); }
                set { SetValue(UrlProperty, value); }
            }
        }
    }
    

    IOS

    using CustomWebview;
    using CustomWebview.iOS;
    using WebKit;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
    
    namespace CustomWebview.iOS
    {
        public class MyWebViewRenderer : ViewRenderer<MyWebView, WKWebView>
        {
            WKWebView _wkWebView;
    
            protected override void OnElementChanged(ElementChangedEventArgs<MyWebView> e)
            {
                base.OnElementChanged(e);
    
                if (Control == null)
                {
                    var config = new WKWebViewConfiguration();
                    _wkWebView = new WKWebView(Frame, config);
                    SetNativeControl(_wkWebView);
                }
                if (e.NewElement != null)
                {
                    Control.LoadHtmlString(Element.Url, null);   //use this code instead
                    //Control.LoadRequest(new NSUrlRequest(new NSUrl(Element.Url)));
                }
            }
        }
    }
    

    When I open the page having MyWebView the page redirects to Main.cs and shows the below exception.

    enter image description here

    I have uploaded a sample project here.

    Wednesday, January 22, 2020 7:48 AM

Answers

  • User351573 posted

    I found consumed a .Net Framework library in Forms project, please remove it and use .Net Standard HttpClient. Secondly, try to disable the ATS for your certain URL like:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>services.catholicbrain.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
            </dict>
        </dict>
    </dict>
    

    Finally, move the loading URL code to OnElementPropertyChanged.

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
    
        if (e.PropertyName == "Url")
        {
            Control.LoadHtmlString(Element.Url, null);
        }
    }
    

    This answer is from another XF thread of mine.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, July 15, 2020 5:13 PM

All replies

  • User369978 posted

    The error shows the method receives a null value ,it's htmlString parameter .

    Add a breakpoint at the line Control.LoadHtmlString(Element.Url, null); to check if Element.Url is null or not .

    Wednesday, January 22, 2020 9:33 AM
  • User351573 posted

    @ColeX I have hardcoded the HTML string value. In that case, the custom webview is working.

    In my project, the data is loading from a get rest API. I am getting the exception before getting the data. At reaching the below line my app is broken with this exception.

    var response = await client.GetAsync("rest api");
    

    Before setting the webview url value the app is broken.

    Wednesday, January 22, 2020 11:49 AM
  • User351573 posted

    @ColeX Could you please check this sample project? I have added a private api since the issue only when calling the api.

    Wednesday, January 22, 2020 12:53 PM
  • User369978 posted

    I see you're trying to access the http link , it is insecure website, you should turning ATS off using NSAllowsArbitraryLoads in info.plist .

    Check https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview?tabs=macos#ios-and-ats .

    Thursday, January 23, 2020 8:08 AM
  • User351573 posted

    @ColeX I have added like below in info.plist.

    But getting the same exception.

    Note: Working fine if use Webview instead of local:MyWebView and when hardcode the data.

    Thursday, January 23, 2020 8:27 AM
  • User369978 posted

    Note: Working fine if use Webview instead of local:MyWebView and when hardcode the data.

    It's not relate with custom or native webview , the problem is that we can't access the html string from the website , not the display on webview ,try to figure out the cause of that .

    Friday, January 24, 2020 2:38 AM
  • User351573 posted

    I found consumed a .Net Framework library in Forms project, please remove it and use .Net Standard HttpClient. Secondly, try to disable the ATS for your certain URL like:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>services.catholicbrain.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
            </dict>
        </dict>
    </dict>
    

    Finally, move the loading URL code to OnElementPropertyChanged.

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
    
        if (e.PropertyName == "Url")
        {
            Control.LoadHtmlString(Element.Url, null);
        }
    }
    

    This answer is from another XF thread of mine.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, July 15, 2020 5:13 PM