iOS Swift 5 - Upload a file with a server by calling a PHP function
I've found a solution, here's my edited Swift 5 function, which now can also accept mp4
video files, not just jpg
or png
images:
func uploadFile(fileData:Data, fileName:String , completion: @escaping (_ fileURL:String?, _ error:String?) -> Void) {
print("FILENAME: \(fileName)")
let boundary: String = "------VohpleBoundary4QuqLuM1cE5lMwCy"
let contentType: String = "multipart/form-data; boundary=\(boundary)"
let request = NSMutableURLRequest()
request.url = URL(string: DATABASE_PATH + "upload-file.php")
request.httpShouldHandleCookies = false
request.timeoutInterval = 60
request.httpMethod = "POST"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"fileName\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(fileName)\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"file\"\r\n".data(using: String.Encoding.utf8)!)
// File is an image
if fileName.hasSuffix(".jpg") {
body.append("Content-Type:image/png\r\n\r\n".data(using: String.Encoding.utf8)!)
// File is a video
} else if fileName.hasSuffix(".mp4") {
body.append("Content-Type:video/mp4\r\n\r\n".data(using: String.Encoding.utf8)!)
}
body.append(fileData)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _:Data = data as Data?, let _:URLResponse = response, error == nil else {
DispatchQueue.main.async { completion(nil, error!.localizedDescription) }
return
}
if let response = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) {
print("XSUploadFile -> RESPONSE: " + DATABASE_PATH + response)
DispatchQueue.main.async { completion(DATABASE_PATH + response, nil) }
// NO response
} else { DispatchQueue.main.async { completion(nil, E_401) } }// ./ If response
}; task.resume()
}
Here's how I use that function:
let imageData = UIImage(named: "my_img")!.jpegData(compressionQuality: 1)
uploadFile(fileData: imageData!, fileName: "image.jpg") { (fileURL, e) in
if e == nil {
print("FILE URL: " + fileURL!)
}}
This works 100%.
Upload Pdf, Docx and image file to server using Swift 4
One fundamental mistake is that you are using dataTask
instead of an uploadTask on your URLSession
instance, e.g. uploadTask(with:from:completionHandler:)
Construction of Body Data
Here's a generic example from my own code (as requested in the comments below) of how body data might be constructed:
// imagesURLS is an optional array of URLs, i.e. imageURLS:[URL]?
if let imgURLs = imagesURLS {
for f in imgURLs {
let filename = f.lastPathComponent
let splitName = filename.split(separator: ".")
let name = String(describing: splitName.first)
let filetype = String(describing: splitName.last)
let imgBoundary = "\r\n--\(boundary)\r\nContent-Type: image/\(filetype)\r\nContent-Disposition: form-data; filename=\(filename); name=\(name)\r\n\r\n"
if let d = imgBoundary.data(using: .utf8) {
bodyData.append(d)
}
do {
let imgData = try Data(contentsOf:f, options:[])
bodyData.append(imgData)
}
catch {
// can't load image data
}
}
}
let closingBoundary = "\r\n--\(boundary)--"
if let d = closingBoundary.data(using: .utf8) {
bodyData.append(d)
}
The loop means that every item of data (in this case an image) is preceded by a boundary string and after the very last item of data the closing boundary string is added (i.e. the one ending in a double hyphen).
Upload files using multipart request - Swift 4
Try with:
multipartFormData.append(fileData, withName: "file", fileName: "file", mimeType: "image/png")
How to upload files on FTP in ios?
You can use
https://github.com/amosavian/FileProvider
let returnCredential = URLCredential(user:<username>, password:<password>, persistence: .none)
let ftpFileProvider = FTPFileProvider(baseURL: URL(string:<host eg ftp:>, mode: .default, credential: returnCredential, cache: .none)!
ftpFileProvider.copyItem(localFile: <local_file_path>, to:<where on ftp>, completionHandler: { error in
if error != nil {
print(error)
return
}
})
Upload an .XML file with a name via POST method in SWIFT
Here's a generic example to upload a file.
let headers = [
"content-type": "multipart/form-data;",
"authorization": "authToken",
]
let parameters = [
[
"name": "xmlfile",
"fileName": "search_xml.xml"
]
]
var body = ""
var error: NSError? = nil
for param in parameters {
let paramName = param["name"]!
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(paramName)\""
if let filename = param["fileName"] {
let contentType = param["content-type"]!
let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
if (error != nil) {
print(error)
}
body += "; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(contentType)\r\n\r\n"
body += fileContent
} else if let paramValue = param["value"] {
body += "\r\n\r\n\(paramValue)"
}
}
let request = NSMutableURLRequest(url: NSURL(string: "https://example.com/fileupload")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
iOS Error on uploading pdf file to server - Swift Xcode 13
Try below way to fix issue:
startAccessingSecurityScopedResource
will help to fix issue
if var firstDoc = urls.first, firstDoc.startAccessingSecurityScopedResource() {
defer {
DispatchQueue.main.async {
firstDoc.stopAccessingSecurityScopedResource()
}
}
do {
let data = try Data.init(contentsOf: firstDoc)
let dest = URL(type: .doc, fileName: firstDoc.lastPathComponent)
try data.write(to: dest)
firstDoc = dest
} catch {
debugPrint("Error : ", error)
}
self.openDocumentController()
}
Sending .MOV video file as part of POST request to own server as part of a multipart/form-data request in Swift not working
Intro:
I wouldn't transform it into String...
Thinking that every data can be a valid UTF8 string, that's a big mistake... But a valid UTF8 string into Data
, that works every time.
let stringImage = String(data: anyUIImage.pngData()!, encoding: .utf8)
Should give normally nil
value...
In use:
Instead, make body
a Data
, not a String
, since in the end, httpBody
is a Data
.
var body = Data()
When you want to append a String
:
body += "--\(boundary)\r\n"
=>
body += Data("--\(boundary)\r\n".utf8)
If you have a Data
parameter, append it directly.
Then, for your video content;
let paramSrc = param["src"] as! String
let fileData = try NSData(contentsOfFile:paramSrc, options:[]) as Data
let fileContent = String(data: fileData, encoding: .utf8)!
body += "; filename=\"\(paramSrc)\"\r\n"
+ "Content-Type: \"content-type header\"\r\n\r\n\(fileContent)\r\n"
Should be:
if let source = param["src"] as? String, let fileContent = try? Data(contentsOf: source) {
body += Data("; filename=\"\(paramSrc)\"\r\n".utf8)
body += Data("Content-Type: \"content-type header\"\r\n".utf8)
//Now, appending the data
body += Data("\r\n".utf8)
body += fileContent
body += Data("\r\n".utf8)
}
And in the end:
request.httpBody = body
Related Topics
Function Taking a Variable Number of Arguments
Nested Types Inside a Protocol
Codable and Xmlparser in Swift
Using Foreach with a an Array of Bindings (Swiftui)
Avoid Consecutive "If Let" Declarations in Swift
Swift Calling Static Methods: Type(Of: Self) VS Explicit Class Name
Swift Struct Doesn't Conform to Protocol Equatable
Why Is There a Memory Leak at String Creation in Swift
Uialertcontroller Change Font Color
What's the Swift Equivalent of Objective-C's "#Ifdef _Iphone_11_0"
How to Zip More Than 4 Publishers
Uisearchcontroller in Navigationitem iOS 11 Apple Way
Swiftui: Detect Finger Position on MAC Trackpad
Forcing Nspersistentcontainer Change Core Data
Realitykit - Set Text Programmatically of an Entity of Reality Composer
One-Way Platform Collisions in Sprite Kit
Swift: Uicollectionview Selecting Cell Indexpath Issues
Swift - Initialize View Controller from Storyboard by Overriding Init