Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Objective-C发布多部分/表单数据_Objective C_Http Post_Multipartform Data_Http Post Vars - Fatal编程技术网

使用Objective-C发布多部分/表单数据

使用Objective-C发布多部分/表单数据,objective-c,http-post,multipartform-data,http-post-vars,Objective C,Http Post,Multipartform Data,Http Post Vars,因此,这个HTML代码以正确的格式为我提交数据 <form action="https://www.example.com/register.php" method="post" enctype="multipart/form-data"> Name: <input type="text" name="userName"><BR /> Email: <input type="text" name="userEmail"><BR

因此,这个HTML代码以正确的格式为我提交数据

<form action="https://www.example.com/register.php" method="post" enctype="multipart/form-data">
    Name: <input type="text" name="userName"><BR />
    Email: <input type="text" name="userEmail"><BR />
    Password: <input type="text" name="userPassword"><BR />
    Avatar: <input type="file" name="avatar"><BR />
    <input type="submit">
</form>

名称:
电子邮件:
密码:
化身:
我已经阅读了大量关于如何在iOS上发布多部分/表单数据的文章,但没有一篇真正解释如果存在正常参数以及文件上传,该怎么做

你能帮我把代码贴在Obj-C上吗


谢谢

过程如下:

  • 使用
    userName
    userEmail
    userPassword
    参数创建字典

    NSDictionary *params = @{@"userName"     : @"rob",
                             @"userEmail"    : @"rob@email.com",
                             @"userPassword" : @"password"};
    
  • 确定图像的路径:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"avatar" ofType:@"png"];
    
  • 创建请求:

    NSString *boundary = [self generateBoundaryString];
    
    // configure the request
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    
    // set content type
    
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField: @"Content-Type"];
    
    // create body
    
    NSData *httpBody = [self createBodyWithBoundary:boundary parameters:params paths:@[path] fieldName:fieldName];
    
    - (NSData *)createBodyWithBoundary:(NSString *)boundary
                            parameters:(NSDictionary *)parameters
                                 paths:(NSArray *)paths
                             fieldName:(NSString *)fieldName {
        NSMutableData *httpBody = [NSMutableData data];
    
        // add params (all params are strings)
    
        [parameters enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) {
            [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8StringEncoding]];
        }];
    
        // add image data
    
        for (NSString *path in paths) {
            NSString *filename  = [path lastPathComponent];
            NSData   *data      = [NSData dataWithContentsOfFile:path];
            NSString *mimetype  = [self mimeTypeForPath:path];
    
            [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, filename] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimetype] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:data];
            [httpBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        }
    
        [httpBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
        return httpBody;
    }
    
  • 这是上面用于构建请求主体的方法:

    NSString *boundary = [self generateBoundaryString];
    
    // configure the request
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    
    // set content type
    
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField: @"Content-Type"];
    
    // create body
    
    NSData *httpBody = [self createBodyWithBoundary:boundary parameters:params paths:@[path] fieldName:fieldName];
    
    - (NSData *)createBodyWithBoundary:(NSString *)boundary
                            parameters:(NSDictionary *)parameters
                                 paths:(NSArray *)paths
                             fieldName:(NSString *)fieldName {
        NSMutableData *httpBody = [NSMutableData data];
    
        // add params (all params are strings)
    
        [parameters enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) {
            [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8StringEncoding]];
        }];
    
        // add image data
    
        for (NSString *path in paths) {
            NSString *filename  = [path lastPathComponent];
            NSData   *data      = [NSData dataWithContentsOfFile:path];
            NSString *mimetype  = [self mimeTypeForPath:path];
    
            [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, filename] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimetype] dataUsingEncoding:NSUTF8StringEncoding]];
            [httpBody appendData:data];
            [httpBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        }
    
        [httpBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
        return httpBody;
    }
    
  • 以上使用以下实用方法:

    @import MobileCoreServices;    // only needed in iOS
    
    - (NSString *)mimeTypeForPath:(NSString *)path {
        // get a mime type for an extension using MobileCoreServices.framework
    
        CFStringRef extension = (__bridge CFStringRef)[path pathExtension];
        CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL);
        assert(UTI != NULL);
    
        NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType));
        assert(mimetype != NULL);
    
        CFRelease(UTI);
    
        return mimetype;
    }
    
    - (NSString *)generateBoundaryString {
        return [NSString stringWithFormat:@"Boundary-%@", [[NSUUID UUID] UUIDString]];
    }
    
  • 然后提交请求。这里有很多很多选择

    例如,如果使用
    NSURLSession
    ,则可以创建
    NSURLSessionUploadTask

    NSURLSession *session = [NSURLSession sharedSession];  // use sharedSession or create your own
    
    NSURLSessionTask *task = [session uploadTaskWithRequest:request fromData:httpBody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error = %@", error);
            return;
        }
    
        NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"result = %@", result);
    }];
    [task resume];
    
    request.HTTPBody = httpBody;
    
    NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error = %@", error);
            return;
        }
    
        NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"result = %@", result);
    }];
    [task resume];
    
    或者您可以创建一个
    NSURLSessionDataTask

    NSURLSession *session = [NSURLSession sharedSession];  // use sharedSession or create your own
    
    NSURLSessionTask *task = [session uploadTaskWithRequest:request fromData:httpBody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error = %@", error);
            return;
        }
    
        NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"result = %@", result);
    }];
    [task resume];
    
    request.HTTPBody = httpBody;
    
    NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error = %@", error);
            return;
        }
    
        NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"result = %@", result);
    }];
    [task resume];
    
    以上假设服务器只是返回文本响应。最好是服务器返回JSON,在这种情况下,您应该使用
    NSJSONSerialization
    而不是
    NSString
    方法
    initWithData

    同样,我正在使用上面的
    NSURLSession
    的完成块格式副本,但也可以使用更丰富的基于代理的格式副本。但这似乎超出了这个问题的范围,所以我将把这个问题留给你们

  • 但希望这能说明这个想法


    如果我没有指出,你可以使用比上面简单得多的方法,重复上面的步骤1和步骤2,然后只调用:

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // only needed if the server is not returning JSON; if web service returns JSON, remove this line
    NSURLSessionTask *task = [manager POST:urlString parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        NSError *error;
        if (![formData appendPartWithFileURL:[NSURL fileURLWithPath:path] name:@"avatar" fileName:[path lastPathComponent] mimeType:@"image/png" error:&error]) {
            NSLog(@"error appending part: %@", error);
        }
    }  progress:nil success:^(NSURLSessionTask *task, id responseObject) {
        NSLog(@"responseObject = %@", responseObject);
    } failure:^(NSURLSessionTask *task, NSError *error) {
        NSLog(@"error = %@", error);
    }];
    
    if (!task) {
        NSLog(@"Creation of task failed.");
    }
    
    AFHTTPSessionManager*manager=[AFHTTPSessionManager-manager];
    manager.responseSerializer=[AFHTTPResponseSerializer序列化程序];//仅当服务器未返回JSON时才需要;如果web服务返回JSON,请删除此行
    NSURLSessionTask*task=[manager POST:urlString参数:params constructingBodyWithBlock:^(id formData){
    n错误*错误;
    if(![formData appendPartWithFileURL:[NSURL fileURLWithPath:path]名称:@“avatar”文件名:[path lastPathComponent]mimeType:@“image/png”错误:&错误]){
    NSLog(@“错误附加部分:%@”,错误);
    }
    }进度:无成功:^(NSURLSessionTask*任务,id响应对象){
    NSLog(@“responseObject=%@”,responseObject);
    }失败:^(NSURLSessionTask*任务,NSError*错误){
    NSLog(@“error=%@”,error);
    }];
    如果(!任务){
    NSLog(@“任务创建失败”);
    }
    
    尝试将其用于具有不同mime类型的视频和图像数据

    NSDictionary *param;
    
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    
    // 1. Create `AFHTTPRequestSerializer` which will create your request.
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    NSMutableURLRequest *request;
    
    NSData *fileData;
    if ([objDoc.url containsString:@".mp4"]) {
        manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"application/json"];
        [serializer setValue:@"video/mp4" forHTTPHeaderField:@"Content-Type"];
        manager.requestSerializer = serializer;
    }
    
    // 2. Create an `NSMutableURLRequest`.
    
    NSLog(@"filename =%@",objDoc.url);
    request= [serializer multipartFormRequestWithMethod:@"POST" URLString:strUrl parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    
        if ([objDoc.url containsString:@".mp4"]) {
            [formData appendPartWithFileData:fileData
                                        name:@"File"
                                    fileName:@"video.mp4"
                                    mimeType:@"video/mp4"];
    
        }else{
            [formData appendPartWithFileData:fileData
                                        name:@"File"
                                    fileName:@"image.jpeg"
                                    mimeType:@"image/jpeg"];
        }
    
    } error:nil];
    
    // 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created.
    
    self.objeDocument.isUploading = [NSNumber numberWithInt:1];
    
    self.operation = [manager HTTPRequestOperationWithRequest:request
                                                      success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
                                                          NSLog(@"Success %@", responseObject);
                                                      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                                          UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error!" message:@"The document attached has failed to upload." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                                                          [alert show];
                                                          [self.operation cancel];
                                                          NSLog(@"Failure %@", error.description);
                                                      }];
    
    
    // 4. Set the progress block of the operation.
    [self.operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
                                             long long totalBytesWritten,
                                             long long totalBytesExpectedToWrite) {
        NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
        float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
    
    
    }];
    
    // 5. Begin!
    [self.operation start];
    
    NSDictionary*param;
    AFHTTPRequestOperationManager*manager=[AFHTTPRequestOperationManager];
    // 1. 创建“AFHTTPRequestSerializer”,它将创建您的请求。
    AFHTTPRequestSerializer*serializer=[AFHTTPRequestSerializer];
    NSMutableURLRequest*请求;
    NSData*文件数据;
    if([objDoc.url包含字符串:@“.mp4”]){
    manager.responseSerializer.acceptableContentTypes=[manager.responseSerializer.acceptableContentTypes setByAddingObject:@“应用程序/json”];
    [序列化程序设置值:@“视频/mp4”用于HttpHeaderField:@“内容类型”];
    manager.requestSerializer=序列化程序;
    }
    // 2. 创建一个“NSMutableURLRequest”。
    NSLog(@“filename=%@”,objDoc.url);
    request=[serializer multipartFormRequestWithMethod:@“POST”URLString:strUrl参数:param constructingBodyWithBlock:^(id formData){
    if([objDoc.url包含字符串:@“.mp4”]){
    [formData appendPartWithFileData:fileData
    名称:@“文件”
    文件名:@“video.mp4”
    mimeType:@“视频/mp4”];
    }否则{
    [formData appendPartWithFileData:fileData
    名称:@“文件”
    文件名:@“image.jpeg”
    mimeType:@“image/jpeg”];
    }
    }错误:无];
    // 3. 创建并使用“AFHTTPRequestOperationManager”从我们刚刚创建的“NSMutableURLRequest”创建“AFHTTPRequestOperation”。
    self.objeDocument.isUploading=[NSNumber numberwhithint:1];
    self.operation=[manager HTTPRequestOperationWithRequest:request
    成功:^(AFHTTPRequestOperation*操作,id响应对象){
    NSLog(@“成功%@”,响应对象);
    }失败:^(AFHTTPRequestOperation*操作,NSError*错误){
    UIAlertView*alert=[[UIAlertView alloc]initWithTitle:@“错误!”消息:@“所附文档未能上载”。委托:nil cancelButtonTitle:@“确定”其他ButtonTitles:nil,nil];
    [警报显示];
    [自行操作取消];
    NSLog(@“故障%@”,错误描述);
    }];
    // 4. 设置操作的进度块。
    [self.operation setUploadProgressBlock:^(NSUInteger\uu未使用的字节写入,
    写了很长很长的TotalBytes,
    long long totalBytesExpectedToWrite){
    NSLog(@“写入%lld/%lld”、TotalBytesWrite、totalBytesExpectedToWrite);
    浮动进度=(浮动)TotalBytesWrite/(浮动)totalBytesExpectedToWrite;
    }];
    // 5. 开始!
    [自操作启动];
    
    使用Objective-C的多部分或表单数据发布多个图像

    -(void)multipleimageandstring
    {
        NSString *urlString=@"URL NAME";
    
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
        [request setURL:[NSURL URLWithString:urlString]];
        [request setHTTPMethod:@"POST"];
    
        NSMutableData *body = [NSMutableData data];
    
        NSString *boundary = @"---------------------------14737809831466499882746641449";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
        [request addValue:contentType forHTTPHeaderField:@"Content-Type"];
    
        // file
        float low_bound = 0;
        float high_bound =5000;
        float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound);//image1
        int intRndValue = (int)(rndValue + 0.5);
       NSString *str_image1 = [@(intRndValue) stringValue];
    
        UIImage *chosenImage1=[UIImage imageNamed:@"Purchase_GUI_curves-12 copy.png"];
    
        NSData *imageData = UIImageJPEGRepresentation(chosenImage1, 90);
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"files\"; filename=\"%@.png\"\r\n",str_image1] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[NSData dataWithData:imageData]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    
    
    
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"name\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Nilesh" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"apipassword\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithString:app.password] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"adminId\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithString:app.adminId] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
        // close form
        [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        // set request body
        [request setHTTPBody:body];
    
        //return and test
        NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
        NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    
        NSLog(@"%@", returnString);
    
    }
    

    我为此挣扎了一段时间,如果您想上传多个图像或任何其他文件类型,可以使用
    AFNetworking 3.0

    NSDictionary *params = @{key        : value,
                                ..... etc
                             };
    
     NSString *urlString = @"http://..... your endpoint url";
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // only needed if the server is not returning JSON;  
    
    NSURLSessionTask *task = [manager POST:urlString parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        for (int x = 0 ; x< contentArray.count; x++) {
            AttachmentsModel *model = contentArray[x];
    
            if(model.type == ImageAttachmentType){
                [formData appendPartWithFileData:model.data name:model.name fileName:model.fileName mimeType:model.mimeType];
    
            }else if(model.type == AudioAttachmentType){
                NSURL *urlVideoFile = [NSURL fileURLWithPath:model.path];
                [formData appendPartWithFileURL:urlVideoFile name:model.name fileName:model.fileName mimeType:model.mimeType error:nil];
            }else{
                [formData appendPartWithFileURL:model.url name:model.name fileName:model.fileName mimeType:model.mimeType error:nil];
    
            }
    
        }
    }  progress:nil success:^(NSURLSessionTask *task, id responseObject) {
        [Utility stopLoading];
    
         NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSLog(@"result = %@", result);
    
        id json = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
    
    
        if (block) {
    
            //your response comes here
        }
    
    } failure:^(NSURLSessionTask *task, NSError *error) {
        NSLog(@"error = %@", error);
    
    }];
    
    if (!task) {
        NSLog(@"Creation of task failed.");
    }
    

    请注意,还可以使用nsuid:
    NSString*绑定生成UUID