Search code examples
iosobjective-cuiimagepickercontroller

"The file “IMG_xxxx.JPG” couldn’t be opened because there is no such file."


I'm trying to pass an image selected in an image picker to an API. To do so, I have to pass the full path of the image. What I'm currently doing is finding the image name, and the file path of the image, the appending the name onto the file path. Even after I pass this full path to the API, I still get the error described below:

Error Domain=NSCocoaErrorDomain Code=260 "The file “IMG_0082.JPG” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/private/var/mobile/Containers/Data/Application/C7C8D8A8-B9E7-4E4E-B35C-DBFB061804D6/tmp/IMG_0082.JPG, NSUnderlyingError=0x14fb200f0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

What is the problem? I've attached my full imagePickerController method below.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    // Dismiss image picker
    [picker dismissViewControllerAnimated:YES completion:nil];

    // Classify image
    UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];

    // Get image name
    NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[refURL] options:nil];
    NSString *filename = [[result firstObject] filename];

    // Get image file path and append file name onto it
    NSData *imageData = UIImagePNGRepresentation(image);
    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
    [imageData writeToFile:path atomically:YES];

    NSDictionary *headers = @{ @"content-type": @"multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
                               @"Content-Type": @"multipart/form-data",
                               @"Accept": @"application/json",
                               @"Authorization": @"Token 60f6be2a21bdf731d86a8817b440a1afba692fed",
                               @"Cache-Control": @"no-cache",
                               @"Postman-Token": @"79ca63d8-1bdc-f3e3-13cd-9bc18b68caa0" };
    NSArray *parameters = @[ @{ @"name": @"task", @"value": @"4b363547-58da-48a8-b76d-8877dd816d13" },
                             @{ @"name": @"image_file", @"fileName": @"/private/var/mobile/Containers/Data/Application/C7C8D8A8-B9E7-4E4E-B35C-DBFB061804D6/tmp/IMG_0082.JPG" } ];
    NSString *boundary = @"----WebKitFormBoundary7MA4YWxkTrZu0gW";

    NSError *error;
    NSMutableString *body = [NSMutableString string];
    for (NSDictionary *param in parameters) {
        [body appendFormat:@"--%@\r\n", boundary];
        if (param[@"fileName"]) {
            [body appendFormat:@"Content-Disposition:form-data; name=\"%@\"; filename=\"%@\"\r\n", param[@"name"], param[@"fileName"]];
            [body appendFormat:@"Content-Type: %@\r\n\r\n", param[@"contentType"]];
            [body appendFormat:@"%@", [NSString stringWithContentsOfFile:param[@"fileName"] encoding:NSUTF8StringEncoding error:&error]];
            if (error) {
                NSLog(@"%@", error);
            }
        } else {
            [body appendFormat:@"Content-Disposition:form-data; name=\"%@\"\r\n\r\n", param[@"name"]];
            [body appendFormat:@"%@", param[@"value"]];
        }
    }
    [body appendFormat:@"\r\n--%@--\r\n", boundary];
    NSData *postData = [body dataUsingEncoding:NSUTF8StringEncoding];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.vize.ai/v1/classify/"]
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:10.0];
    [request setHTTPMethod:@"POST"];
    [request setAllHTTPHeaderFields:headers];
    [request setHTTPBody:postData];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                    if (error) {
                                                        NSLog(@"%@", error);
                                                    } else {
                                                        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                        NSLog(@"%@", httpResponse);
                                                    }
                                                }];
    [dataTask resume];

Solution

  • Shouldn't the second parameter in the array be the location you've written the file too?

    So this...

    NSArray *parameters = @[ @{ @"name": @"task", @"value": @"4b363547-58da-48a8-b76d-8877dd816d13" },
                             @{ @"name": @"image_file", @"fileName": @"/private/var/mobile/Containers/Data/Application/C7C8D8A8-B9E7-4E4E-B35C-DBFB061804D6/tmp/IMG_0082.JPG" } ];
    

    should be

    NSArray *parameters = @[ @{ @"name": @"task", @"value": @"4b363547-58da-48a8-b76d-8877dd816d13" },
                             @{ @"name": @"image_file", @"fileName": path} ];