I'm trying to send data (first name, last name, age, image) to a MySQL database. And I can. The following is what I have.
class PostViewController: UIViewController {
@IBAction func selectTapped(_ sender: UIButton) {
postData()
}
func postData() {
var request = URLRequest(url: URL(string: "http://www.mywebsite.tv/post.php")!)
request.httpMethod = "POST"
let fName = firstField.text!
let lName = lastField.text!
let ageStr = ageField.text!
let image = imageView.image!
guard let pictStr = convertImageBase64(image: image) else {
return
}
let postString = "a=\(fName)&b=\(lName)&c=\(ageStr)&d=\(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()
}
func convertImageBase64(image: UIImage) -> String? {
guard let pictData = UIImagePNGRepresentation(image) else {
return nil
}
let strBase64: String = pictData.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters)
return strBase64
}
}
And populating UITableView
with data from MySQL..
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, DataModelProtocol {
// MARK: - Variables
var myItems = NSArray()
// MARK: - IBOutlets
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// somehow loading data //
}
// MARK: - TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ProfileTableViewCell
let item: PictureModel = myItems[indexPath.row] as! PictureModel
cell.firstLabel.text = item.fName
cell.lastLabel.text = item.lName
cell.ageLabel.text = item.ageStr
print(item.pictStr!) // returning iVBORw0KGgoAAAANSUh...
if let img = convertBase64Image(base64String: item.pictStr!) {
cell.pictureImageView.image = img
}
return cell
}
func convertBase64Image(base64String: String) -> UIImage? {
if let pictData = Data(base64Encoded: base64String, options: Data.Base64DecodingOptions.ignoreUnknownCharacters) {
return UIImage(data: pictData)
} else {
return nil
}
}
}
The thing is cell.pictureImageView.image
is always nil. And I now know why. When I post a picture, a sample base64 string is
iVBORw0KGgoAAAANSUhEUgAAAFYAAACACAYAAACRMZ7FAAAAAXNSR0IArs4c6QAA\r\nABxp...
And the decoded string that I get is
iVBORw0KGgoAAAANSUhEUgAAAFYAAACACAYAAACRMZ7FAAAAAXNSR0IArs4c6QAA ABxp...
So the Data.Base64DecodingOptions.ignoreUnknownCharacters
option actually replaces \r\n with a white space. How can I encode an image and then decode it back the same?
Drop the .lineLength64Characters
options:
func convertImageBase64(image: UIImage) -> String? {
guard let pictData = UIImagePNGRepresentation(image) else {
return nil
}
let strBase64: String = pictData.base64EncodedString(options: [])
return strBase64
}
That way the string will not have a \r\n
in it in the first place.