-1

I'm building an app that can send a .jpeg files to the server. So what I want to do is I have a controller to take a photo and send the photo to the server. Of course the first photo format is a UIImage, which would not work when I send it to the server because the server doesn't accept UIImage file types. So I've done a bit of a research and found the function to convert UIImage to .jpeg file format like this:

let photoJpg = self.photo?.jpegData(compressionQuality: 1.0)

And I pass the photoJpg variable to the API call function, but the API keeps rejecting my request, by saying 500 status code when calling the API. So I'm guessing I might not convert the file the right way. So how can I convert the UIImage to a .jpeg file format, store it into a variable and send it to the API? If you need more info feel free to ask and I will provide it to you. Thank you.

EDIT: The function to call the API

func submitPhoto() {
        let headers = ["authorization": registerData!.token]
        let photoJpg = self.photo?.jpegData(compressionQuality: 1.0)

        let params: [String: Any] = [
            "files": photoJpg!
        ]

        Webservice.Request(url: Webservice.SUBMIT_PHOTO, method: Webservice.HttpMethod.post, parameters: params, headers: headers, loading: true, loadingString: nil, success: { (response) in
            print("Submit photo success")
        }) { (response) in
            print("Submit photo failed")
        }
    }

The Request function in Webservice class

class func Request(url: String, method: HttpMethod, parameters: [String: Any], headers: [String:String], loading: Bool, loadingString: String?, success: @escaping (JSON) -> Void, failure: @escaping (Error) -> Void) {
        if manager == nil {
            let urlConfig = URLSessionConfiguration.default
            urlConfig.timeoutIntervalForRequest = KPMConfig.RTO_TIME
            manager = SessionManager(configuration: urlConfig)
        }
        let request = manager.request(url, method: method == .post ? HTTPMethod.post : HTTPMethod.get, parameters: parameters, encoding: URLEncoding.default, headers: headers)
        if loading {
            ProgressHUD.show(loadingString, interaction: false)
        }
        print("-url: \n\(url)")
        print("-params: \n\(parameters)")
        print("-headers: \n\(headers)")
        request.responseJSON { (response) in
            if loading {
                ProgressHUD.dismiss()
            }
            switch response.result {
            case .success(let values):
                let data = JSON(values)
                print("response: \n\(data)")
                switch data["code"].intValue {
                case 200...203:
                    success(data)
                case 400...403:
                    let errorDetails = Error(
                        error: ErrorModel(code: data["error"]["code"].stringValue,
                                     message: data["error"]["message"].stringValue,
                                     target: data["error"]["target"].stringValue,
                                     details: data["error"]["details"]),
                        code: data["code"].intValue)
                    failure(errorDetails)

                        if data["code"].intValue == 401 {
                            print("-url: \n\(url)")
                            self.removeUserData()
                            self.goToLoginPage()
                        }

                case 500:
                    let errorDetails = Error(
                        error: ErrorModel(code: data["error"]["code"].stringValue,
                                     message: data["error"]["message"].stringValue,
                                     target: data["error"]["target"].stringValue,
                                     details: data["error"]["details"]),
                        code: data["code"].intValue)
                    failure(errorDetails)
                default:
                    break
                }
            case .failure(let values):
                let data = JSON(values)
                print("-response: \n\(data)")
                let errorDetails = Error(
                    error: ErrorModel(code: data["error"]["code"].stringValue,
                                 message: data["error"]["message"].stringValue,
                                 target: data["error"]["target"].stringValue,
                                 details: data["error"]["details"]),
                    code: data["code"].intValue)    
                failure(errorDetails)
            }
        }
    }
cleanrun
  • 549
  • 6
  • 20
  • 1
    Does this answer your question? [How to upload images to a server in iOS with Swift?](https://stackoverflow.com/questions/26335656/how-to-upload-images-to-a-server-in-ios-with-swift) – Keshu R. Jun 05 '20 at 07:18
  • 500 errors are internal server errors, it doesn't necessarily mean that your request is wrong. That said we need way more info to diagnose this. Who's in charge of the server, did you build it? How are you calling the API? Is `self.photo` not `nil`? Do you have access to server logs? – EmilioPelaez Jun 05 '20 at 07:24
  • @EmilioPelaez unfortunately i'm not the one who made the server nor in charge of it. i called the api by calling the function already provided to send the datas to the server – cleanrun Jun 05 '20 at 07:30
  • By "how are you calling the API" I mean we need to see code. We can't help you fix your code if we haven't seen it. – EmilioPelaez Jun 05 '20 at 08:13
  • @EmilioPelaez sorry for not making it clearer, i've added more code for you to read – cleanrun Jun 05 '20 at 08:23

2 Answers2

2

You need to save image in document directory You can then send the jpeg file to server, as that is what you require to do.

func saveImageAndGetData(name: String, image: UIImage) -> Data? {


     guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil}

  let fileName = name
  let fileURL = documentsDirectory.appendingPathComponent(fileName)
   guard let data = image.jpegData(compressionQuality: 1) else { return nil}


//Checks if file exists, removes it if so.
  if FileManager.default.fileExists(atPath: fileURL.path) {
    do {
        try FileManager.default.removeItem(atPath: fileURL.path)
        print("Removed old image")
    } catch let removeError {
        print("couldn't remove file at path", removeError)
    }

}

  do {
    try data.write(to: fileURL)
  } catch let error {
    print("error saving file with error", error)
  }
     return data
}

Get data like this

if let imageData = saveImageAndGetData(name: "name", image: UIImage(named: "image")!) {

}

To load image

func loadImageFromDisk(fileName: String) -> UIImage? {

  let documentDirectory = FileManager.SearchPathDirectory.documentDirectory

    let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
    let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)

    if let dirPath = paths.first {
        let imageUrl = URL(fileURLWithPath: dirPath).appendingPathComponent(fileName)
        let image = UIImage(contentsOfFile: imageUrl.path)
        return image

    }

    return nil
}
Jawad Ali
  • 13,556
  • 3
  • 32
  • 49
  • Yes it doesn't work for me. I got this error message `"The file couldn’t be saved because the specified URL type isn’t supported."` – cleanrun Jun 05 '20 at 07:47
  • 2
    While you're updating your answer why not change "You can do it like this" to something more descriptive and meaningful – Joakim Danielson Jun 05 '20 at 07:48
  • @jawadAli i'm assuming this function is to only save the file? is there any way of getting the file before sending it to the server? – cleanrun Jun 05 '20 at 08:12
1

Edit: here is how the getDocumentsDirectory function:

func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory

}

Well the code you have posted gives you JPEG data and not a JPEG file, you still need to save it to file, like this:

if let data = image.jpegData(compressionQuality: 0.8) {
    let jpegFile = getDocumentsDirectory().appendingPathComponent("copy.jpg")
    try? data.write(to: filename)
}

You can then send the jpegFile to server, as that is what you require to do.

Mohammad Assad Arshad
  • 1,535
  • 12
  • 14