Te damos la bienvenida a nuestro espacio, aquí encontrarás la resolución a lo que buscabas.
Solución:
En su comentario a continuación, nos informa que está utilizando el $_FILES
sintaxis para recuperar los archivos. Eso significa que desea crear un multipart/form-data
solicitud. El proceso es básicamente:
-
Especifique un límite para su
multipart/form-data
solicitud. -
Especifique un
Content-Type
de la solicitud que especifica quemultipart/form-data
y cuál es el límite. -
Cree el cuerpo de la solicitud, separando los componentes individuales (cada uno de los valores publicados, así como entre cada carga).
Para obtener más detalles, consulte RFC 7578. De todos modos, en Swift 3 y versiones posteriores, esto podría verse así:
/// 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]?, filePathKey: String, urls: [URL], boundary: String) throws -> Data
var body = Data()
parameters?.forEach (key, value) in
body.append("--(boundary)rn")
body.append("Content-Disposition: form-data; name="(key)"rnrn")
body.append("(value)rn")
for url in urls
let filename = url.lastPathComponent
let data = try Data(contentsOf: url)
let mimetype = mimeType(for: filename)
body.append("--(boundary)rn")
body.append("Content-Disposition: form-data; name="(filePathKey)"; filename="(filename)"rn")
body.append("Content-Type: (mimetype)rnrn")
body.append(data)
body.append("rn")
body.append("--(boundary)--rn")
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)"
/// Determine mime type on the basis of extension of a file.
///
/// This requires `import MobileCoreServices`.
///
/// - parameter path: The path of the file for which we are going to determine the mime type.
///
/// - returns: Returns the mime type if successful. Returns `application/octet-stream` if unable to determine mime type.
private func mimeType(for path: String) -> String
let pathExtension = URL(fileURLWithPath: path).pathExtension as NSString
guard
let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil)?.takeRetainedValue(),
let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue()
else
return "application/octet-stream"
return mimetype as String
Con:
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)
Teniendo todo esto, ahora debe enviar esta solicitud. Aconsejaría que esto se haga de forma asincrónica. Por ejemplo, usando URLSession
, harías algo como:
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()
Para las representaciones de Swift 2, consulte la revisión anterior de esta respuesta.
AlamoFire ahora es compatible con Multipart:
https://github.com/Alamofire/Alamofire#uploading-multipartformdata
Aquí hay una publicación de blog con un proyecto de muestra que trata sobre el uso de Multipart con AlamoFire.
http://www.thorntech.com/2015/07/4-essential-swift-networking-tools-for-working-with-rest-apis/
El código relevante podría verse así (asumiendo que está usando AlamoFire y 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
)
Reseñas y valoraciones del artículo
Más adelante puedes encontrar las explicaciones de otros programadores, tú además eres capaz mostrar el tuyo si lo crees conveniente.