question

bags-7830 avatar image
0 Votes"
bags-7830 asked WenyanZhang-MSFT edited

Xamarin set Cookies in Multiplatform iOS app using (Hybrid)WebView

I followed example from here (https://docs.microsoft.com/en-gb/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview#invoke-c-from-javascript) to setup WebView for my project and I can invoke C# code from WebView page event, that is working fine.
However, before sending a request I have to setup a Cookie and that cookie should be passed to remote server. I followed several examples from net I am getting it to work for Android but iOS its not working.

Code I got from another Stackoverflow question as follows.

Android Working

var cookieManager = CookieManager.Instance;
cookieManager.SetAcceptCookie(true);
cookieManager.RemoveAllCookie();
var cookies = UserInfo.CookieContainer.GetCookies(new System.Uri(AppInfo.URL_BASE));
for (var i = 0; i < cookies.Count; i++)
{
    string cookieValue = cookies[i].Value;
    string cookieDomain = cookies[i].Domain;
    string cookieName = cookies[i].Name;
    cookieManager.SetCookie(cookieDomain, cookieName + "=" + cookieValue);
}


iOS Not Working

// Set cookies here
var cookieUrl = new Uri(AppInfo.URL_BASE);
var cookieJar = NSHttpCookieStorage.SharedStorage;
cookieJar.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;
foreach (var aCookie in cookieJar.Cookies)
{
    cookieJar.DeleteCookie(aCookie);
}

var jCookies = UserInfo.CookieContainer.GetCookies(cookieUrl);
IList<NSHttpCookie> eCookies = 
                   (from object jCookie in jCookies 
                    where jCookie != null 
                    select (Cookie) jCookie 
                    into netCookie select new NSHttpCookie(netCookie)).ToList();
cookieJar.SetCookies(eCookies.ToArray(), cookieUrl, cookieUrl);


I have tried code from WebView documentation here, Cookie section (https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview?tabs=macos#cookies)


In my HybridWebViewRenderer method I am adding my custom Cookie as follows.


protected override void OnElementChanged(VisualElementChangedEventArgs e)
 {

    base.OnElementChanged(e);

    if (e.OldElement != null)
    {
        userController.RemoveAllUserScripts();
        userController.RemoveScriptMessageHandler("invokeAction");
        HybridWebView hybridWebView = e.OldElement as HybridWebView;
        hybridWebView.Cleanup();
    }

    if (e.NewElement != null)
    {
        string cookieDomain = new System.Uri(((HybridWebView)Element).Uri).Host;

        foreach (var c in NSHttpCookieStorage.SharedStorage.Cookies)
        {
            Console.WriteLine("Cookie (Delete)" + c.Name);
            NSHttpCookieStorage.SharedStorage.DeleteCookie(c);
        }
            

        var cookieDict = new NSMutableDictionary();
        cookieDict.Add(NSHttpCookie.KeyDomain, new NSString("." + cookieDomain));
        cookieDict.Add(NSHttpCookie.KeyName, new NSString("ABC"));
        cookieDict.Add(NSHttpCookie.KeyValue, new NSString("123e4567-e89b-12d3-a456-426652340003"));
        cookieDict.Add(NSHttpCookie.KeyPath, new NSString("/"));
        cookieDict.Add(NSHttpCookie.KeyExpires, DateTime.Now.AddDays(1).ToNSDate());

        var myCookie = new NSHttpCookie(cookieDict);

        NSHttpCookieStorage.SharedStorage.SetCookie(myCookie);

        string filename = $"{hybridView.Uri}";

        var request = new NSMutableUrlRequest(new NSUrl(filename));

        var wkNavigation = LoadRequest(request);
    }
 }


In AppDelegate I have added.

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
 {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());

            NSHttpCookieStorage.SharedStorage.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;

            return base.FinishedLaunching(app, options);
  }


Still no luck :( .........

I'll really appreciate if anybody can point out what I am doing wrong any hints.
Thanks.

dotnet-xamarinformsdotnet-ios
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I have tried code from WebView documentation here, Cookie section (https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview?tabs=macos#cookies)

You could set the cookie in WebView (Forms) directly, I test in iOS, it works. And it won't break the Custom Renderers that invoke C# code from WebView page event.

In Safari Develop mode, I check the Cookies under Storage, XamarinCookie is in the list. I'm not clear if there is someting missing , you could share more information about your practice.

0 Votes 0 ·

Xaml

 <StackLayout>
         <local:MyWebView x:Name="MyWebview" WidthRequest="400" HeightRequest="500"></local:MyWebView>
         <Button Text="click to load" Clicked="Button_Clicked"></Button>
     </StackLayout>

Code

  private void Button_Clicked(object sender, EventArgs e)
             {
                 CookieContainer cookieContainer = new CookieContainer();
                 Uri uri = new Uri("https://dotnet.microsoft.com/apps/xamarin", UriKind.RelativeOrAbsolute);
    
             Cookie cookie = new Cookie
             {
                 Name = "XamarinCookie",
                 Expires = DateTime.Now.AddDays(1),
                 Value = "My cookie",
                 Domain = uri.Host,
                 Path = "/"
             };
             cookieContainer.Add(uri, cookie);
             MyWebview.Cookies = cookieContainer;
             MyWebview.Source = new UrlWebViewSource { Url = uri.ToString() };
         }
0 Votes 0 ·

0 Answers