Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

xamarin forms: System.ArgumentNullException has been thrown (IOS)

SreeeeSreeee INMember ✭✭✭✭✭

I am using webview for parsing my HTML data. For this, I am using a custom render.

In the Main Project:

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 Renderer

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)));
        }
    }
}

In XAML and XAML.cs:

<local:MyWebView 
    x:Name="web_view"
    VerticalOptions="FillAndExpand"/>

web_view.Url = htmldata;

But I am getting System.ArgumentNullException when running the project.

Screenshots:

enter image description here

I have uploaded a sample project here.

Best Answer

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    I found you 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 like what @Graverobber said:

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

    Here is the modified sample. Try to check it for the specific code.

Answers

  • GraverobberGraverobber Member ✭✭✭

    Your Element.Url is null and that's not allowed.
    It is null due to the fact that OnElementChanged is called before the url is assigned in the MainPage.
    In MainPage the url is only assigned after the request to a service is successful.
    It is btw never successful, at least in your example, because you didn't allow non https calls in your Info plist.
    Your request will need more time than the rendering of the Webview.

    From your MyWebviewRenderer remove the Control.LoadString from OnElementChanged and implement the OnElementPropertyChanged method. Check for the Url property and load it there:

    protected override void OnElementChanged(ElementChangedEventArgs<MyWebView> e)
    {
                base.OnElementChanged(e);
    
                if (Control == null)
                {
                    var config = new WKWebViewConfiguration();
                    _wkWebView = new WKWebView(Frame, config);
                    SetNativeControl(_wkWebView);
                }
            }
    
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if(e.PropertyName.Equals("Url"))
                {
                    Control.LoadHtmlString(Element.Url, null);   //use this code instead
                }
            }
    
  • SreeeeSreeee INMember ✭✭✭✭✭
    edited March 2020

    @Graverobber Tried this code, no error. But the UI is blank.

    I am expecting an output like this.

    Could you please check with the sample project I have added?

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    I found you 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 like what @Graverobber said:

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

    Here is the modified sample. Try to check it for the specific code.

  • SreeeeSreeee INMember ✭✭✭✭✭

    @LandLu Thanks, I will check this and update you.

  • GraverobberGraverobber Member ✭✭✭
    edited March 2020

    @Sreeee
    Did you allow http calls within your app?
    Or was it only for the demo that you used http?

    By default iOS blocks non secure requests you have to specify App Transport Security Settings with the Allow Abritary Loads set to true in your Info.plist.
    Like described here:
    https://www.ioscreator.com/tutorials/disable-apple-transport-security-ios-tutorial

    Otherwise the request will never work and therefore your Url will never be set, which will never trigger the OnPropertyChanged for your URL hence not loading any page.

  • SreeeeSreeee INMember ✭✭✭✭✭
    edited April 2020

    @LandLu and @Graverobber

    The default size of the webview contents is very small, video is also small. Is there any way to increase the size of content and video in webview?

Sign In or Register to comment.