Jonathan
Jonathan

Reputation: 614

AFNetworking POST Writes to Server and Returns Failure Error (Cocoa Error 3840)

I've been working on getting some jpg images uploaded to a server with AFNetworking 2.0 and some code I came across on stackoverflow, but I've been getting a Cocoa error 3840. I looked this up and found that some information regarding txt files, but I am not uploading txt files, so this has me confused. When I execute this code it starts writing to the server for a while until it crashes with the following statement:

Failure Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x155b1360 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

I am still new to AFNetworking so can someone please explain what is causing this error?

Also one other problem I'm having while writing this code is that I'm trying to save NSData by using the dataWithContentsOfFile method, but it keeps returning nil after using that method. I've tried multiple ways of doing it, which are coded out below. When I use the pathForResource (_filename contains the extension) for fileRoot it returns nil, but the other method stringByAppendingPathComponent works as expected, but then even after having the correct path as the parameter for dataWithContentsOfFile it still returns nil for imageToUpload. For now I just settled using UIImageJPEGRepresentation to get it working.

Can someone also please explain what might be causing that?

Sorry if I am not supposed to post 2 separate questions in one post. My first question is the most pressing. Thank you.

NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
                                _username, @"username",
                                _filename, @"filename",
                                _metadata, @"metadata",
                                nil];

    // 1. Create `AFHTTPRequestSerializer` which will create your request.
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];

    //NSString* fileRoot = [[NSBundle mainBundle] pathForResource:_filename ofType:nil];
    //NSString *fileRoot=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:_filename];
    //NSData *imageToUpload = [NSData dataWithContentsOfFile:fileRoot];
    NSData *imageToUpload = UIImageJPEGRepresentation(_savedFiles[_selectedRowNumber], 1.0);

    // 2. Create an `NSMutableURLRequest`.
    NSMutableURLRequest *request =
    [serializer multipartFormRequestWithMethod:@"POST" URLString:@"http://69.91.198.44:8080/GeodatabaseServer/FileUpload"
                                    parameters:parameters
                     constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                         [formData appendPartWithFileData:imageToUpload
                                                     name:_filenameNoExt
                                                 fileName:_filename
                                                 mimeType:@"image/jpeg"];
                     }error:nil];

    // 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created.
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    AFHTTPRequestOperation *operation =
    [manager HTTPRequestOperationWithRequest:request
                                     success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                         NSLog(@"Success %@", responseObject);
                                     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                         NSLog(@"Failure %@", error.description);
                                     }];

    // 4. Set the progress block of the operation.
    [operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
                                        long long totalBytesWritten,
                                        long long totalBytesExpectedToWrite) {
        NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
    }];

    // 5. Begin!
    [operation start];

Upvotes: 1

Views: 491

Answers (1)

Jonathan
Jonathan

Reputation: 614

I was able to fix the failure to upload by setting the following property:

manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];

I was also able to fix my second issue by not using the bundle method and instead grabbing from my documents directory as follows:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:_filename];

Upvotes: 1

Related Questions