How to load a PDF from a Base64 string in a UIWebView - ios

I'm using an API that is returning a Base64 string, something like this:
data:application/pdf;base64,**BASE64STRING**
Where BASE64STRING is what I need to display the PDF.
So far I only created a Data object that gets the Base64 string:
let data = Data(base64Encoded: BASE64STRING)
And I tried to load it in the webview:
webView.load(data!, mimeType: "application/pdf", textEncodingName: "", baseURL: URL(string: "")!)
The problem is that I don't have a local PDF file, so I don't know what I should put in baseURL. Currently it's giving me a fatal error: unexpectedly found nil while unwrapping an Optional value
How can I load the PDF in the webView? Is there any better way to do that?

I solved the problem, despite that I'm not sure if it's a good approach, the solution is to put any valid URL in baseUrl:
webView.load(data!, mimeType: "application/pdf", textEncodingName: "", baseURL: URL(string: "https://www.google.com")!)

Try this
webView.load(data, mimeType: "application/pdf", textEncodingName: "utf-8", baseURL: URL(fileURLWithPath: ""))

First convert the base64String to NSData and then convert to Data and use it.
PDF files are binary files so they can't be represented as UITF8 encoded string directly.
if let data = NSData(base64Encoded: base64String, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) as Data? {
self.webView.load(data, mimeType: "application/pdf", characterEncodingName: "", baseURL: URL(fileURLWithPath: ""))
}

For Swift 5, here a complete example with no force unwrapped and temporary file:
guard let data = Data(base64Encoded: base64), let fileUrl = try? saveTemporaryFile(from: data, filename: fileName) else {
// error handling
return
}
webView.load(data, mimeType: "application/pdf", textEncodingName: "", baseURL: fileUrl)
And the utility function to save the data in local temp file:
func saveTemporaryFile(from data: Data, filename: String? = nil) throws -> URL {
let filename = filename ?? UUID().uuidString
let fileURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(filename)
try? FileManager.default.removeItem(at: fileURL)
try data.write(to: fileURL)
return fileURL
}

Swift 5+
Very Easy and Smooth Solution
let base64PDF = "m5hbWVfaWQiOiJ1aWQiLCJRSUQiOiIyNzg1ODYwNDM3NSIsIlVVSUQiOiIwMDE2M0U2Ri1EREMyLTFFRTktQUE5MS0wOEYxMDFEODU4NTYiLCJFbWFpbCI6IlNBSUYuUkVITUFOQEFBQlFBVEFSLkNPTSIs"
if let data = Data(base64Encoded: base64PDF, options: Data.Base64DecodingOptions.ignoreUnknownCharacters) as Data? {
self.webKitView.load(data, mimeType: "application/pdf", characterEncodingName: "", baseURL: nil)
}

Related

How to save a file in a variable in SwiftUI 2

I have got the URL of a file using file importer. Now I want to store the file in a variable so that I can send it to the server.
.fileImporter(isPresented: $openfile, allowedContentTypes: [.audio,.pdf,.png, .text, .jpeg], allowsMultipleSelection: false) { (res) in
do{
let fileURL = try res.get()
//getting file name
self.fileName = fileURL.last?.lastPathComponent ?? "File Uplaoded"
print(fileURL)
}catch{
print("Error reading docs")
print(error.localizedDescription)
}
}
How can I save the file in a variable from the fileURL?
The stackoverflow answer shows you how to go about getting the file content.
You have to adapt the answer to your code, something like:
var fileData: Data?
.fileImporter(isPresented: $openfile, allowedContentTypes: [.audio,.pdf,.png, .text, .jpeg], allowsMultipleSelection: false) { (res) in
do{
let fileURL = try res.get()
if let url = fileURL.first {
fileName = url.lastPathComponent
fileData = try Data(contentsOf: url)
print("\n fileName: \(fileName) \n url: \(url) \n fileData: \(fileData)")
}
}catch{
print("Error reading docs")
print(error.localizedDescription)
}
}
Then you can use fileData to send to the server.

How to download a PDF document when comes in Data type from WS, i dont have any URL the pdf comes from web service swift

i got show the pdf with next lines
webView.load(decodeData, mimeType: "application/pdf", characterEncodingName: "utf-8", baseURL: URL(fileURLWithPath: ""))
however i cant find the way to download it, how can i download it using a button the next lines are a little part
if let form = eDocument{
self.title = "Follow"
if let decodeData = Data(base64Encoded: form.content, options: .ignoreUnknownCharacters) {
let str = String(decoding: decodeData, as: UTF8.self)
webView.load(decodeData, mimeType: "application/pdf", characterEncodingName: "utf-8", baseURL: URL(fileURLWithPath: ""))
}
}
thanks

Load iframe tag (video) from html string into web view using Swift 3

enter image description here
It shows GRAY frame, but it has only black borders...no video shown!
Hint: load function only accepts Data type, not String...but after converting, nothing happands!
#IBOutlet weak var webView: UIWebView!
func callWS(){
let url = URL(string: "endpoint url")
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: url!, completionHandler: {
(data, response, error) in
if error != nil
{
print("Error")
}
else
{
if let content = data
{
do {
let myJSON = try JSONSerialization.jsonObject(with: content) as? [String:Any]
let text:String = myJSON?["text"] as! String
let textData:Data = text.data(using: .utf8)!
//self.webView.loadHTMLString(text, baseURL: nil) no frame
self.webView.load(textData, mimeType: "text/html", textEncodingName: "utf8", baseURL: NSURL() as URL)
}
catch {}
}
}
})
task.resume()
}
You should be able to use .loadHTMLString(). Change your code to:
let myJSON = try JSONSerialization.jsonObject(with: content) as? [String:Any]
let text:String = myJSON?["text"] as! String
self.webView.loadHTMLString(text, baseURL: URL(string: "https://"))
You may also have to first replace the extra escape chars. Without your actual call to get the JSON data, I can't replicate it exactly for testing - but I had to remove them to get the HTML format to be correct.
So, if you end up with tags being shown instead of being parsed as tags:
adassa dasdas dsadas .<\/p>
that means the JSON string actually has invalid characters, so you probably want to do it like this:
let myJSON = try JSONSerialization.jsonObject(with: content) as? [String:Any]
let text:String = myJSON?["text"] as! String
// remove the extra "\" escape chars
let cleanedText = text.replacingOccurrences(of: "\\/", with: "/")
self.webView.loadHTMLString(cleanedText, baseURL: URL(string: "https://"))

Swift 3: Load GIF in UIWebView

I want to load GIF in my swift 3 application. I used this code to do that but the gif is not showed.
let filePath = Bundle.main.path(forResource: “myGif”, ofType: "gif")
let gif = NSData(contentsOfFile: filePath!)
self.webView.load(gif! as Data, mimeType: "image/gif", textEncodingName: String(), baseURL: NSURL() as URL)
self.webView.isUserInteractionEnabled = false
I don't know what is wrong with my code (I'm really new to swift and iOS development).
Any help please?
I found SwiftGif Lbrary from github, it doesn't use webview (if you want to use webview write me to comments to update the answer)
EDIT:
Webview:
let url = Bundle.main.url(forResource: "source", withExtension: "gif")!
let data = try! Data(contentsOf: url)
webview.load(data, mimeType: "image/gif", textEncodingName: "UTF-8", baseURL: NSURL() as URL)
webview.scalesPageToFit = true
webview.contentMode = UIViewContentMode.scaleAspectFit
Hope it helps.
Here is working example. I downloaded the gif image from web and added it to sample project.
let url = Bundle.main.url(forResource: "hsk", withExtension: "gif")!
let data = try! Data(contentsOf: url)
webView.load(data, mimeType: "image/gif", textEncodingName: "UTF-8", baseURL: NSURL() as URL)
With the code above, I could see the animated gif as below.

UIWebView for GIF Background loadData method error

I keep receiving the same error of: Cannot invoke loadData with an argument of list type '(NSData, MIMEType: String, textEncodingName: nil, baseURL: nil)'
for the loadData method.
var filePath = NSBundle.mainBundle().pathForResource("fractal", ofType: "gif")
var gif = NSData(contentsOfFile: filePath!)
var webViewBG = UIWebView(frame: self.view.frame)
webViewBG.loadData(gif!,MIMEType: "image/gif",textEncodingName: nil,baseURL: nil) // this line of code causes the build error
You should check loadData function signature, which is:
func loadData(_ data: NSData, MIMEType MIMEType: String,
textEncodingName textEncodingName: String, baseURL baseURL: NSURL)
textEncodingName is String, not String?, thus you can't pass nil. Same applies to baseURL where the type is NSURL, not NSURL?.
In this case, you can pass whatever values like utf-8 and http://localhost/ to meet non-nil criteria.
Check this thread for other ways how to do it.
Try to minimize usage of ! to avoid runtime failures. Something like this is much more robust:
guard let filePath = NSBundle.mainBundle().pathForResource("fractal", ofType: "gif"),
let gifData = NSData(contentsOfFile: filePath) else {
return
}
var webViewBG = UIWebView(frame: self.view.frame)
webViewBG.loadData(gifData, MIMEType: "image/gif", textEncodingName: "utf-8",
baseURL: NSURL(string: "http://localhost/")!)

Resources