ios Jsonobject +图像多部分AF网络

s71maibg  于 2023-03-05  发布在  iOS
关注(0)|答案(2)|浏览(95)

我们正在尝试使用AFNetworking向服务器发送多部分请求。我们需要发送一个JSON对象和两个图像文件。以下是相同的curl请求。
curl -X POST http://localhost:8080/Circle/restapi/offer/add -H "Content-Type: multipart/form-data" -F "offerDTO={"code": null,"name": "Merry X'Mas - 1","remark": "25% discount on every purchase","validityDate": "22-12-2014","domainCode": "DO - 1","merchantCode": "M-4","isApproved": false,"discountValue": 25,"discountType": "PERCENTAGE"};type=application/json" -F "image=@Team Page.png;type=image/png" -F "letterhead=@Team Page.png;type=image/png"
我知道这应该是相当容易的,因为我已经实现了服务器以及Android代码相同。和我的朋友是工作的iOS的一部分,这一点。我也搜索了很多谷歌,但没有得到任何有用的。

编辑

下面是我们尝试的代码:

UIImage *imageToPost = [UIImage imageNamed:@"1.png"];
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0);

offerDTO = [[NSMutableDictionary alloc]init];
[offerDTO setObject(angry)"" forKey:@"code"];
[offerDTO setObject:[NSString stringWithFormat:@"Testing"] forKey:@"discountDiscription"];
[offerDTO setObject:[NSString stringWithFormat:@"Test"] forKey:@"remark"];
[offerDTO setObject:@"07-05-2015" forKey:@"validityDate"];
[offerDTO setObject:@"C-7" forKey:@"creatorCode"];
[offerDTO setObject:@"M-1" forKey:@"merchantCode"];
[offerDTO setObject:[NSNumber numberWithBool:true] forKey:@"isApproved"];
[offerDTO setObject:@"2.4" forKey:@"discountValue"];
[offerDTO setObject:[NSString stringWithFormat:@"FREE"] forKey:@"discountType"];

NSURL *urlsss = [NSURL URLWithString:@"http://serverurl:8180"];
AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:urlsss];
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST" 
                                    path:@"/restapi/offer/add" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData)
                                    {
                                        NSData *myData = [NSJSONSerialization dataWithJSONObject:offerDTO
                                                            options:NSJSONWritingPrettyPrinted
                                                            error:NULL];

                                        [formData appendPartWithFileData:imageData name:@"image"
                                                            fileName:@"image.jpg" 
                                                            mimeType:@"image/jpeg"];
                                                            
                                        [formData appendPartWithFileData:imageData name:@"letterhead"
                                                            fileName:@"image.jpg" 
                                                            mimeType:@"image/jpeg"];
                                        
                                        [formData appendPartWithFormData:myData name:@"offerDTO"];
                                    }
                                ];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSDictionary *jsons = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];     
    }
     failure:^(AFHTTPRequestOperation operation, NSError error)
    {    
        NSLog(@"error: %@", [operation error]);
         
    }
];
iq3niunx

iq3niunx1#

几点意见:
1.您的示例是AFNetworking 1.x。AFNetworking 3.x副本可能如下所示:

NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"1" withExtension:@"png"];

// If you need to build dictionary dynamically as in your question, that's fine,
// but sometimes array literals are more concise way if the structure of
// the dictionary is always the same.

// Also note that these keys do _not_ match what are present in the `curl`
// so please double check these keys (e.g. `discountDiscription` vs
// `discountDescription` vs `name`)!

NSDictionary *offerDTO = @{@"code"                : @"",
                           @"discountDescription" : @"Testing",
                           @"remark"              : @"Test",
                           @"validityDate"        : @"07-05-2015",
                           @"creatorCode"         : @"C-7",
                           @"merchantCode"        : @"M-1",
                           @"isApproved"          : @YES,
                           @"discountValue"       : @2.4,
                           @"discountType"        : @"FREE"};

// `AFHTTPSessionManager` is AFNetworking 3.x equivalent to `AFHTTPClient` in AFNetworking 1.x

NSURL *baseURL = [NSURL URLWithString:@"http://serverurl:8180"];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];

// The `POST` method both creates and issues the request

[manager POST:@"/restapi/offer/add" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    NSError *error;
    BOOL success;

    success = [formData appendPartWithFileURL:fileURL
                                         name:@"image"
                                     fileName:@"image.jpg"
                                     mimeType:@"image/png"
                                        error:&error];
    NSAssert(success, @"Failure adding file: %@", error);

    success = [formData appendPartWithFileURL:fileURL
                                         name:@"letterhead"
                                     fileName:@"image.jpg"
                                     mimeType:@"image/png"
                                        error:&error];
    NSAssert(success, @"Failure adding file: %@", error);

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:offerDTO options:0 error:&error];
    NSAssert(jsonData, @"Failure building JSON: %@", error);

    // You could just do:
    //
    // [formData appendPartWithFormData:jsonData name:@"offerDTO"];
    //
    // but I now notice that in your `curl`, you set the `Content-Type` for the
    // part, so if you want to do that, you could do it like so:

    NSDictionary *jsonHeaders = @{@"Content-Disposition" : @"form-data; name=\"offerDTO\"",
                                  @"Content-Type"        : @"application/json"};
    [formData appendPartWithHeaders:jsonHeaders body:jsonData];
} progress:^(NSProgress * _Nonnull uploadProgress) {
    // do whatever you want here
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"responseObject = %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"error = %@", error);
}];

1.你在这里创建了一个操作,但是从来没有把它添加到队列中来启动它。我假设你在其他地方也这样做。值得注意的是AFHTTPSessionManager不支持像已经过时的AFHTTPRequestOperationManagerAFHTTPClient那样的操作。上面的代码只是自动启动操作。
1.注意,AFNetworking现在假设响应是JSON,假设代码建议响应是JSON,那么注意不需要JSONObjectWithData,因为已经为您完成了。

  • 现在您的代码是(a)创建UIImage;(B)将其转换回NSData;以及(c)将其添加到formData。由于许多原因,这是低效的:
  • 具体来说,通过获取图像资源,将其加载到UIImage中,然后使用UIImageJPEGRepresentation,可能会使生成的NSData比原始资源大得多。您可能会考虑直接获取原始资源,完全绕过UIImage,然后发送它(显然,如果要发送PNG,也要更改MIME类型)。
  • NSData添加到请求的过程可能会导致内存占用量增加。通常,如果您提供一个文件名,它可以将内存使用峰值保持在较低的水平。
xwbd5t1u

xwbd5t1u2#

您可以将NSDictionary直接传递到参数字段中的管理器发布块

UIImage *imageToPost = [UIImage imageNamed:@"1.png"];
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0);

NSDictionary *offerDTO = @{@"code"                : @"",
                           @"discountDescription" : @"Testing",
                           @"remark"              : @"Test",
                           @"validityDate"        : @"07-05-2015",
                           @"creatorCode"         : @"C-7",
                           @"merchantCode"        : @"M-1",
                           @"isApproved"          : @YES,
                           @"discountValue"       : @2.4,
                           @"discountType"        : @"FREE"};

NSURL *baseURL = [NSURL URLWithString:@"http://serverurl:8180"];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];

[manager POST:@"/restapi/offer/add" parameters:offerDTO constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileData:imageData name:@"image"
                            fileName:@"image.jpg"
                            mimeType:@"image/jpeg"];

    [formData appendPartWithFileData:imageData name:@"letterhead"
                            fileName:@"image.jpg"
                            mimeType:@"image/jpeg"];

    [formData appendPartWithHeaders:jsonHeaders body:jsonData];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"responseObject = %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"error = %@", error);
}]

;

相关问题