2017-12-18 151 views
1

我试图将配置文件图片上传到服务器。但我在做JSON Serialization时遇到了错误。在做JSON序列化时出错,数据格式不正确

日志中的错误消息是

[通用]创建具有一个未知类型的图像格式错误,

的数据不能因为它读格式不正确

从照片库中选择图像后,图像出现在用户界面中,但图像未成功上传到服务器,所以也许这就是为什么我在执行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!) 

    } 

} 

回答

1

您的服务器数据是打印更多的细节。像服务器错误或任何其他细节。

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