I have an iOS app which allows uploading an image to an Ubuntu server (with Apache webserver) using the Swift function below:
private func uploadPhoto(image:UIImage) {
let imageData = image.jpegData(compressionQuality: 0.6)
if imageData == nil {
NSLog("Image Data is nil")
} else {
let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
let url = URL(string: "https://example.com/myapi.php")!
var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
let boundary = NSUUID().uuidString
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
// Text Parameter: Action
body.append(NSString(format: "--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Disposition: form-data; name=\"action\"\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "some_text_data\r\n").data(using: String.Encoding.utf8.rawValue)!)
// Text Parameter: Build Number
body.append(NSString(format: "--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Disposition: form-data; name=\"build\"\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: ("\(buildNumber ?? "99999")\r\n" as NSString)).data(using: String.Encoding.utf8.rawValue)!)
// File Parameter
body.append(NSString(format: "--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data; name=\"the_img\"; filename=\"image.jpg\"\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(imageData!)
body.append(NSString(format: "\r\n--%@--\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
request.httpBody = body as Data
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
}
}
The upload function works fine, and the images are uploaded to the server without errors. However, some images uploaded (around 1 in 100 images) will have green lines on the thumbnail (shown in macOS 10.15.6 Finder's quick preview) of the uploaded images; seems like the JPEG is corrupted. Please see an example screen shot below:
But the image itself seems to have no problem:
Why does that happen? If the image.jpegData(compressionQuality:)
is set to 1.0
(no compression), this issue does not happen at all. Am I doing the image compression incorrectly?