Significant drop in performance after migrating from UIWebView to WKWebView - xamarin

The project I'm working on was using Xamarin Forms (3.4.0.x) Cross Platform, so obviously the iOS app had the UIWebView built in.
We decided to migrate to WKWebView, which required the Xamarin Forms 4.4 update so we proceeded to do that then added [assembly: ExportRenderer(typeof(WebView), typeof(Xamarin.Forms.Platform.iOS.WkWebViewRenderer))] to the AssemblyInfo.cs in our iOS app, like it says to do here. https://github.com/xamarin/Xamarin.Forms/pull/3346
Now I think that's all I need to do completely migrate to WK, but I have noticed that the app has slowed down significantly, taking ~5x as long to load a page, and on top of that, this loading icon stays on the screen even after the page is done loading
My questions are:
Did I migrate correctly, or are there any steps I'm missing/did wrong? Has anyone run into this loading icon problem before? Please ask me to clarify if I'm leaving information out, I'm new to Xamarin Forms so I'm not sure how to ask the best questions, and this is a big project I'm being introduced to. I have been told there is no custom iOS WebView Renderer though, so everything is done using the default WebView.
Thanks!

It is a native iOS issue caused because of the time it takes to detect phone numbers on the web page. So if you just disable that detection, it should work better.
Here's a sample of how you can do it in Xamarin:
var urlRequest = new NSUrlRequest(new NSUrl("https://www.gooogle.com"));
var config = new WebKit.WKWebViewConfiguration();
config.DataDetectorTypes = WebKit.WKDataDetectorTypes.Address;
var frame = new CoreGraphics.CGRect();
var webView = new WebKit.WKWebView(frame, config);
webView.LoadRequest(urlRequest);
If you followed the link you shared, you should be able to put the code inside the SetElement function of the WkWebViewRenderer. So your code would look like this:
var config = new WebKit.WKWebViewConfiguration();
config.DataDetectorTypes = WebKit.WKDataDetectorTypes.Address;
WebView = new WebKit.WKWebView(WebView.Frame, config);

There's an easier solution that just went public from the Xamarin team. All you need to do is update the Forms Nuget, Visual Studio, and Xamarin.iOS, and then:
... go to your iOS project, open the project properties and add this flag in the additional mtouch arguments field: --optimize=experimental-xforms-product-type.

Related

Default WebView for Xamarin Forms iOS?

So I'm trying to migrate from using UIWebView to WKWebView for Xamarin Forms iOS but I have a few questions because this all seems to be pretty new and none of the resources are helping me online.
https://github.com/xamarin/Xamarin.Forms/pull/7367
I came across this link though, and apparently the WKWebview is not the default for Xamarin.Forms for 4.0+ and so,
1) I'm currently using Xamarin Forms 3.4.0.x. From my understanding, is all I have to do to get the WKWebView upgrading to 4.4.0.991477, the latest build?
2) Follow up to question 1, how would I not change any code because my cs files contain "using UIKit", which is the namespace for UIWebView, is it not?
3) In this link, it seems like there is no design change at all.. but I thought that WKWebView contained a URL link at the top of the page, which UIWebView does not, which is correct?
Thanks!
1) If you have only cross-platform code, then yes there is nothing that you need to worry about, it just works.
2) As you suggest that you have UIKit in your code, then obviously that won't work. UIKit is not Xamarin.Forms API and basically you don't use Xamarin.Forms in this case, but rather Xamarin.iOS.
3) Neither of those controls display URL.

Xamarin Forms Native embedding Memory issue

I am trying to use Xamarin Forms pages in a Xamarin IOS Native app. To do that I am using the CreateViewController. The issue I am facing is that every time I push a new view controller, memory are allocated that are not released when I click on the back button. This results in that the app will crash. Is this the wrong way to do it?
var _historyViewController = new HistoryPage().CreateViewController();
// And push it onto the navigation stack
_navigation.PushViewController(_historyViewController, true);
Link to code: https://github.com/toupilsner/XamarinFormsEmbedded/blob/master/README.md

Navigating from xamarin multi-platform page to iOS or android page

I'm trying to follow this tutorial on creating a login page using Auth0: https://auth0.com/docs/quickstart/native/xamarin/01-login#handing-the-callback-url and noticed that the tutorial creates two separate login pages for android and iOS, as if they are two separate apps/projects/solutions. But my app is supposed to be compatible with both android and iOS, so I created a forms page under RoseySports.ios called Login_iOS (As indicated in screenshot 1) and would like to test it out to see if the login page works, but cannot seem to find a way to set the MainPage as Login_iOS (screenshot 2). I would like for it to be so that if a device is running iOS, it will redirect the user to the iOS version of the login page, and vice versa for android. Sorry if I'm not using the correct terminology when describing my issue. The reason I had to create two separate login pages for iOS and android was because i had to use using Auth0.OidcClient; as there are separate Nuget packages for the iOS solution and Android solution, which doesn't work when trying to put it on the main project (the one compatible for both iOS and Android).
And please let me know if there's a way to make just one login page for both platforms using Auth0.
UPDATE:
This is what I've done now, but I'm getting an error at MainPage = new RoseySports.Login_iOS(); saying that Login.iOS does not exist in the namespace RoseySports. This is the rest of the code:
`switch(Device.RuntimePlatform)
{
case Device.iOS:
MainPage = new RoseySports.Login_iOS();
break;
case Device.Android:
MainPage = new Login_Page();
break;
}`
You have multiple questions and in StackOverflow you should not ask them in one question, but let's try to address them:
Pages are only graphic elements and there is no need to implement separate graphic elements in iOS and Android in most cases, and yours doesn't look like a valid one for that
In general you can implement some code as platform specific. If you are using shared projects you can use conditional compiling, if not then dependency injection
You can use some of the technics above to do what you wanted to do (have different versions of pages per platform)

Configure platform page with platform specific options

We've begun evaluating Xamarin for a up and coming project involving both iOS and Android, with the overriding intention to produce a single UI layer (and some share code, obviously) (I'm also new to C#)
TL;DR
I've begun exploring Xamarin on iOS. I started with the Phoneword example and it worked well enough.
The first issue I found was running the code on the iPhone X, which I was able to solve by using MainPage.On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true); in the platform App class
While testing this, I noticed some issues with the ListView not scrolling properly (the core issue was actually with the platform padding).
I then used (MainPage as Xamarin.Forms.NavigationPage).On<iOS>().EnableTranslucentNavigationBar(); to enable translucent navigation bars (as we're targeting iOS 11+) and now everything appears under the navigation bar.
This is easily fixed in xCode and after some research I've found that I need to be using UIKit.UIViewController.EdgesForExtendedLayout Property, the immediate problem I'm facing is, the only "snippets" of code I can find are from the View is displayed under status bar in iOS 7 and EdgesForExtendedLayout doesn't help forum post.
Issue at hand...
The example solution snippets posted seem to be making use of a platform (iOS) specific solution. The problem is, I want to keep using the "cross-platform" code in the "platform" project and simply provide some custom configuration for the iOS platform which can apply these states.
I understand it could be possible to use a renderer, but this seems to counter-interactive, as I'd need one for both iOS and Android, where the platform page is doing just fine as it.
I understand that I could setup a DependencyService, but this seems annoying to have to include a specific "configuration" service just to solve this issue for iOS
I was hoping it might be possible to setup a iOS Page which would "override" some of the functionality of the platform page and would allow me to make use of things like viewDidLoad so I can apply the iOS specific configurations on a page by pages bases, so we could keep the platform page as it, but when running under iOS, it would provide me access to iOS life cycle of the actual view...
I've been trying to search the documentation and tutorials and haven't yet come across anything which would seem to do this or something similar (not to say there isn't one, but I'm just not finding it).

How do I create a mapview with titanium appcelerator mobile?

I just start to work with appcelerator and I haven't found a good layout tutorial yet.
At the moment I try to show a mapview with a specific location. Has anybody an example or a good pointer on how to do this?
Download the KitchenSink which is mentioned on the Getting Started page. It has several hundred examples on how to use the various Titanium based APIs - including MapViews.
Here's a simple example
var mapview = Titanium.Map.createView({
mapType: Titanium.Map.STANDARD_TYPE,
region:{latitude:33.74511, longitude:-84.38993, latitudeDelta:0.5, longitudeDelta:0.5},
animate:true,
regionFit:true,
userLocation:true
});
win.add(mapview);

Resources