问题描述
我只是想将静态 PDF 存储在 S3 存储桶中,我可以使用 Apple 的内置 PDF 查看器抓取和呈现。我在以正确的形式在本地存储 PDF 的方法上遇到问题并且有点困惑。如果重复或太简单,我深表歉意,我已经搜索了几个小时以找到合适的解决方案,但没有找到任何有效的方法。谢谢你。我尝试直接使用 URL,但这也引发了错误。
import Amplify
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
containedView()
}
func grabPDF(){
Amplify.Storage.downloadData(
key: "TermsOfUse.pdf"
){ result in
switch result{
case .success(let key):
print("File with key: \(key)")
case .failure(let storageError):
print("Failed: ",storageError)
}
}
}
func containedView() -> WebView{
grabPDF()
return WebView(request: openPDF())
}
func openPDF() -> URLRequest{
let path = Bundle.main.path(forResource: "TermsOfUse",ofType: "pdf")
let url = URL(fileURLWithPath: path!)
print(url)
return URLRequest(url: url)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct WebView: UIViewRepresentable{
let request: URLRequest
func makeUIView(context: Context) -> WKWebView{
return WKWebView()
}
func updateUIView(_ uiView: WKWebView,context: Context){
uiView.load(request)
}
}
解决方法
-
Amplify.Storage.downloadData
返回一个Data
对象——它实际上并不下载文件。但是,还有另一种方法downloadFile
可以解决这个问题。 -
您的应用程序
Bundle
有一组静态文件。保存文件后,您将不会在 Bundle 中查看,而是在应用的文档或临时目录中查看。 -
与其在视图主体中进行 Amplify 调用,不如将其分配给一个单独的对象(这里我使用的是一个名为
ObservableObject
的DataLoader
)来完成工作然后在完成后设置一个标志 (downloaded
)。
class DataLoader : ObservableObject {
@Published var downloaded : Bool = false
func makeRequest() {
let downloadToFileName = getTermsOfUseURL()
Amplify.Storage.downloadFile(
key: "TermsOfUse.pdf",local: downloadToFileName,progressListener: { progress in
print("Progress: \(progress)")
},resultListener: { event in
switch event {
case .success:
print("Completed")
DispatchQueue.main.async { self.downloaded = true }
case .failure(let storageError):
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
})
}
func getTermsOfUseURL() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory,in: .userDomainMask)
return paths[0].appendingPathComponent("TermsOfUse.pdf")
}
}
struct ContentView: View {
@ObservedObject var loader = DataLoader()
var body: some View {
VStack {
if loader.downloaded {
WebView(request: URLRequest(url: loader.getTermsOfUseURL()))
}
}.onAppear {
loader.makeRequest()
}
}
}
注意:我没有测试过放大代码;假设它是从 https://docs.amplify.aws/lib/storage/download/q/platform/ios