Last active
November 30, 2022 03:17
-
-
Save ncerezo/b1991f8dfac01cb162c0 to your computer and use it in GitHub Desktop.
Alamofire multipart upload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FileUploader.swift | |
// | |
// Copyright (c) 2015 Narciso Cerezo Jiménez. All rights reserved. | |
// Largely based on this stackoverflow question: http://stackoverflow.com/questions/26121827/uploading-file-with-parameters-using-alamofire/28467829// | |
import Foundation | |
import Alamofire | |
private struct FileUploadInfo { | |
var name:String | |
var mimeType:String | |
var fileName:String | |
var url:NSURL? | |
var data:NSData? | |
init( name: String, withFileURL url: NSURL, withMimeType mimeType: String? = nil ) { | |
self.name = name | |
self.url = url | |
self.fileName = name | |
self.mimeType = "application/octet-stream" | |
if mimeType != nil { | |
self.mimeType = mimeType! | |
} | |
if let _name = url.lastPathComponent { | |
fileName = _name | |
} | |
if mimeType == nil, let _extension = url.pathExtension { | |
switch _extension.lowercaseString { | |
case "jpeg", "jpg": | |
self.mimeType = "image/jpeg" | |
case "png": | |
self.mimeType = "image/png" | |
default: | |
self.mimeType = "application/octet-stream" | |
} | |
} | |
} | |
init( name: String, withData data: NSData, withMimeType mimeType: String ) { | |
self.name = name | |
self.data = data | |
self.fileName = name | |
self.mimeType = mimeType | |
} | |
} | |
class FileUploader { | |
private var parameters = [String:String]() | |
private var files = [FileUploadInfo]() | |
private var headers = [String:String]() | |
func setValue( value: String, forParameter parameter: String ) { | |
parameters[parameter] = value | |
} | |
func setValue( value: String, forHeader header: String ) { | |
headers[header] = value | |
} | |
func addParametersFrom( #map: [String:String] ) { | |
for (key,value) in map { | |
parameters[key] = value | |
} | |
} | |
func addHeadersFrom( #map: [String:String] ) { | |
for (key,value) in map { | |
headers[key] = value | |
} | |
} | |
func addFileURL( url: NSURL, withName name: String, withMimeType mimeType:String? = nil ) { | |
files.append( FileUploadInfo( name: name, withFileURL: url, withMimeType: mimeType ) ) | |
} | |
func addFileData( data: NSData, withName name: String, withMimeType mimeType:String = "application/octet-stream" ) { | |
files.append( FileUploadInfo( name: name, withData: data, withMimeType: mimeType ) ) | |
} | |
func uploadFile( request sourceRequest: NSURLRequest ) -> Request? { | |
var request = sourceRequest.mutableCopy() as! NSMutableURLRequest | |
let boundary = "FileUploader-boundary-\(arc4random())-\(arc4random())" | |
request.setValue( "multipart/form-data;boundary=\(boundary)", forHTTPHeaderField: "Content-Type") | |
let data = NSMutableData() | |
for (name, value) in headers { | |
request.setValue(value, forHTTPHeaderField: name) | |
} | |
// Amazon S3 (probably others) wont take parameters after files, so we put them first | |
for (key, value) in parameters { | |
data.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) | |
data.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!) | |
} | |
for fileUploadInfo in files { | |
data.appendData( "\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)! ) | |
data.appendData( "Content-Disposition: form-data; name=\"\(fileUploadInfo.name)\"; filename=\"\(fileUploadInfo.fileName)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) | |
data.appendData( "Content-Type: \(fileUploadInfo.mimeType)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) | |
if fileUploadInfo.data != nil { | |
data.appendData( fileUploadInfo.data! ) | |
} | |
else if fileUploadInfo.url != nil, let fileData = NSData(contentsOfURL: fileUploadInfo.url!) { | |
data.appendData( fileData ) | |
} | |
else { // ToDo: report error | |
return nil | |
} | |
} | |
data.appendData("\r\n--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) | |
return Alamofire.upload( request, data ) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This example uploads a file called example.png found in the app resources | |
let fileURL = NSBundle.mainBundle().URLForResource("example", withExtension: "png") | |
let fileUploader = FileUploader() | |
// we can add multiple files | |
// this would be equivalent to: <input type="file" name="myFile"/> | |
fileUploader.addFileURL(fileURL!, withName: "myFile") | |
// we can add NSData objects directly | |
let data = UIImage(named: "sample") | |
fileUploader.addFileData( UIImageJPEGRepresentation(data,0.8), withName: "mySecondFile", withMimeType: "image/jpeg" ) | |
// we can also add multiple aditional parameters | |
// this would be equivalent to: <input type="hidden" name="folderName" value="sample"/> | |
fileUploader.setValue( "sample", forParameter: "folderName" ) | |
// put your server URL here | |
var request = NSMutableURLRequest( URL: NSURL(string: "http://myserver.com/uploadFile" )! ) | |
request.HTTPMethod = "POST" | |
fileUploader.uploadFile(request: request) |
Thanks for your job !
I can not upload files to 2 MB superiors when my server is parametrer to 6MB. Did you have a solution?
can you sent me php file web service ?
handle response by following code ->
req = fileUploader.uploadFile(request: request)
.progress { [weak self] bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
// To update your ui, dispatch to the main queue.
dispatch_async(dispatch_get_main_queue()) {
print("Total bytes written on main queue: \(totalBytesWritten)....\(totalBytesExpectedToWrite)")
}
}
.responseJSON { [weak self] response in
debugPrint(response)
if response.result.isSuccess {
self?.serverRequestResult(ServerResult.Success(response.data))
}
else{
self?.serverRequestResult(ServerResult.Failure(response.result.error))
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to get the response from server?