Encoding base64 string to image in swift received from mysql


Encoding base64 string to image in swift received from mysql



I am receiving a base64 string from mysql (stored as blob) and try to encode it like this:


func loadImage() {
var request = URLRequest(url: URL(string: URL_IMAGES)!)
request.httpMethod = "POST"
let userid = self.defaultValues.integer(forKey: "userid")
let postString = "userid=(userid)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=(String(describing: error))")
return
}

if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is (httpStatus.statusCode)")
print("response = (String(describing: response))")
}

let responseString = String(data: data, encoding: .utf8)
if let encodedImage = responseString,
let imageData = NSData(base64Encoded: encodedImage, options: .ignoreUnknownCharacters),
let image = UIImage(data: imageData as Data) {
print(image.size)
}
}
task.resume()
}



And the php file looks like this:


<?php
$userid=$_POST["userid"];
$conn = mysqli_connect(connection);
if ($conn->connect_error) {
die("Connection failed: " . $conn>connect_error);
}
$sql = "SELECT profilepicture FROM users WHERE id = $userid";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$out=$row;
}
echo json_encode($out);
} else {
echo "0 results";
}
?>



EDIT 2* And this is how Im storing the image into the database:


@objc func updateUser(sender: UIButton!) {
let refreshAlert = UIAlertController(title: "Update profile?", message: "Do you want to update your profile? This will log you out to update the data!", preferredStyle: UIAlertControllerStyle.alert)
refreshAlert.view.tintColor = UIColor.red
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in

let URL_REQUEST = "request"

self.messageLbl.text = ""

var request = URLRequest(url: URL(string: URL_REQUEST)!)
request.httpMethod = "POST"
let userid = self.defaultValues.integer(forKey: "userid")
let password = self.passWordTf.text!
let email = self.eMailTf.text!
let image = self.imageView.image!
guard let pictStr = self.convertImageBase64(image: image) else {
return
}
let postString = "id=(userid)&password=(password)&email=(email)&profilepicture=(pictStr)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=(String(describing: error))")
return
}

if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is (httpStatus.statusCode)")
print("response = (String(describing: response))")
}

let responseString = String(data: data, encoding: .utf8)
print("responseString = (String(describing: responseString))")
}
task.resume()

if (self.eMailTf.text != self.defaultValues.string(forKey: "useremail")) {
self.defaultValues.set(self.eMailTf.text, forKey: "useremail")
}
self.navigationController?.popViewController(animated: true)
}))

refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action: UIAlertAction!) in
print("Handle Cancel Logic here")
}))

present(refreshAlert, animated: true, completion: nil)
}



EDIT 2* This is the encoding function:


func convertImageBase64(image: UIImage) -> String? {
guard let pictData = UIImagePNGRepresentation(image) else {
return nil
}
let strBase64: String = pictData.base64EncodedString(options: )
return strBase64
}



EDIT 2* And the php file for storing:


<?php
$userid=$_POST["userid"];
$password=$_POST["password"];
$pass = md5($password);
$email=$_POST["email"];
$profilepicture=$_POST["profilepicture"];


$conn = mysqli_connect(connection);

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

$sql =("UPDATE users SET password='".$pass."' , email='".$email."' , profilepicture='".$profilepicture."' WHERE id=".$userid."");

if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $conn->error;
}

$conn->close();
?>



this is a similar question to this, but even trying all the answers did not work for me. The response I'm getting is right but I can't encode it, since Im always getting nil trying to encode:



I have tried a lot of things like this too:



Decode base64_encode Image from JSON in Swift



EDIT 1



The string im receiving has the following prefix:
"[{"profilepicture":"iVBORw0KGgoAAAANSUhE...



Is it possible to convert the string without this prefix or is the prefix not even relevant to convert the string?



EDIT 2




1 Answer
1



Your server side code returns JSON data containing an array of assoc arrays retrieved with fetch_assoc().


fetch_assoc()



I recommend you to update the server side code, as it returns some other things than an image data, it should better send only the image data.



But if you want to use the server side code as is, you may need to write something like this in your loadImage:


loadImage


let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=(error?.localizedDescription ?? "nil")")
return
}

guard let httpResponse = response as? HTTPURLResponse else {
print("response is not an HTTPURLResponse")
return
}
guard httpResponse.statusCode == 200 else {
print("statusCode should be 200, but is (httpResponse.statusCode)")
print("response = (httpResponse)")
return
}

do {
//First decode the response body as JSON
let json = try JSONSerialization.jsonObject(with: data)
//The decoded object should be a JSON array containing one JSON object
guard let arr = json as? [[String: Any]], !arr.isEmpty else {
print("json is not an array, or is empty")
return
}
//Use only the first record
let person = arr[0]
//Retrieve the column value of "profilepicture" in the first record
guard let encodedImage = person["profilepicture"] as? String else {
print("NO profilepicture")
return
}
//Decode it into binary data as Base64
guard let imageData = Data(base64Encoded: encodedImage, options: .ignoreUnknownCharacters) else {
print("encodedImage is not a valid Base64")
return
}
//Convert the decoded binary data into an image
guard let image = UIImage(data: imageData) else {
print("imageData is in a unsupported format or is not an image")
return
}
print(image.size)
//Use `image` here...
} catch {
print(error)
}
}
task.resume()



You may need to modify some parts, but you can easily find where to fix as I embedded many print in bad cases.


print





Thank you really much! I can finally show the image stored in my database in my ImageView. Now I am facing the issue, that I can't store it in the database, since I changed some functions trying to make the download work :/ I would be really glad when you can help me with the edited (EDIT 2) question.
– xoxxi
Jun 30 at 21:32





Please describe I can't store it in the database. Any sort of errors? Some sort of unexpected results? I do not have enough time to analyze codes with no comments... Why don't you just revert to the original code in your original post?
– OOPer
Jul 1 at 0:59


I can't store it in the database






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API