Hi, So when the user fill all his data he must select a photo from carrier (photos)
@IBAction func selecFoto(_ sender: UIButton) { //select photo from carrier let imageController = UIImagePickerController() imageController.delegate = self imageController.sourceType = UIImagePickerController.SourceType.photoLibrary self.present(imageController, animated: true, completion: nil) } //display it on UIVIEW func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { image.image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage self.dismiss(animated: true, completion: nil) }
So the user's photo is named 'image'
image converts into base64
*note this code is before the UIbutton action *
class func convertImageToBase64(image: UIImage) -> String { let imageData = UIImagePNGRepresentation(image)! return imageData.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters) }
so and sends into my database
@IBAction func crearCuenta(_ sender: UIButton) { if nombreConductor.text == "" || email.text == "" || password.text == "" || confirmarpass.text == "" || telefono.text == "" || telefonoContacto.text == "" || emailContacto.text == "" || ciudad.text == "" || direccion.text == "" || matricula.text == "" || licencia.text == "" || numeroTaxi.text == "" || tipoVehiculo.text == "" || year.text == "" || marcaCarro.text == "" { displayAlert(title: "Información Faltante", message: "Debes porporcionar los datos solicitados") } if password.text != confirmarpass.text { displayAlert(title: "Usuario", message: "Las contraseñas no coinciden") } else{ let request = NSMutableURLRequest(url: NSURL(string: "hehe")! as URL) request.httpMethod = "POST" let postString = "Nombre_Completo=\(nombreConductor.text!)&Correo=\(email.text!)&Password=\(password.text!)&Telefono=\(telefono.text!)&Email_Contacto=\(emailContacto.text!)&Telefono_Contacto=\(telefonoContacto.text!)&Nivel=\(nivel)&Ciudad=\(ciudad.text!)&Direccion=\(direccion.text!)&Matricula=\(matricula.text!)&Licencia=\(licencia.text!)&N_Taxi=\(numeroTaxi.text!)&Tipo_Vehiculo=\(tipoVehiculo.text!)&Marca_Vehiculo=\(marcaCarro.text!)&Year=\(year.text!)&Foto=\(image!)" request.httpBody = postString.data(using: String.Encoding.utf8) let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in if error != nil { print("error=\(String(describing: error))") return } print("response = \(String(describing: response))") let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) print("responseString = \(String(describing: responseString))") } task.resume() } }
i get this response from the console
*which is true and sends sucessfully the data to the DB, but not the Image*
response = Optional( { URL: hehe } { Status Code: 200, Headers { "Content-Encoding" = ( gzip ); "Content-Type" = ( "text/html; charset=UTF-8" ); Date = ( "Fri, 26 Oct 2018 18:24:15 GMT" ); Server = ( Apache ); "x-powered-by" = ( "PHP/5.6.38" ); } }) responseString = Optional({"Response":"true"}) //true
and this is what my DB gets on the image Field
<UIImageView: 0x147d0d7d0; frame = (93 1502; 188 83); opaque = NO; autoresize = RM BM; userInteractionEnabled = NO; layer = <CALayer: 0x2816f2820>>
any ideas?
So the user's photo is named 'image'
It is not true. You are storing the user's photo into a UIImageView named `image`. And you are trying to send the UIImageView, not an image.
I strongly recommend you not to name a `UIImageView` as `image`, rename it to `imageView`:
@IBOutlet weak var imageView: UIImageView!
//display it on UIImageView func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { imageView.image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage self.dismiss(animated: true, completion: nil) }
*note this code is before the UIbutton action *
class func convertImageToBase64(image: UIImage) -> String { let imageData = image.pngData()! return imageData.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters) }
Seems this is the right version of your code, but it is not true that the func converts the image as string when the user press the submit button. It is just a class method and you need to call it explicitly. Though, the option `lineLength64Characters` may not be needed.
class func convertImageToBase64(image: UIImage) -> String { let imageData = image.pngData()! return imageData.base64EncodedString() }
And one more, when you post some special characters like `+` or `=` which may be included in a Base-64 string, you need to escape them.
You need something like this somewhere in your code (not inside a class):
extension String { var urlQueryValueEscaped: String { let urlQueryValueAllowed = CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "+&=")) return self.addingPercentEncoding(withAllowedCharacters: urlQueryValueAllowed)! .replacingOccurrences(of: " ", with: "+") } }
And then, your `crearCuenta(_:)` would be something like this:
@IBAction func crearCuenta(_ sender: UIButton) { //### You should better use guard guard let nombreConductorText = nombreConductor.text, !nombreConductorText.isEmpty, let emailText = email.text, !emailText.isEmpty, let passwordText = password.text, !passwordText.isEmpty, let confirmarpassText = confirmarpass.text, !confirmarpassText.isEmpty, let telefonoText = telefono.text, !telefonoText.isEmpty, let telefonoContactoText = telefonoContacto.text, !telefonoContactoText.isEmpty, let emailContactoText = emailContacto.text, !emailContactoText.isEmpty, let ciudadText = ciudad.text, !ciudadText.isEmpty, let direccionText = direccion.text, !direccionText.isEmpty, let matriculaText = matricula.text, !matriculaText.isEmpty, let licenciaText = licencia.text, !licenciaText.isEmpty, let numeroTaxiText = numeroTaxi.text, !numeroTaxiText.isEmpty, let tipoVehiculoText = tipoVehiculo.text, !tipoVehiculoText.isEmpty, let yearText = year.text, !yearText.isEmpty, let marcaCarroText = marcaCarro.text, !marcaCarroText.isEmpty else { displayAlert(title: "Información Faltante", message: "Debes porporcionar los datos solicitados") return } guard passwordText == confirmarpassText else { displayAlert(title: "Usuario", message: "Las contraseñas no coinciden") return } //### You need to convert the user's photo to Base-64 string explicitly guard let userImage = imageView.image else { displayAlert(title: "Usuario", message: "El foto no es selectado") return } //### `ViewController` should be renamed to the class name where you defined `convertImageToBase64(image:)` let imageBase64 = ViewController.convertImageToBase64(image: userImage) //### You should better use `URLRequest` with `var` instead of `NSMutableURLRequest` //### You should better use `URL` instead of `NSURL` var request = URLRequest(url: URL(string: "hehe")!) request.httpMethod = "POST" //### You need to escaape POST parames properly let postParams = [ "Nombre_Completo": nombreConductorText, "Correo": emailText, "Password": passwordText, "Telefono": telefonoText, "Email_Contacto": emailContactoText, "Telefono_Contacto": telefonoContactoText, "Nivel": nivel, "Ciudad": ciudadText, "Direccion": direccionText, "Matricula": matriculaText, "Licencia": licenciaText, "Tipo_Vehiculo": tipoVehiculoText, "Marca_Vehiculo": marcaCarroText, "Year": yearText, "Foto": imageBase64, ] let postString = postParams.map {"\($0.key.urlQueryValueEscaped)=\($0.value.urlQueryValueEscaped)"} .joined(separator: "&") request.httpBody = postString.data(using: .utf8) //### You have no need to use `as URLRequest` let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("error=\(error)") return } print("response = \(response?.description ?? "")") guard let data = data else { print("Something wrong: data = nil") return } //### You should better use `String` instead of `NSString` let responseString = String(data: data, encoding: .utf8)! print("responseString = \(responseString)") } task.resume() }