Swift, Send File to Server

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



Leave a reply



Submit