我目前在将本地pdf加载到网络视图时遇到问题。我拥有可以正常工作的代码,当我在iPad模拟器上运行它时,它的工作原理绝对完美。但是,当我尝试在物理iPad设备上运行它时,就会出现问题。当我运行它时,它到达需要显示PDF的地步,将加载Web视图,但是在Web视图中没有显示PDF。
PDF实际上是由应用程序生成的,我将其存储在库文件夹内的目录中。
在WebView中显示PDF的代码:
public void LoadPdfToWebView(string pdfPath)
{
//Console.WriteLine("Load request started");
WebView.LoadRequest(new NSUrlRequest(new NSUrl(pdfPath, false)));
View.AddSubview(WebView);
//Console.WriteLine("Load request Finished");
}
不太确定为什么会这样,希望有人能提供帮助。
答案 0 :(得分:1)
在Xamarin.IOS中在UIWebView中显示HTML以外的文档类型:
将文档(例如PDF)添加到Xamarin.iOS项目。将“生成操作”设置为BundleResource。您可以通过右键单击该文件并在打开的菜单中选择“构建动作”来设置文件的构建动作。
创建一个UIWebView并将其添加到视图中:
webView = new UIWebView (View.Bounds);
View.AddSubview(webView);
使用NSUrl和NSUrlRequest类加载文件:
string fileName = "Loading a Web Page.pdf"; // remember case-sensitive
string localDocUrl = Path.Combine (NSBundle.MainBundle.BundlePath, fileName);
webView.LoadRequest(new NSUrlRequest(new NSUrl(localDocUrl, false)));
webView.ScalesPageToFit = true;
您可以参考此官方步骤。如果有问题或其他需求,可以参考this link
如果您无法读取捆绑中的资源,则可以将资源缓存放入沙箱的temp目录中,并尝试使用LoadRequest
进行读取。
答案 1 :(得分:0)
可能是通过更改info.plist文件解决的 像这样 NSAppTransportSecurity NSAllowsArbitraryLoads
我建议您使用此项目
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>mysupersexywebsite.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>subdomain.mysupersexywebsite.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
答案 2 :(得分:0)
我刚刚为一个应用修复了这个问题,并想我会发布解决方案
这是针对 WKWebView 的,这是 Apple 自 2020 年 12 月起的一项要求,但截止日期已暂时延长
Xaml PdfWebView 内容页
<controls:PdfWebView
Source="{Binding PDFSource}"
HeightRequest="1000"
WidthRequest="1000"/>
控制
namespace XForms.Controls
{
public class PdfWebView : WebView { }
}
VM,只有相关部分
private string _pdfSource;
public string PDFSource
{
get => _pdfSource;
set
{
if (Device.RuntimePlatform == Device.Android && value.StartsWith("file:") == false)
{
value = $"file:///android_asset/pdfjs/web/viewer.html?file=file:///{WebUtility.UrlEncode(value)}";
}
SetProperty(ref _pdfSource, value);
}
}
用于 PdfWebView 的 iOS 渲染器
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using XForms.Controls;
using WebKit;
using Foundation;
[assembly: ExportRenderer(typeof(PdfWebView), typeof(iOSUI.Renderers.PdfWebViewRenderer))]
namespace iOSUI.Renderers
{
public class PdfWebViewRenderer : ViewRenderer<WebView, WKWebView>
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var wkWebViewConfiguration = new WKWebViewConfiguration();
var wkWebView = new WKWebView(Frame, wkWebViewConfiguration)
{
AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
};
SetNativeControl(wkWebView);
}
if (e.NewElement != null)
{
if (string.IsNullOrEmpty(((UrlWebViewSource)e.NewElement.Source)?.Url) == false)
{
var url = ((UrlWebViewSource)e.NewElement.Source).Url;
if(url.StartsWith("http"))
{
Control.LoadRequest(new NSUrlRequest(new NSUrl(url)));
}
else
{
Control.LoadFileUrl(new NSUrl($"file://{url}"), new NSUrl($"file://{url}"));
}
}
}
}
}
}
安卓渲染器
using System.Net;
using Android.Content;
using Android.Views;
using Android.Webkit;
using XForms.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(PdfWebView), typeof(AndroidUI.Renderers.PDFViewRenderer))]
namespace AndroidUI.Renderers
{
public class PDFViewRenderer : WebViewRenderer
{
public PDFViewRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.Settings.JavaScriptEnabled = true;
Control.Settings.DomStorageEnabled = true;
Control.Settings.AllowFileAccess = true;
Control.Settings.AllowFileAccessFromFileURLs = true;
Control.Settings.AllowUniversalAccessFromFileURLs = true;
Control.SetWebChromeClient(new WebChromeClient());
}
}
// If you want to enable scrolling in WebView uncomment the following lines.
public override bool DispatchTouchEvent(MotionEvent e)
{
Parent.RequestDisallowInterceptTouchEvent(true);
return base.DispatchTouchEvent(e);
}
}
}
此解决方案使用 Android 中的 pdfjs 和 iOS 中的 WKWebview 来呈现 PDF
PDFSource 是文件的完整路径,我使用 System.IO .net 标准调用以跨平台方式处理此问题
所有文件都存放在(我有个方法叫GetFullPath,返回跨平台通用路径)
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
结合文件名和 Path.Combine
Path.Combine(GetFullPath(), fileName);
这是在 VM 中设置的 PDFSource
Pdfjs 库文件只是复制到 Assets/pdfjs for Android 中
iOS 的神奇之处在于调用 LoadFileUrl 而不是 LoadRequest 并在前面加上“file://”
我稍微清理了我们的命名空间,因此其中一些不会像 XForms.Controls 等那样解析我们的内部代码