Xamarin HybridWebView перейти на страницу в папке кэша - PullRequest
0 голосов
/ 04 ноября 2018

Я хочу создать приложение для веб-просмотра форм xamarin, которое загружает веб-страницу (само приложение), а затем отображает ее. Перед загрузкой я показываю локальную страницу входа, которая вызывает приложение, как только пользователь отправляет форму. Локальная страница будет находиться внутри пакета приложения, загруженная страница будет загружена в место, где приложение может хранить данные (CommenApplicationData в этом примере UWP, но я должен использовать папку документов на iOS).

Я уже создал библиотеку .NET Core, которая загружает, распаковывает и поддерживает команды сценариев, которые использует веб-страница внутри веб-просмотра. Основной входной класс этой библиотеки называется: BroadsheetInterface, и он принимает сообщения из веб-просмотра (BroadsheetInterface.RunCommand) и использует интерфейс для выполнения обратных вызовов к веб-представлению (RunJavascript).

Чтобы показать локальную «страницу входа» и загруженную «страницу приложения» или «страницу запуска», я использую пример HybridWebView из Xamarin. Затем я изменил гибридное веб-представление для конкретной платформы, чтобы сделать его собственную навигацию следующим образом:

// IWebView is a interface that is used for the BroadsheetInterface can do callbacks 
// to this control
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Windows.UI.Xaml.Controls.WebView>, IWebView 
{
    // The pointer to the current "BroadsheetInterface", a class that has all logic of 
    // the webpage inside the webview
    public BroadsheetInterface_Helper BroadsheetInterface { get; set; }

    // The standard call to setup the webview to a local page, I use this call to show 
    // the login page.
    protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            SetNativeControl(new Windows.UI.Xaml.Controls.WebView());
        }
        if (e.OldElement != null)
        {
            Control.NavigationCompleted -= OnWebViewNavigationCompleted;
            Control.ScriptNotify -= OnWebViewScriptNotify;
        }
        if (e.NewElement != null)
        {
            Control.NavigationCompleted += OnWebViewNavigationCompleted;
            Control.ScriptNotify += OnWebViewScriptNotify;

            LoadLoginPage();                
        }
    }

    // Once the local page has been loaded I setup the library (note the "this" 
    // parameter), then check if the user has checked the "remember login" checkbox 
    // last time he or she logged in.
    void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
    {
        if (args.IsSuccess)
        {
            BroadsheetInterface = new BroadsheetInterface_Helper(this);
            BroadsheetInterface.Browser_SetLogin();
        }
    }

    // If the Javascript inside the webview calls the app, the command will be passed 
    // into the BroadsheetInterface to be processed. 
    void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
    {
        BroadsheetInterface.RunCommand(e.Value);
    }

    // If the library want to call the webpage inside the webview, it will call 
    // this function
    public async void RunJavascript(string script)
    {
        await Control.InvokeScriptAsync("eval", new[] { script });
    }

    // Show the login page
    public void LoadLoginPage()
    {
        Control.Source = new Uri(string.Format("ms-appx-web:///Content//{0}", Element.Uri));
    }

    // Show the launcher page
    public void LoadLauncherPage()
    {
        // The location of the launcher page
        var fullname = BroadsheetInterface.AccountHelper.CurrentAccount.GetLauncherPage().FullName;
        // fullname = "C:\Users\wille\AppData\Local\Packages\a05728a3-841f-4ef2-8f13-f1dbf39590a0_tbz3402trp7yy\LocalState\ProgramData\Launcher\willem\index.html"

        // Convert the path to a url
        var url = "file:///" + fullname.Replace("\\", "/");
        // url = "file:///C:/Users/wille/AppData/Local/Packages/a05728a3-841f-4ef2-8f13-f1dbf39590a0_tbz3402trp7yy/LocalState/ProgramData/Launcher/willem/index.html"

        // Set it to the webview
        Control.Source = new Uri(url);
        // DOESN'T WORK :(
    }

    // This is called from the library to get the location where to store 
    // the launcher page
    public string GetCacheFolder()
    {
        return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
    }
}

Теперь приложение работает, я могу войти в систему, и когда я отправляю, оно начинает загружать файлы. После того, как файлы были загружены, я хочу настроить веб-просмотр, чтобы показать страницу запуска, которая была загружена. Поэтому я вызываю функцию «LoadLauncherPage ()», но она не меняется на загруженную страницу. Это как установка параметра «Источник», ничего не делает.

1 Ответ

0 голосов
/ 04 ноября 2018

Хорошо, узнал сам.

Я полагаю, что нельзя устанавливать для свойства Source для WebView значение "file: ///". Вот и я наткнулся на это решение:

// Show the launcher page
public void LoadLauncherPage()
{
    Uri uri = Control.BuildLocalStreamUri("Launcher", "/index.html");
    Control.NavigateToLocalStreamUri(uri, new StreamResolver(BroadsheetInterface));
}

// Resolver for mapping the files
public class StreamResolver : IUriToStreamResolver
{
    private BroadsheetInterface_Helper broadsheetInterface;

    public StreamResolver(BroadsheetInterface_Helper broadsheetInterface)
    {
        this.broadsheetInterface = broadsheetInterface;
    }

    public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
    {
        if (uri == null) throw new Exception();
        return GetContent(uri.AbsolutePath).AsAsyncOperation();
    }
    private async Task<IInputStream> GetContent(string path)
    {
        try
        {
            string fullname = broadsheetInterface.AccountHelper.CurrentAccount.RootFolder.FullName + path.Replace("/", "\\");
            StorageFile f = await StorageFile.GetFileFromPathAsync(fullname);
            IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
            return stream;
        }
        catch (Exception) { throw new Exception("Invalid path"); }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...