等待多部分图像发送完成 [英] Waiting for multipart image sending get completed

查看:77
本文介绍了等待多部分图像发送完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在iOS7中使用一个应用程序,它是一种社交网络应用程序,带有带有图像的帖子和一个后端,用于保存从客户端发送来的所有数据. iOS客户端通过json发送帖子的信息,信息发送后,它开始使用AFNetworking通过多部分形式发送图像.

I'm impementing an application in iOS7, it's kind of a social network app with posts with images and a backend that saves all of the data sent form the client. The iOS client is sending the information of the post via json and after the info is sent, it starts to send the image via multipart form using AFNetworking.

发送图像时需要通知我,以便我可以使用新帖子(包括客户端最近发布的帖子)刷新应用程序的主视图.在实践中,如果我请求最后一个帖子的后端,而多部分还没有完成,则图像的发送会被打乱而无法发送图像.

I need to be notified when the image is sent, so that I can refresh the main view of the app with the new posts, including the recently posted by the client. In the practice if I request the backend for the last posts and the multipart hasn't finished, the sending of the image gets interruped and fails to send the image.

后端是在WCF中开发的,并且是RESTful JSON Web服务.

The backend is develop in WCF and is a RESTful JSON web service.

这是将帖子发送到后端的方法:

Here is the method that sends the post to the backend:

+(void)addPostToServerAddtext:(NSString *)text addimage:(UIImage *)image addbeach:(NSString *)beach location:(NSString*)location;
{
    NSLog(@"entro a addPost");
    NSString *urlBackend = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"URLBackend"];

    NSData* dataImage = UIImageJPEGRepresentation(image, 1.0);
    NSString* ImageName = [NSString stringWithFormat:@"%@_%@.jpg",idUser ,dateToServer];
    NSString *jsonRequest = [NSString stringWithFormat:@"{\"Date\":\"%@\"...."];

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@newPost",urlBackend]];

    NSMutableURLRequest *request = [ [NSMutableURLRequest alloc] initWithURL:url];
    NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:requestData];

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];

    if (image != nil) {

        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        [manager POST:[NSString stringWithFormat:@"%@FileUpload",urlBackend]
           parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
            [formData appendPartWithFileData:dataImage name:@"image" fileName:ImageName mimeType:@"image/jpg" ];
        }
              success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"Success: %@", responseObject);
        }
              failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
        }];
    }
}

推荐答案

一些想法:

  1. 您说:

  1. You say:

iOS客户端通过json发送帖子的信息,信息发送后,它开始使用AFNetworking通过多部分形式发送图像.

The iOS client is sending the information of the post via json and after the info is sent, it starts to send the image via multipart form using AFNetworking.

从技术上讲,您不是在等待信息发送,而是同时进行这些操作.您是否希望这些是并发的?还是顺序的?还是为什么不只是发布信息和图像的单个请求?

Technically, you're not waiting for the information to be sent, but you're doing these concurrently. Do you want these to be concurrent? Or sequential? Or why not just a single request that posts the information as well as the image?

我建议对两个请求都使用AFNetworking.您已经有了一个强大的框架来管理网络请求,并且在那里看到冗长的NSURLConnection代码感到很尴尬.

I'd suggest using AFNetworking for both requests. You've got a powerful framework for managing network requests, and it feels awkward to see hairy NSURLConnection code in there.

如果在其中保留NSURLConnection代码,请注意,您想要start一个NSURLConnection,除非您对最后一个参数使用initWithRequest:delegate:startImmediately:NO .您实际上将其启动了两次,这可能会导致问题.我建议删除start呼叫.

If you keep the NSURLConnection code in there, note that you do not want to start a NSURLConnection, unless you used initWithRequest:delegate:startImmediately: with NO for that last parameter. You're effectively starting it twice, which can cause problems. I'd suggest removing the start call.

将所有内容放在一旁,您要做的是在您的方法中添加一个完成块参数,例如:

Setting all of that aside, what you want to do is to add a completion block parameter to your method, e.g., something like:

+ (void)addPostToServerAddtext:(NSString *)text addimage:(UIImage *)image addbeach:(NSString *)beach location:(NSString*)location completion:(void (^)(id responseObject, NSError *error))completion
{
    // ...

    if (image != nil) {

        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        [manager POST:[NSString stringWithFormat:@"%@FileUpload",urlBackend] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
            [formData appendPartWithFileData:dataImage name:@"image" fileName:ImageName mimeType:@"image/jpg" ];
        } success:^(AFHTTPRequestOperation *operation, id responseObject) {
            if (completion) completion(responseObject, nil);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            if (completion) completion(nil, error);
        }];

    }
}

然后您将像这样调用它:

You'd then invoke that like so:

[Persistence addPostToServerAddtext:text addimage:image addbeach:nil location:annotation completion:^(id responseObject, NSError *error) {
    if (error) {
        // handle error
        return
    }

    // otherwise use the responseObject
}];

现在,我不知道要在完成块中返回哪些参数(我假设您想返回AFHTTPRequestOperationManager所做的操作),但只需更改该completion块的参数即可您的需求.

Now, I don't know what parameters you want to return in your completion block (I'm assuming you wanted to return what the AFHTTPRequestOperationManager did), but just change the parameters for that completion block as suits your needs.

与您的原始问题无关,但我注意到您正在像这样构建jsonRequest:

Unrelated to your original question, but I notice that you're building jsonRequest like so:

NSString *jsonRequest = [NSString stringWithFormat:@"{\"Date\":\"%@\"...."];

如果这些字段中的任何一个包含用户提供的信息(例如,如果用户在提供的信息中使用双引号怎么办),那就有点冒险了.我建议您建立一个字典,然后从中建立jsonRequest.它将更加强大.因此:

That's a little risky if any of those fields include user supplied information (e.g. what if the user used double quotes in the information provided). I'd suggest you build a dictionary, and then build the jsonRequest from that. It will be more robust. Thus:

NSDictionary *dictionary = @{@"Date"    : date,
                             @"Message" : message};
NSError *error = nil;
NSData *request = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
if (error)
    NSLog(@"%s: dataWithJSONObject error: %@", __FUNCTION__, error);

或者,如果您使用AFNetworking,我相信它将为您完成字典的JSON转换.但是,最重要的是,至少在请求中可能包含用户提供的任何信息时,请务必谨慎自行创建JSON字符串.

Or, if you use AFNetworking, I believe it will do this JSON conversion of your dictionary for you. But, bottom line, be very wary about creating JSON strings yourself, at least if the request might include any user supplied information.

这篇关于等待多部分图像发送完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆