1

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?

11
  • 1
    Why do you do .lineLength64Characters? I would simply remove that and you should be good to go. Commented Feb 26, 2018 at 11:59
  • @luk2302 's comment should be the answer. Commented Feb 26, 2018 at 12:02
  • @luk2302 I don't know anything about Base64, and that's what I got here the other day when I needed to encode image into Base64 for Firebase Database. How can I change the convertImageBase64 function? Thanks. Commented Feb 26, 2018 at 12:02
  • 1
    Why are you base64 encoding binary data and then storing in a BLOB column? Just store the raw binary. Commented Feb 26, 2018 at 12:05
  • 2
    @ElTomato: You might like to read this answer. Commented Feb 26, 2018 at 12:54

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I see. Not nil but []. I'll try it.
Thanks. I don't get my image back, though. Of course, that's not fault.
@ElTomato wait a second, I "changed" the wrong function, please check again, you should change the convertImageBase64 method, the other method should have been fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.