Xamarin Forms' WebView - local assets not found on Windows Phone - xamarin

I'm using WebView to display HTML from a string. This HTML references a stylesheet that I have locally on the device. I'm following the instructions from the official docs so the local CSS file can be accessed. It works fine on Android and iOS but I can't make it work on Windows Phone 8.1. I placed the CSS file in the root of the project and set the build action to Content, then set the BaseUrl to "" (I tried ms-appx-web:/// as well, with no success).
Does anyone know if the docs are missing some instructions? Or is it a bug in Forms? Any help would be appreciated.
Here's the code for populating the WebView with data (in a Forms PCL):
private async Task LoadData()
{
string html = await _dataProvider.GetHtmlAsync("index");
WebView.Source = new HtmlWebViewSource
{
Html = html,
BaseUrl = _baseUrlProvider.Get()
};
}
_baseUrlProvider is an instance of my WebViewBaseUrlProvider that is defined as follows:
internal class WebViewBaseUrlProvider : IWebViewBaseUrlProvider
{
public string Get() => "";
}
EDIT:
Seeing this question leads me to believe that there indeed is a bug in Xamarin Forms. When the link in the HTML contains the whole ms-appx-web:///style.css instead of just style.css, it suddenly starts to work. Obviously, this is not quite cross-platform...

I just found the answer - Xamarin simply ignores the BaseUrl property: https://github.com/xamarin/Xamarin.Forms/blob/2d9288eee6e6f197364a64308183725e7bd561f9/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs#L26

Related

Logging via TraceSource in Xamarin (UWP)

I just want to log to console and to a log file, using a standard TraceSource, in my Xamarin app that will run on UWP, Mac OS X, iOS and Android. I'm developing/debugging on UWP.
TraceSource, TraceListener, and TextWriterTraceListener are indeed all available in .Net Standard library, so perhaps I'm setting it up incorrectly? Most places on the Internet insist on setting up trace listeners in an app.config file, but this is not applicable nor possible for Xamarin apps. So here is my logging initialization code, mostly based on an example in Microsoft docs:
private void SetupLogging()
{
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out, "consoleTraceListener"));
string logFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Application.log");
if (!File.Exists(logFilePath)) File.Create(logFilePath);
var logFileTraceListener = new TextWriterTraceListener(logFilePath, "logFileTraceListener");
Trace.Listeners.Add(logFileTraceListener);
Trace.Write("Test");
Trace.TraceInformation("Logging Initialized. Log file location: " + logFilePath);
Trace.Flush();
}
When I run this in a Xamarin UWP app, a file is created but nothing is written to it, nor can I find anything in the Output of the program (there is no ConsoleTraceListener so I'm trying to write a TextWriterTraceListener to Console.Out). Can someone provide a working example for Xamarin? (I haven't tried the Android or iOS apps yet; want to get UWP on the local machine working first.)
The problem is that you passed wrong string parameter to TextWriterTraceListener method. Please try to pass Stream parameter. You could use following code directly. by the way, you'd better use LocalApplicationData SpecialFolder that could be accessed successfully within uwp.
private void SetupLogging()
{
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out, "consoleTraceListener"));
string logFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Application.log");
if (!File.Exists(logFilePath))
{
File.Create(logFilePath);
}
var logFileTraceListener = new TextWriterTraceListener(File.Open(logFilePath,FileMode.Open), "logFileTraceListener");
Trace.Listeners.Add(logFileTraceListener);
Trace.Write("Test");
Trace.TraceInformation("Logging Initialized. Log file location: " + logFilePath);
Trace.Flush();
}

Xamarin Forms - Image doesn't show up on Lumia

I implemented a Xamarin App with UWP Platform as target.
I added 4 images in the Assets of PCL and set Build Action = Embedded Resource on each. No image has been added on UWP project.
If I run the app on my laptop everything works great, instead when I run the same app on my Lumia no image shows up. I don't understand why, since the app is the same with the only difference of Target Platform, x64/x86 for my laptop and ARM for my Lumia.
I have also tried to set Copy to output Directory = Copy Always for each image, but without success.
Have you tried in another plaftorm (Droid, iOs?)
Like mentionned in the documentation: https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/, you need to:
1) Use a custom MarkupExtension to load image from EmbeddedResource:
[ContentProperty ("Source")]
public class ImageResourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue (IServiceProvider serviceProvider)
{
if (Source == null)
{
return null;
}
// Do your translation lookup here, using whatever method you require
var imageSource = ImageSource.FromResource(Source);
return imageSource;
}
}
2) Use this Custom Markup Extension and provide the fully qualified name of your image (namespace + name)
<Image Source="{local:ImageResource MyProject.Assets.Images.beach.jpg}" />
Just found the solution, disable "Compile with .NET Native tool chain".
https://stackoverflow.com/a/37352400/2297037
Do you know something about possible side effects?

Xamarin.forms OnAppLinkRequestReceived

I'm trying to use https://developer.xamarin.com/api/member/Xamarin.Forms.Application.OnAppLinkRequestReceived/p/System.Uri/ but can't seem to get it to be called in any way.
Did anyone ever tried to implement this new method?
I've tried several ways to implement different deeplinks, all of them open the app fine so they're correctly configured but that method never gets called.
Thanks.
This is how I set it up in Android.
Put this above your MainActivity.cs
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[]
{
Android.Content.Intent.CategoryDefault,
Android.Content.Intent.CategoryBrowsable
},
DataScheme = "http",
DataPathPrefix = "/tesla/",
DataHost = "exrin.net")]
This registers the activity when the app is installed. Change the URL to your desired URL.
For Android only (no need to do this with iOS) you need to also install the Nuget Xamarin Forms AppLinks
In your OnCreate make sure you do this after your Xamarin Forms Init
AndroidAppLinks.Init(this);
Then when you load the URL in a browser (in my example http://exrin.net/tesla) you will get this:
Then if you open the app it will enter here with the full URL as the URI parameter. This is in the App.cs (Xamarin.Forms.Application)
protected override void OnAppLinkRequestReceived(Uri uri)
{
base.OnAppLinkRequestReceived(uri);
}
You can then decode the URI as you see fit to move to the specific page in your app that the URL relates to/
More details at Xamarin Forms AppLinks
Also, your MainActivity must be derived from FormsAppCompatActivity for it to work. Once I changed it to that from FormsApplicationActivity, it started working.

How do I clear the cache of Cordova Web View on Windows Phone 8?

I'm developing a Cordova 2.9.0 app for Windows Phone 8. The app in question utilises external content heavily, using the JS and HTML content that's being served from another source. It all works fine, but the browser component caches heavily.
The only way I have discovered to clear caches is to uninstall-install the app again to take effect. The downside to this is that my localStorage also clears, slowing down my cycles.
I presume the cache can be cleared by writing extra C# into the Cordova template they serve, which I use by the way.
So while it was not that critical, I did stumble to a working answer. The WebBrowser class does have a suitable method to call: ClearInternetCacheAsync.
Since CordovaBrowser inherits from WebBrowser, it's just a matter of adding one line to MainPage.xaml.cs where the C# init of the start page happens:
namespace FooBarApp
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.CordovaView.Loaded += CordovaView_Loaded;
// blammo!
this.CordovaView.CordovaBrowser.ClearInternetCacheAsync();
}
Phonegap Cookies Plugin can be found HERE
A simple, lightweight jQuery plugin for reading, writing and deleting cookies can be found HERE
I hope it will resolve your problem. Thanks!!

Opening a PDF file in Windows Phone

I'm developing an app for Windows Phone 7 and I'm using a Phonegap template for it.
Everything looks perfect, but now I’m stuck trying to open a PDF file in the browser.
I tried the following but that doesn’t work because the url of the PDF exceeds the 2048 character limit (it’s a data url). This code runs after the deviceReady event was fired.
var ref = window.open('http://www.google.com', '_blank', 'location=no');
ref.addEventListener('loadstart', function () { alert(event.url); });
Now, I'm trying to save the PDF file to storage and then I'm trying to have it opened by the browser, but the browser doesn't show anything. I'm editing the InAppBrowser.cs code from cordovalib and I added the following lines before calling browser.Navigate(loc);
private void ShowInAppBrowser(string url)
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
FileStream stream = store.OpenFile("test.pdf", FileMode.Create);
BinaryWriter writer = new BinaryWriter(stream);
var myvar = Base64Decode("the big data url");
writer.Write(myvar);
writer.Close();
if (store.FileExists("test.pdf")) // Check if file exists
{
Uri loc = new Uri("test.pdf", UriKind.Relative);
...
}
}
This code is returning the following error:
Log:"Error in error callback: InAppBrowser1921408518 = TypeError: Unable to get value of the property 'url': object is null or undefined"
I don’t wanna use ComponentOne.
Any help would be greatly appreciated!
You cannot open pdf files from the isolated storage in the default reader for PDF files. If the file is online e.g. it has a URI for it, you can use WebBrowserTask to open it since that will download and open the file in Adobe Reader.
On Windows Phone 8 you actually can open your own file in default file reader for that extension, but I am not sure how that will help you since you target PhoneGap and Windows Phone 7.
Toni is correct. You could go and try to build your own viewer (which would be the same thing as using C1, but with more time involved). I worked on a port of iTextSharp and PDFSharp for WP7, but neither of which are PDF Viewers. They are good for creating PDFs and parsing them some (but to render them there is more work involved). This has been a personal quest of mine, but honestly the best I have gotten is to be able to extract some images from the PDF (and none of the text)
try this
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("metro.pdf");
Windows.System.Launcher.LaunchFileAsync(pdf);
This worked correctly on my Device.

Resources