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/")!)
Related
I'm trying to upload an image with parameters in Swift. When I try this code, I can get the parameters but not the image
uploadFileToUrl(fotiño:UIImage){
var foto = UIImage(data: UIImageJPEGRepresentation(fotiño, 0.2))
var request = NSMutableURLRequest(URL:NSURL(string: "URL"))
request.HTTPMethod = "POST"
var bodyData = "id_user="PARAMETERS&ETC""
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(foto))
println("miraqui \(request.debugDescription)")
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var HTTPError: NSError? = nil
var JSONError: NSError? = nil
var dataVal: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: &HTTPError)
if ((dataVal != nil) && (HTTPError == nil)) {
var jsonResult = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: &JSONError)
if (JSONError != nil) {
println("Bad JSON")
} else {
println("Synchronous\(jsonResult)")
}
} else if (HTTPError != nil) {
println("Request failed")
} else {
println("No Data returned")
}
}
edit 2:
I think that I have some problems with the path of the saved UIImage, because php tells me that the file already exist, which I think is because I send it in blank
func createRequest (#userid: String, disco: String, id_disco: String, pub: String, foto: UIImage) -> NSURLRequest {
let param = [
"id_user" : userid,
"name_discoteca" : disco,
"id_discoteca" : id_disco,
"ispublic" : pub] // build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = NSURL(string: "http....")
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.timeoutInterval = 60
request.HTTPShouldHandleCookies = false
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var imagesaver = ImageSaver()
var image = foto // However you create/get a UIImage
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let destinationPath = documentsPath.stringByAppendingPathComponent("VipKing.jpg")
UIImageJPEGRepresentation(image,1.0).writeToFile(destinationPath, atomically: true)
self.saveImage(foto, withFileName: "asdasd22.jpg")
var path = self.documentsPathForFileName("asdasd22.jpg")
self.ViewImage.image = self.loadImageWithFileName("asdasd22.jpg")
// let path1 = NSBundle.mainBundle().pathForResource("asdasd22", ofType: "jpg", inDirectory: path) as String!
**//path1 always crash**
println(param.debugDescription)
println(path.debugDescription)
println(boundary.debugDescription)
request.HTTPBody = createBodyWithParameters(param, filePathKey: "asdasd22.jpg", paths: [path], boundary: boundary)
println(request.debugDescription)
return request
}
In your comment below, you inform us that you are using the $_FILES syntax to retrieve the files. That means that you want to create a multipart/form-data request. The process is basically:
Specify a boundary for your multipart/form-data request.
Specify a Content-Type of the request that specifies that it multipart/form-data and what the boundary is.
Create body of request, separating the individual components (each of the posted values as well as between each upload).
For more detail, see RFC 7578. Anyway, in Swift 3 and later, this might look like:
/// Create request
///
/// - parameter userid: The userid to be passed to web service
/// - parameter password: The password to be passed to web service
/// - parameter email: The email address to be passed to web service
///
/// - returns: The `URLRequest` that was created
func createRequest(userid: String, password: String, email: String) throws -> URLRequest {
let parameters = [
"user_id" : userid,
"email" : email,
"password" : password] // build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = URL(string: "https://example.com/imageupload.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let fileURL = Bundle.main.url(forResource: "image1", withExtension: "png")!
request.httpBody = try createBody(with: parameters, filePathKey: "file", urls: [fileURL], boundary: boundary)
return request
}
/// Create body of the `multipart/form-data` request
///
/// - parameter parameters: The optional dictionary containing keys and values to be passed to web service.
/// - parameter filePathKey: The optional field name to be used when uploading files. If you supply paths, you must supply filePathKey, too.
/// - parameter urls: The optional array of file URLs of the files to be uploaded.
/// - parameter boundary: The `multipart/form-data` boundary.
///
/// - returns: The `Data` of the body of the request.
private func createBody(with parameters: [String: String]? = nil, filePathKey: String, urls: [URL], boundary: String) throws -> Data {
var body = Data()
parameters?.forEach { (key, value) in
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
}
for url in urls {
let filename = url.lastPathComponent
let data = try Data(contentsOf: url)
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(filePathKey)\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(url.mimeType)\r\n\r\n")
body.append(data)
body.append("\r\n")
}
body.append("--\(boundary)--\r\n")
return body
}
/// Create boundary string for multipart/form-data request
///
/// - returns: The boundary string that consists of "Boundary-" followed by a UUID string.
private func generateBoundaryString() -> String {
return "Boundary-\(UUID().uuidString)"
}
With:
extension URL {
/// Mime type for the URL
///
/// Requires `import UniformTypeIdentifiers` for iOS 14 solution.
/// Requires `import MobileCoreServices` for pre-iOS 14 solution
var mimeType: String {
if #available(iOS 14.0, *) {
return UTType(filenameExtension: pathExtension)?.preferredMIMEType ?? "application/octet-stream"
} else {
guard
let identifier = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(),
let mimeType = UTTypeCopyPreferredTagWithClass(identifier, kUTTagClassMIMEType)?.takeRetainedValue() as String?
else {
return "application/octet-stream"
}
return mimeType
}
}
}
extension Data {
/// Append string to Data
///
/// Rather than littering my code with calls to `data(using: .utf8)` to convert `String` values to `Data`, this wraps it in a nice convenient little extension to Data. This defaults to converting using UTF-8.
///
/// - parameter string: The string to be added to the `Data`.
mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {
if let data = string.data(using: encoding) {
append(data)
}
}
}
Having all of this, you now need to submit this request. I would advise this is done asynchronously. For example, using URLSession, you would do something like:
let request: URLRequest
do {
request = try createRequest(userid: userid, password: password, email: email)
} catch {
print(error)
return
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
// handle error here
print(error ?? "Unknown error")
return
}
// parse `data` here, then parse it
// note, if you want to update the UI, make sure to dispatch that to the main queue, e.g.:
//
// DispatchQueue.main.async {
// // update your UI and model objects here
// }
}
task.resume()
If you are uploading large assets (e.g. videos or the like), you might want to use a file-based permutation of the above. See https://stackoverflow.com/a/70552269/1271826.
For Swift 2 renditions, see previous revision of this answer.
AlamoFire now supports Multipart:
https://github.com/Alamofire/Alamofire#uploading-multipartformdata
Here's a blog post with sample project that touches on using Multipart with AlamoFire.
http://www.thorntech.com/2015/07/4-essential-swift-networking-tools-for-working-with-rest-apis/
The relevant code might look something like this (assuming you're using AlamoFire and SwiftyJSON):
func createMultipart(image: UIImage, callback: Bool -> Void){
// use SwiftyJSON to convert a dictionary to JSON
var parameterJSON = JSON([
"id_user": "test"
])
// JSON stringify
let parameterString = parameterJSON.rawString(encoding: NSUTF8StringEncoding, options: nil)
let jsonParameterData = parameterString!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// convert image to binary
let imageData = UIImageJPEGRepresentation(image, 0.7)
// upload is part of AlamoFire
upload(
.POST,
URLString: "http://httpbin.org/post",
multipartFormData: { multipartFormData in
// fileData: puts it in "files"
multipartFormData.appendBodyPart(fileData: jsonParameterData!, name: "goesIntoFile", fileName: "json.txt", mimeType: "application/json")
multipartFormData.appendBodyPart(fileData: imageData, name: "file", fileName: "iosFile.jpg", mimeType: "image/jpg")
// data: puts it in "form"
multipartFormData.appendBodyPart(data: jsonParameterData!, name: "goesIntoForm")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, data, error in
let json = JSON(data!)
println("json:: \(json)")
callback(true)
}
case .Failure(let encodingError):
callback(false)
}
}
)
}
let fotoImage = UIImage(named: "foto")
createMultipart(fotoImage!, callback: { success in
if success { }
})
Thank you #Rob, your code is working fine, but in my case, I am retriving image from gallary and taking name of the image by using code:
let filename = url.lastPathComponent
But this code, displaying image extension as .JPG (in capital letter), but server not accepting extensions in captital letter, so i changed my code as:
let filename = (path.lastPathComponent as NSString).lowercaseString
and now my code is working fine.
Thank you :)
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
I'm trying to upload an image with parameters in Swift. When I try this code, I can get the parameters but not the image
uploadFileToUrl(fotiño:UIImage){
var foto = UIImage(data: UIImageJPEGRepresentation(fotiño, 0.2))
var request = NSMutableURLRequest(URL:NSURL(string: "URL"))
request.HTTPMethod = "POST"
var bodyData = "id_user="PARAMETERS&ETC""
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(foto))
println("miraqui \(request.debugDescription)")
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var HTTPError: NSError? = nil
var JSONError: NSError? = nil
var dataVal: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: &HTTPError)
if ((dataVal != nil) && (HTTPError == nil)) {
var jsonResult = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: &JSONError)
if (JSONError != nil) {
println("Bad JSON")
} else {
println("Synchronous\(jsonResult)")
}
} else if (HTTPError != nil) {
println("Request failed")
} else {
println("No Data returned")
}
}
edit 2:
I think that I have some problems with the path of the saved UIImage, because php tells me that the file already exist, which I think is because I send it in blank
func createRequest (#userid: String, disco: String, id_disco: String, pub: String, foto: UIImage) -> NSURLRequest {
let param = [
"id_user" : userid,
"name_discoteca" : disco,
"id_discoteca" : id_disco,
"ispublic" : pub] // build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = NSURL(string: "http....")
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.timeoutInterval = 60
request.HTTPShouldHandleCookies = false
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var imagesaver = ImageSaver()
var image = foto // However you create/get a UIImage
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let destinationPath = documentsPath.stringByAppendingPathComponent("VipKing.jpg")
UIImageJPEGRepresentation(image,1.0).writeToFile(destinationPath, atomically: true)
self.saveImage(foto, withFileName: "asdasd22.jpg")
var path = self.documentsPathForFileName("asdasd22.jpg")
self.ViewImage.image = self.loadImageWithFileName("asdasd22.jpg")
// let path1 = NSBundle.mainBundle().pathForResource("asdasd22", ofType: "jpg", inDirectory: path) as String!
**//path1 always crash**
println(param.debugDescription)
println(path.debugDescription)
println(boundary.debugDescription)
request.HTTPBody = createBodyWithParameters(param, filePathKey: "asdasd22.jpg", paths: [path], boundary: boundary)
println(request.debugDescription)
return request
}
In your comment below, you inform us that you are using the $_FILES syntax to retrieve the files. That means that you want to create a multipart/form-data request. The process is basically:
Specify a boundary for your multipart/form-data request.
Specify a Content-Type of the request that specifies that it multipart/form-data and what the boundary is.
Create body of request, separating the individual components (each of the posted values as well as between each upload).
For more detail, see RFC 7578. Anyway, in Swift 3 and later, this might look like:
/// Create request
///
/// - parameter userid: The userid to be passed to web service
/// - parameter password: The password to be passed to web service
/// - parameter email: The email address to be passed to web service
///
/// - returns: The `URLRequest` that was created
func createRequest(userid: String, password: String, email: String) throws -> URLRequest {
let parameters = [
"user_id" : userid,
"email" : email,
"password" : password] // build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = URL(string: "https://example.com/imageupload.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let fileURL = Bundle.main.url(forResource: "image1", withExtension: "png")!
request.httpBody = try createBody(with: parameters, filePathKey: "file", urls: [fileURL], boundary: boundary)
return request
}
/// Create body of the `multipart/form-data` request
///
/// - parameter parameters: The optional dictionary containing keys and values to be passed to web service.
/// - parameter filePathKey: The optional field name to be used when uploading files. If you supply paths, you must supply filePathKey, too.
/// - parameter urls: The optional array of file URLs of the files to be uploaded.
/// - parameter boundary: The `multipart/form-data` boundary.
///
/// - returns: The `Data` of the body of the request.
private func createBody(with parameters: [String: String]? = nil, filePathKey: String, urls: [URL], boundary: String) throws -> Data {
var body = Data()
parameters?.forEach { (key, value) in
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
}
for url in urls {
let filename = url.lastPathComponent
let data = try Data(contentsOf: url)
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(filePathKey)\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(url.mimeType)\r\n\r\n")
body.append(data)
body.append("\r\n")
}
body.append("--\(boundary)--\r\n")
return body
}
/// Create boundary string for multipart/form-data request
///
/// - returns: The boundary string that consists of "Boundary-" followed by a UUID string.
private func generateBoundaryString() -> String {
return "Boundary-\(UUID().uuidString)"
}
With:
extension URL {
/// Mime type for the URL
///
/// Requires `import UniformTypeIdentifiers` for iOS 14 solution.
/// Requires `import MobileCoreServices` for pre-iOS 14 solution
var mimeType: String {
if #available(iOS 14.0, *) {
return UTType(filenameExtension: pathExtension)?.preferredMIMEType ?? "application/octet-stream"
} else {
guard
let identifier = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(),
let mimeType = UTTypeCopyPreferredTagWithClass(identifier, kUTTagClassMIMEType)?.takeRetainedValue() as String?
else {
return "application/octet-stream"
}
return mimeType
}
}
}
extension Data {
/// Append string to Data
///
/// Rather than littering my code with calls to `data(using: .utf8)` to convert `String` values to `Data`, this wraps it in a nice convenient little extension to Data. This defaults to converting using UTF-8.
///
/// - parameter string: The string to be added to the `Data`.
mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {
if let data = string.data(using: encoding) {
append(data)
}
}
}
Having all of this, you now need to submit this request. I would advise this is done asynchronously. For example, using URLSession, you would do something like:
let request: URLRequest
do {
request = try createRequest(userid: userid, password: password, email: email)
} catch {
print(error)
return
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
// handle error here
print(error ?? "Unknown error")
return
}
// parse `data` here, then parse it
// note, if you want to update the UI, make sure to dispatch that to the main queue, e.g.:
//
// DispatchQueue.main.async {
// // update your UI and model objects here
// }
}
task.resume()
If you are uploading large assets (e.g. videos or the like), you might want to use a file-based permutation of the above. See https://stackoverflow.com/a/70552269/1271826.
For Swift 2 renditions, see previous revision of this answer.
AlamoFire now supports Multipart:
https://github.com/Alamofire/Alamofire#uploading-multipartformdata
Here's a blog post with sample project that touches on using Multipart with AlamoFire.
http://www.thorntech.com/2015/07/4-essential-swift-networking-tools-for-working-with-rest-apis/
The relevant code might look something like this (assuming you're using AlamoFire and SwiftyJSON):
func createMultipart(image: UIImage, callback: Bool -> Void){
// use SwiftyJSON to convert a dictionary to JSON
var parameterJSON = JSON([
"id_user": "test"
])
// JSON stringify
let parameterString = parameterJSON.rawString(encoding: NSUTF8StringEncoding, options: nil)
let jsonParameterData = parameterString!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// convert image to binary
let imageData = UIImageJPEGRepresentation(image, 0.7)
// upload is part of AlamoFire
upload(
.POST,
URLString: "http://httpbin.org/post",
multipartFormData: { multipartFormData in
// fileData: puts it in "files"
multipartFormData.appendBodyPart(fileData: jsonParameterData!, name: "goesIntoFile", fileName: "json.txt", mimeType: "application/json")
multipartFormData.appendBodyPart(fileData: imageData, name: "file", fileName: "iosFile.jpg", mimeType: "image/jpg")
// data: puts it in "form"
multipartFormData.appendBodyPart(data: jsonParameterData!, name: "goesIntoForm")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, data, error in
let json = JSON(data!)
println("json:: \(json)")
callback(true)
}
case .Failure(let encodingError):
callback(false)
}
}
)
}
let fotoImage = UIImage(named: "foto")
createMultipart(fotoImage!, callback: { success in
if success { }
})
Thank you #Rob, your code is working fine, but in my case, I am retriving image from gallary and taking name of the image by using code:
let filename = url.lastPathComponent
But this code, displaying image extension as .JPG (in capital letter), but server not accepting extensions in captital letter, so i changed my code as:
let filename = (path.lastPathComponent as NSString).lowercaseString
and now my code is working fine.
Thank you :)
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)
}
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.