-1

For reference, here is the working android/Java version of what I am trying to do in iOS/Objective-c

public static void saveTextsAndImagesOnServer(List<byte[]> images, long someID1, String servingUrl, boolean someFlag)
            throws ClientProtocolException, IOException {
        Log.d(TAG, "saveTextsAndImagesOnServer started ");
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost postRequest = new HttpPost(servingUrl);
        MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

        AdditionData extr = AdditionData.getInstance();
        reqEntity.addPart("red", new ByteArrayBody(("" + extr.getred()).getBytes(), "red"));
        reqEntity.addPart("yellow", new ByteArrayBody(extr.getyellow.getBytes(), "yellow"));
        reqEntity.addPart("green", new ByteArrayBody(extr.getgreen().getBytes(), "green"));
        reqEntity.addPart("blue", new ByteArrayBody((extr.getblue()).getBytes(), "blue"));
        reqEntity.addPart("someID1", new ByteArrayBody(("" + someID1).getBytes(), "someID1"));
        if (someFlag) {
            reqEntity.addPart("someFlag", new ByteArrayBody("true".getBytes(), "someFlag"));
        }
        int i = 0;
        for (byte[] img : images) {
            ByteArrayBody image = new ByteArrayBody(img, "img" + i++ + ".png");
            reqEntity.addPart("image", image);
        }
        postRequest.setEntity(reqEntity);
        HttpResponse response = httpClient.execute(postRequest);
        Log.d(TAG, "saveTextsAndImagesOnServer ended with response " + response.toString());
    }

summary: Basically I am able to send an image and accompanying metadata to the blobstore. The metadata helps me identify, for example, who sent the image.

Now trying to do the same thing in iOS I wrote the code below. But for whatever reason, the metadata is not been saved in the blobstore. I try a bunch of different things but I am still getting nothing. I try changing my metadata strings to base-64 but that didn’t work.

THE IOS CODE

-(void)postMultipartToServer
{
    if (!self.destinationUrl) {
        return;
    }

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSLog(@"IS dictionary empty? %@", self.textDictionary);

    [manager POST:self.destinationUrl
       parameters:self.textDictionary
    constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        if ([self.imageDictionaries count]>0)
            for (NSDictionary *imgDic in self.imageDictionaries) {
                [formData appendPartWithFileData:UIImagePNGRepresentation([imgDic objectForKey:@"image"])
                                            name:[imgDic objectForKey:@"name"]//@"image"
                                        fileName:[imgDic objectForKey:@"fileName"]//@"image.png"
                                        mimeType:[imgDic objectForKey:@"mimeType"]//@"image/png"
                 ];
            }


    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"Success: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

Here is the dictionary

 NSDictionary *textDictionary = @{
                                 @"yellow”:self. yellow,
                                 @"red":self. red,
                                 @"green”:self.green,
                                 @“blue”:self. blue,
                                 @“spouse”:self.spouse,
                                 @"isFamouse”:@”true”};//you get the idea

Where am I?

Given that this design works on android, I know it’s possible especially since http is supposed to be agnostic when it comes to languages. So the problem is reduced to saving string from iOS to the Google blobstore.

I am starting a bounty in hope someone will help me resolve this issue (perhaps a google blobstore-iOS expert). I also noticed other people have asked fairly the same question, but no answer. Other ways I have asked this question:

AFHTTPRequestOperationManager post multi-part request not working

How to convert NSString to UIImage for appengine blobstore

Community
  • 1
  • 1
learner
  • 11,490
  • 26
  • 97
  • 169
  • FYI: the destination is the Google Blobstore (if this matters somehow) – learner Jul 14 '14 at 23:55
  • This site isn't a free code translation service. Do your own work first. If you have a specific problem, post the relevant code and explain your issue. – rmaddy Jul 15 '14 at 00:30
  • @rmaddy I have done so and now am starting a bounty. – learner Aug 04 '14 at 01:42
  • for the java code reference: `HttpMultipartMode.BROWSER_COMPATIBLE` makes the MultipartEntity omit the 'Content-Type' and 'Content-Transfer-Encoding' flags for compatibility with older web servers. Is there something equivalent for AFNetworking? or iOS/Objective-c? – learner Aug 04 '14 at 20:16

2 Answers2

1

Replace the method as follows

-(void)postMultipartToServer
{
    if (!self.destinationUrl) {
        return;
    }

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    [manager POST:self.destinationUrl
       parameters:nil
    constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

        if ([self.textDictionary count]>0){
            if ([self.textDictionary count]>0)
                [self.textDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
                    [formData appendPartWithFileData:[object dataUsingEncoding:NSUTF8StringEncoding]
                                                name:key
                                            fileName:key
                                            mimeType:@"application/json"
                     ];

                }];
        }

        if ([self.imageDictionaries count]>0)
            for (NSDictionary *imgDic in self.imageDictionaries) {
                [formData appendPartWithFileData:UIImagePNGRepresentation([imgDic objectForKey:@"image"])
                                            name:[imgDic objectForKey:@"name"]//@"image"
                                        fileName:[imgDic objectForKey:@"fileName"]//@"image.png"
                                        mimeType:[imgDic objectForKey:@"mimeType"]//@"image/png"
                 ];
            }
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"Success: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}
Konsol Labapen
  • 2,424
  • 2
  • 15
  • 12
0

In the end the http request will be a string. You could log that string. Probably want to use a small image for that. Then do the same for the android request and see what the difference is.

How to print AFNetworking request as RAW data

Community
  • 1
  • 1
DylanVann
  • 483
  • 5
  • 9
  • I get the log for AFNetworking 2.0 but it does not show the content of the POST. As for the accepted answer, I don't understand how to implement it. – learner Aug 04 '14 at 05:36
  • If it doesn't solve your problem there's no reason to accept it. Oops, trying to do a line break, but it posted. The return value of "[manager POST: ..." is AFHTTPRequestOperation. If you declare a variable "request" for that you can then put this "[[NSString alloc] initWithData:request.HTTPBody encoding:4]" inside the success and failure blocks to log the request body. I'm not 100% on any of this to be honest, I've done iOS networking but not with AFNetworking. Just trying to help. – DylanVann Aug 04 '14 at 19:45