执行JSON序列化时出错,数据格式不正确

我正在尝试将个人资料图片上传到服务器。 但我在做JSON Serialization遇到错误。

日志中的错误消息是

[Generic]创建具有未知类型的图像格式是错误,

无法读取数据,因为格式不正确

从照片库中选择图像后,图像显示在用户界面中,但图像未成功上传到服务器,因此可能这就是我在进行JSON序列化时出错的原因。 但我不知道为什么说不正确的格式,因为我尝试上传jpeg格式的图像。

这是简化的代码。 什么地方出了错? 🙁

 import UIKit class HomepageVC: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate { @IBAction func editProfilePictureButtonDidPressed(_ sender: Any) { // users choose photo from library or camera let imagePickerController = UIImagePickerController() imagePickerController.delegate = self imagePickerController.allowsEditing = true let actionSheet = UIAlertController(title: "Photo Source", message: "please choose your source", preferredStyle: .actionSheet) // action camera let actionCamera = UIAlertAction(title: "Camera", style: .default) { (action) in if UIImagePickerController.isSourceTypeAvailable(.camera) { imagePickerController.sourceType = .camera self.present(imagePickerController, animated: true, completion: nil) } else { self.showAlert(alertTitle: "Opppss", alertMessage: "camera can't be used / not available", actionTitle: "OK") print("camera can't be used / not available") } } // action photo library let actionPhotoLibrary = UIAlertAction(title: "Photo Library", style: .default) { (action) in imagePickerController.sourceType = .photoLibrary self.present(imagePickerController, animated: true, completion: nil) } //action cancel let actionCancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) actionSheet.addAction(actionCamera) actionSheet.addAction(actionPhotoLibrary) actionSheet.addAction(actionCancel) self.present(actionSheet, animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { let image = info[UIImagePickerControllerOriginalImage] as! UIImage avatarImage.image = image picker.dismiss(animated: true, completion: nil) // call func of uploading file to PHP server uploadAvatar() } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true, completion: nil) } // custom HTTP request body to upload image file func createBodyWithParams(_ parameters: [String: String]?, filePathKey: String?, imageDataKey: Data, boundary: String) -> Data { var body = Data(); if parameters != nil { for (key, value) in parameters! { body.appendString("--\(boundary)\r\n") body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") body.appendString("\(value)\r\n") } } // kita set agar image yang di upload kemudian berformat .jpg let filename = "avatar.jpg" let mimetype = "image/jpg" body.appendString("--\(boundary)\r\n") body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n") body.appendString("Content-Type: \(mimetype)\r\n\r\n") body.append(imageDataKey) body.appendString("\r\n") body.appendString("--\(boundary)--\r\n") return body as Data } // uploading image to server func uploadAvatar() { // get ID from Default variable let id = userInfo!["id"] as! String let url = URL(string: "http://localhost/Twitter/uploadAvatar.php")! var request = URLRequest(url: url) request.httpMethod = "POST" let param = ["id" : id] let boundary = "Boundary-\(UUID().uuidString)" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") let imageData = UIImageJPEGRepresentation(avatarImage.image!, 0.5) // if not compressed, return ... do not continue to code if imageData == nil { return } // constructing http body request.httpBody = createBodyWithParams(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary) // launc session URLSession.shared.dataTask(with: request) { data, response, error in DispatchQueue.main.async(execute: { if error == nil { // if error is nil, then show message from server do { // json containes $returnArray from php let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary // declare new parseJSON to store json guard let parsedJSON = json else { print("Error while parsing") return } // get id from $returnArray["id"] in PHP - parseJSON["id"] let id = parsedJSON["id"] // successfully uploaded if id != nil { // save user information from Server UserDefaults.standard.set(parsedJSON, forKey: "parsedJSON") // if no ID from server then show the message from server } else { // get main queue to communicate back to user DispatchQueue.main.async(execute: { let message = parsedJSON["message"] as! String self.showAlert(alertTitle: "opppps", alertMessage: message, actionTitle: "OK") }) } // error doing JSON serialization } catch { // get main queue to communicate back to user DispatchQueue.main.async(execute: { let message = error.localizedDescription self.showAlert(alertTitle: "Sorry", alertMessage: message, actionTitle: "OK") }) } // error ketika koneksi ke server } else { // get main queue to communicate back to user DispatchQueue.main.async(execute: { let message = error!.localizedDescription self.showAlert(alertTitle: "oppps", alertMessage: message, actionTitle: "OK") }) } }) }.resume() } } // extend data extension Data { mutating func appendString(_ string : String) { let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true) append(data!) } } 

打印服务器数据以获取更多详细信息。 像服务器错误或任何其他细节。

 URLSession.shared.dataTask(with: request) { data, response, error in DispatchQueue.main.async(execute: { // server data is convert in to string and print it let strData = String.init(data: data!, encoding: String.Encoding.utf8) print(strData ) }) } 

服务器返回的响应不是JSON格式。 您可以使用该工具首先测试请求。

打印出错误代码不是HTTP错误代码,因为无法解析JSON