1

I'm trying to send an image (taken from the user using UIImagePickerController), to an API that is looking for a physical file. Either JPEG or PNG will do... Using this code...how do I format it to be sent?

My POST function... The "(image variable)" in the postString should be the image file...

var request = URLRequest(url: URL(string: "web address.php")!)
            request.httpMethod = "POST"
            let postString = "action=setDefendentData&username=\("\(userNameString!)")&datetime=\(localDate)&latitude=\(latitude!)&longitude=\(longitude!)&image=\(image variable)"
            request.httpBody = postString.data(using: .utf8)
            let task = URLSession.shared.dataTask(with: request) { data, response, error in
                guard let data = data, error == nil else {

                    OperationQueue.main.addOperation{
                        loginAlertPopup(title: "Error", message: "Invalid Source: Check Internet Connection")
                    }

                    // check for fundamental networking error
                    print("error=\(error)")
                    return
                }

                if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
                    print("statusCode should be 200, but is \(httpStatus.statusCode)")
                    print("response = \(response)")

                }

                let responseString = String(data: data, encoding: .utf8)

                if responseString! == "success" {
                    print("Good")

                    // Success Alert \\
                    self.presentAlert(title: "Success", message: "Check-In has been updated!")
                }

                if responseString! == "fail" {

                    print("failed sending image")
                    print("Post String: \(postString)")
                    // Alert Error \\

                    OperationQueue.main.addOperation{
                        self.presentAlert(title: "Error", message: "Failed Sending Data")
                    }
                }
            }
            task.resume()
        }

This is my code for saving the image to data using UIImagePickerController:

 let fileDirectory : NSURL  = {
            return try! FileManager.default.url(for: .documentDirectory , in: .userDomainMask , appropriateFor: nil, create: true)
        }() as NSURL

        let imageQuality: CGFloat = 0.5
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage

          // Saves to App Data
        let imagePath = fileDirectory.appendingPathComponent("uploadImage.jpg")
        guard let imageData = UIImageJPEGRepresentation(image, imageQuality) else {
            // handle failed conversion
            presentAlert(title: "Error", message: "Image Failure")
            print("jpg error")
            return
        }
        try! imageData.write(to: imagePath!)
            print("Image Path: \(imagePath!)")
            print("Image Size: \(imageData)")

        //Get Image
        let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        if let dirPath  = documentPath.first{
            let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("uploadImage.jpg")
            let newImage    = UIImage(contentsOfFile: imageURL.path)

I've tried sending through the image variable (newImage in this case) and it doesn't accept it. Ive created a temporary UIImageView on my view controller to display newImage and it updates accordingly... The API handler just doesn't accept it.

Any info/help please?

szady
  • 125
  • 1
  • 1
  • 9

2 Answers2

0

You cannot upload the image by putting the image variable in that post string like this

    let postString = "action=setDefendentData&username=\("\(userNameString!)")&datetime=\(localDate)&latitude=\(latitude!)&longitude=\(longitude!)&image=\(image variable)"
    request.httpBody = postString.data(using: .utf8)

Instead, your POST url should be like this:

yourUrlDomain/action=setDefendentData&username=\("\(userNameString!)")&datetime=\(localDate)&latitude=\(latitude!)&longitude=\(longitude!)

And you must post the image data that is appended to the httpBody.

NSMutableData *body = [NSMutableData data];

// Add __VIEWSTATE
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"__VIEWSTATE\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"/wEPDwUKLTQwMjY2MDA0M2RkXtxyHItfb0ALigfUBOEHb/mYssynfUoTDJNZt/K8pDs=" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

// add image data
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
if (imageData) {
    NSString *imageName = @"Any name you want";
    NSString *contentDisposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"imagefile\"; filename=\"%@\"\r\n",imageName];
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[contentDisposition dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imageData];
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}

[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];

Unfortunately, I made this code for my Objective-C iOS app and I'm not quite experienced with Swift. But you get the picture.

The Mach System
  • 6,703
  • 3
  • 16
  • 20
0
Use Alamofire for image upload -        
func makePostRequestForUploadingImage(_ service : String!, imageData     : Data?, responseCallBack : APIClientResponseCallBack!) {
    let urlString = self.urlStringWithService(service)
    Alamofire.upload(multipartFormData: { (multipartFormData) in
        if let _  = imageData  {

            multipartFormData.append(imageData!, withName: "", fileName: "", mimeType: "image/jpg")

        }
    }, to: urlString) { (encodingresult) in
        switch encodingresult {

        case .success(let upload, _, _):
            upload.responseJSON { response in
                responseCallBack? (response.response?.statusCode,response.result.value as AnyObject? , response.result.error as NSError?)
            }
        case .failure(let encodingError):
            print(encodingError)
        }
    }

}

    static func createBodyForMultiPart(input:Any, previousString:String,multipartFormData: MultipartFormData) {

    print("previousString -- ", previousString)

    if let dic = input as? [String:Any] {

        for key in dic.keys {
            self.createBodyForMultiPart(input: dic[key]!, previousString: previousString != "" ? (previousString + "[\(key)]") : "\(key)",multipartFormData: multipartFormData)
        }
    }
    else if let array = input as? [Any] {

        for i in 0..<array.count{

            self.createBodyForMultiPart(input: array[i], previousString: previousString + "[\(i)]",multipartFormData: multipartFormData)
        }

    }
    else if let number = input as? Int {

        multipartFormData.append(String(number).data(using:String.Encoding.utf8,allowLossyConversion:false )!, withName: previousString)


    }
    else if let text = input as? String{

        multipartFormData.append(text.data(using:String.Encoding.utf8,allowLossyConversion :false)!, withName: previousString)

    }
    else if let image = input as? UIImage {

        multipartFormData.append(UIImageJPEGRepresentation(image, 0.2)!, withName: previousString, fileName: "inspectionitem.jpeg", mimeType: "image/jpg")


    }
    else if let floatNumber = input as? Float {

        multipartFormData.append(String(floatNumber).data(using:String.Encoding.utf8,allowLossyConversion :false)!, withName: previousString)


    }


}

Set your parameters including the images you need to upload in parameters dict

Vaisakh Vinod
  • 267
  • 2
  • 14