Search code examples
pathplatform

Xamarin Forms - How to deal against iOS includes of the PCL part


It's hard to find a title for my problem but it simple to understand !

I have this following code which is a control (gif)

public class Gif : WebView
{
    public string GifSource
    {
        set
        {
            var html = new HtmlWebViewSource();

            string GifAssetURL;
            switch (Device.OS)
            {
                case TargetPlatform.Android:
                    GifAssetURL = "file:///android_asset/";
                    break;
                case TargetPlatform.iOS:
                    //GifAssetURL = NSBundle.MainBundle.BundlePath;
                    GifAssetURL = "";
                    break;
                case TargetPlatform.Windows:
                    GifAssetURL = "ms-appx-web:///Assets/";
                    break;
                default:
                    GifAssetURL = "";
                    break;
            }

            html.Html = String.Format(@"<html><body style='background: #000000;'><img src='{0}' style='width:100%;height:100%;'/></body></html>", GifAssetURL + value);
            SetValue(SourceProperty, html);
            this.Margin = -10;
        }
    }
}

It works for every platform, however, when it's the time to generate a release, it throws an error about the include (Android & UWP):

using Foundation;

However, I need this include for the iOS part because my GIF Image is located in a folder of the Project.iOS part..

First, I use NSBundle.MainBundle.BundlePath but maybe, it could be a simple string?

Second, is it possible tooget a valid string path from a ImageSource.FromResources("");? In that case, I think it would solves the problem..

Thank for help !


Solution

  • I then, finaly, found a solution !

    So finaly, using the Fondation link is crashing my release compilation and the idea to get ride of it, is to have a BaseUrl interface, let me explain !

    First, take back my gif object:

    public class Gif : WebView
    {
        public string GifSource
        {
            set
            {
                var html = new HtmlWebViewSource();
    
                // Take a look on this line !
                string GifAssetURL = DependencyService.Get<IBaseUrl>().Get();
    
                html.Html = String.Format(@"<html><body style='background: #000000;'><img src='{0}' style='width:100%;height:100%;'/></body></html>", GifAssetURL + value);
                SetValue(SourceProperty, html);
                this.Margin = -10;
            }
        }
    }
    

    Depending on the OS currently used, the good path will then be given.

    So, to make it works, you have to create an Interface in the PCL Part like that:

    namespace Project
    {
        public interface IBaseUrl { string Get(); }
    }
    

    Then, for each platform you're focusing, create a class which inherit from IBaseUrl. Take a look below: Android, iOS & UWP

    Android

    using Project;
    using Project.Android.DependencyService;
    using Xamarin.Forms;
    
    [assembly: Dependency(typeof(BaseUrl_Android))]
    namespace Project.Android.DependencyService
    {
        public class BaseUrl_Android : IBaseUrl
        {
            public string Get()
            {
                return "file:///android_asset/";
            }
        }
    }
    

    iOS

    using Foundation;
    using MapPinsProject.Interface;
    using MapPinsProject.iOS.DependencyService;
    using Xamarin.Forms;
    
    [assembly: Dependency(typeof(BaseUrl_iOS))]
    namespace MapPinsProject.iOS.DependencyService
    {
        public class BaseUrl_iOS : IBaseUrl
        {
            public string Get()
            {
                return NSBundle.MainBundle.BundlePath;
            }
        }
    }
    

    UWP

    using Project;
    using Project.UWP.DependencyService;
    using Xamarin.Forms;
    
    [assembly: Dependency(typeof(BaseUrl_UWP))]
    namespace Project.UWP.DependencyService
    {
        public class BaseUrl_UWP : IBaseUrl
        {
            public string Get()
            {
                return "ms-appx-web:///";
            }
        }
    }
    

    Hope it helps ! Have fun !