1

我正在尝试将带有 UIImagePickerController 的 UIImage 连同其他相关值一起发送到服务器 POST。但是我遇到了试图将字典值@“image”设置为 UIImageJPEGRepresentation(image, 1.0) 的行:

-(void)sendImageToServer:(UIImage *)image
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 4;

    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:nil delegateQueue:queue];
    NSURL *uploadURL = [NSURL URLWithString:@"http://...."];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:uploadURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];

    [request addValue:@"application/json" forHTTPHeaderField:@"Accept"];

    [request setHTTPMethod:@"POST"];

    NSData *postData = [[NSData alloc] init];
    [postData setValue:UIImageJPEGRepresentation(image, 1.0) forKey:@"image"];
    [postData setValue:@"1" forKey:@"categories[0]"];
    [postData setValue:@"4" forKey:@"categories[1]"];

    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
                                                               fromData:postData
                                                      completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        if (!error) {
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            if (httpResponse.statusCode == 200) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSError *err;
                    NSDictionary *JSONDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
                    NSLog(@"HTTP 200 response: %@", JSONDict);
                });
            } else {    
                NSLog(@"HTTP %ld status!", (long)httpResponse.statusCode);
            }   
        } else {
            NSLog(@"HTTP post image error: %@", error);
        }
    }];
    [uploadTask resume];
}

JSON 序列化在这里不起作用,因为图像不是有效的 JSON 值。另一方面,如果我尝试:

...
NSMutableData *postData = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:postData];

    [archiver encodeObject:UIImageJPEGRepresentation(image, 1.0) forKey:@"image"];
    [archiver encodeObject:@"1" forKey:@"categories[0]"];
    [archiver encodeObject:@"4" forKey:@"categories[1]"];
    [archiver finishEncoding];



    //NSData *postData = [NSJSONSerialization dataWithJSONObject:dataDict options:NSJSONWritingPrettyPrinted error:&jsonError];
    //Now you can post the json data

    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
                                                               fromData:postData
                                                      completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {...

归档的键:值对似乎并没有像这样到达服务器。这一定是一项常规的 iOS 编码任务。

即使我只是尝试:

NSError *jsonError;
    NSData *postData = [NSJSONSerialization dataWithJSONObject:@{@"image":@"123",@"categories[0]":@"1",@"categories[1]":@"4"} options:NSJSONWritingPrettyPrinted error:&jsonError];

服务器根本没有得到任何密钥......

4

3 回答 3

0

使用 AFNetworking 和多部分表单发布。这是一个粗略的示例(注意我传入了一个块,因此您的实现会有所不同):

AFHTTPRequestOperation *operation = [self POST:FullURLString parameters:Params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData:fileData name:fileName fileName:fileName mimeType:mimeType];
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSData *responseData = [operation responseData];
        id retObj;
        NSError *error = nil;
        if (responseData) {
            retObj = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
        }
        // Pass back the serialized object (either an NSArray of type NSDictionaries or an NSArray of type customClass)
        block(retObj);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Failed with error = [Error]: %@", error);
        block(nil);
}];
于 2014-09-23T19:18:04.957 回答
0

试试 AFNetworking,它有一个很好的上传方式,你可以在这里找到示例:https ://github.com/AFNetworking/AFNetworking#creating-an-upload-task

我个人建议大家使用它,因为我开始使用我的应用程序与网络服务器通信没有任何麻烦。

于 2014-09-23T18:25:03.590 回答
0

这不是NSData. 它现在崩溃了,因为NSData没有名为 image 的键(..或之后的其他两个)。您需要做的是创建一个NSDictionary然后将其转换为NSData.

改为执行以下操作:

NSDictionary *dictionary = [NSDictionary alloc]initWithObjectsAndKeys:image,@"image",@(1),@"categories[0]",@(4),@"categories[1]", nil];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dictionary]; //Not currently using NSJSONSerialization since you want to post a Dictionary with an invalid NSJSONSerialization type in it.
//Now you can post the json data
于 2014-09-23T17:09:22.933 回答