ios Upload Image and Text using HTTP POST

后端 未结 10 1986
执笔经年
执笔经年 2020-11-22 08:27

Thanks for reading.

I am new to iOS and I am trying to upload an Image and a text using multi-part form encoding in iOS.

The curl

相关标签:
10条回答
  • 2020-11-22 08:48

    I can show you an example of uploading a .txt file to a server with NSMutableURLRequest and NSURLSessionUploadTask with help of a php script.

    -(void)uploadFileToServer : (NSString *) filePath
    {
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://YourURL.com/YourphpScript.php"]];
    [request setHTTPMethod:@"POST"]; 
    [request addValue:@"File Name" forHTTPHeaderField:@"FileName"];
    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject];
    
    NSURLSessionUploadTask* uploadTask = [defaultSession uploadTaskWithRequest:request fromFile:[NSURL URLWithString:filePath] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                          {
                                              NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                              if (error || [httpResponse statusCode]!=202)
                                              {
    
                                                  //Error
                                              }
                                              else
                                              {
                                                 //Success
                                              }
                                              [defaultSession invalidateAndCancel];
                                          }];
    [uploadTask resume];
    }
    

    php Script

    <?php 
    $request_body = @file_get_contents('php://input');
    foreach (getallheaders() as $name => $value) 
    {
        if ($FileName=="FileName") 
        {
            $header=$value;
            break;
        }
    }   
    $uploadedDir = "directory/";
    @mkdir($uploadedDir);
    file_put_contents($uploadedDir."/".$FileName.".txt",
    $request_body.PHP_EOL, FILE_APPEND);
    header('X-PHP-Response-Code: 202', true, 202);  
    ?>       
    
    0 讨论(0)
  • 2020-11-22 08:50

    here's the working swift code translated from the code provided by @xjones. Thanks alot for your help mate. Yours was the only way that worked for me. I used this method to send 1 image and a another parameter to a webservice made in asp.net


                        let params = NSMutableDictionary()
    
                        let boundaryConstant  = "----------V2y2HFg03eptjbaKO0j1"
    
                        let file1ParamConstant = "file1"
                        params.setObject(device_id!, forKey: "deviceID")
    
                        let requestUrl = NSURL(string: "\(siteurl):\(port)/FileUpload/Upload")
    
                        let request = NSMutableURLRequest()
    
                        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
                        request.HTTPShouldHandleCookies=false
                        request.timeoutInterval = 30
                        request.HTTPMethod = "POST"
    
                        let contentType = "multipart/form-data; boundary=\(boundaryConstant)"
    
                        request.setValue(contentType, forHTTPHeaderField: "Content-Type")
    
                        let body = NSMutableData()
    
                        // parameters
    
                        for param in params {
    
                        body.appendData("--\(boundaryConstant)\r\n" .dataUsingEncoding(NSUTF8StringEncoding)! )
                        body.appendData("Content-Disposition: form-data; name=\"\(param)\"\r\n\r\n" .dataUsingEncoding(NSUTF8StringEncoding)!)
                        body.appendData("\(param.value)\r\n" .dataUsingEncoding(NSUTF8StringEncoding)!)
    
                        }
                        // images
    
                        // image begin
                        body.appendData("--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    
                        body.appendData("Content-Disposition: form-data; name=\"\(file1ParamConstant)\"; filename=\"image.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
                        body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    
                        body.appendData(passportImageData)
                        body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    
                        // image end
    
    
    
                        body.appendData("--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    
                        request.HTTPBody  = body
                        let postLength = "\(body.length)"
                        request.setValue(postLength, forHTTPHeaderField: "Content-Length")
                        request.URL = requestUrl
    
                        var serverResponse = NSString()
    
                        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
                            data, response, error in
    
                            if error != nil
                            {
                                print("error=\(error)")
                                return
                            }
    
    
                            print("response = \(response)")
    
    
                            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                            print("responseString = \(responseString!)")
                            serverResponse = responseString!
    
    
                            }
    
                                task.resume()
    
    0 讨论(0)
  • 2020-11-22 08:56

    Here is a Swift version. Note that if you do not want to send form data it is still important to send the empty form boundary. Flask in particular expects form data followed by file data and will not populate request.files without the first boundary.

      let composedData = NSMutableData()
    
      // Set content type header
      let BoundaryConstant = "--------------------------3d74a90a3bfb8696"
      let contentType = "multipart/form-data; boundary=\(BoundaryConstant)"
      request.setValue(contentType, forHTTPHeaderField: "Content-Type")
    
      // Empty form boundary
      composedData.appendData("--\(BoundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    
      // Build multipart form to send image
      composedData.appendData("--\(BoundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      composedData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      composedData.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      composedData.appendData(rawData!)
      composedData.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      composedData.appendData("--\(BoundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    
      request.HTTPBody = composedData
    
      // Get content length
      let length = "\(composedData.length)"
      request.setValue(length, forHTTPHeaderField: "Content-Length")
    
    0 讨论(0)
  • 2020-11-22 09:01

    Use AFNetworking; Put other parameters in the parameter dictionary and append the image data in form data.

    //Upload Image Using AFNetworking
    
    -(BOOL)uploadImageAFNetworkingWithURL:(NSString *)path andImage:(UIImage *)image andImageNameWithExtension:(NSString *)strImageName andParamDict:(NSDictionary *)dictParam andKeyForUploadingImage:(NSString *)keyUplaodImg{
    
        NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
        NSString *strError = EMPTY_STRING;
    
        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
         manager.requestSerializer = [AFJSONRequestSerializer serializer];
        [manager POST:path parameters:dictParam constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    
            [formData appendPartWithFileData:imageData name:keyUplaodImg fileName:strImageName mimeType:@"image/jpeg"];
    
        } success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"success = %@", responseObject);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"error = %@", error);
            NSLog(@"Response = %@", operation);
            [strError stringByAppendingString:STR_ERR_MESSAGE];
        }];
        if(strError.length>0){
            return NO;
        }else{
            return YES;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:04

    XJones' answer worked like charm.

    But he didn't mentioned/declared variables _params, BoundaryConstant and requestURL. So, i thought of posting that part as an add-on to his post, so that it may help others in future.

    // Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept.
    NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
    [_params setObject:[NSString stringWithString:@"1.0"] forKey:[NSString stringWithString:@"ver"]];
    [_params setObject:[NSString stringWithString:@"en"] forKey:[NSString stringWithString:@"lan"]];
    [_params setObject:[NSString stringWithFormat:@"%d", userId] forKey:[NSString stringWithString:@"userId"]];
    [_params setObject:[NSString stringWithFormat:@"%@",title] forKey:[NSString stringWithString:@"title"]];
    
    // the boundary string : a random string, that will not repeat in post data, to separate post data fields.
    NSString *BoundaryConstant = [NSString stringWithString:@"----------V2ymHFg03ehbqgZCaKO6jy"];
    
    // string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ 
    NSString* FileParamConstant = [NSString stringWithString:@"file"];
    
    // the server url to which the image (or the media) is uploaded. Use your server url here
    NSURL* requestURL = [NSURL URLWithString:@""]; 
    

    As i mentioned earler, this is not an answer by itself, just an addon to XJones' post.

    0 讨论(0)
  • 2020-11-22 09:05
    use below code. it will work fine for me.
    
    +(void) sendHttpRequestWithArrayContent:(NSMutableArray *) array 
    ToUrl:(NSString *) strUrl withHttpMethod:(NSString *) strMethod 
    withBlock:(dictionary)block
    {
    if (![Utility isConnectionAvailableWithAlert:TRUE])
    {
        [Utility showAlertWithTitle:@"" andMessage:@"No internet connection available"];
    }
    
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
    
    [request setURL:[NSURL URLWithString:strUrl]];
    [request setTimeoutInterval:120.0];
    [request setHTTPMethod:strMethod];
    
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    
    NSMutableData *body=[[NSMutableData alloc]init];
    
    for (NSMutableDictionary *dict in array)
    {
        if ([[dict valueForKey:[[dict allKeys]objectAtIndex:0]] isKindOfClass:[NSString class]])
        {
            [body appendData:[self contentDataFormStringWithValue:[dict valueForKey:[[dict allKeys]objectAtIndex:0]] withKey:[[dict allKeys]objectAtIndex:0]]];
        }
        else if ([[dict valueForKey:[[dict allKeys]objectAtIndex:0]] isKindOfClass:[UIImage class]])
        {
            [body appendData:[self contentDataFormImage:[dict valueForKey:[[dict allKeys]objectAtIndex:0]] withKey:[[dict allKeys]objectAtIndex:0]]];
        }
        else if ([[dict valueForKey:[[dict allKeys]objectAtIndex:0]] isKindOfClass:[NSMutableDictionary class]])
        {
            [body appendData:[self contentDataFormStringWithValue:[dict valueForKey:[[dict allKeys]objectAtIndex:0]] withKey:[[dict allKeys]objectAtIndex:0]]];
        }
        else
        {
            NSMutableData *dataBody = [NSMutableData data];
            [dataBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [dataBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"ipodfile.jpg\"\r\n",@"image"] dataUsingEncoding:NSUTF8StringEncoding]];
            [dataBody appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
            [dataBody appendData:[dict valueForKey:[[dict allKeys]objectAtIndex:0]]];
    
            [body appendData:dataBody];
        }
    }
    
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    [request setHTTPBody:body];
    
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
     {
         if (!data) {
             NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
              [dict setObject:[NSString stringWithFormat:@"%@",SomethingWentWrong] forKey:@"error"];
             block(dict);
             return ;
         }
         NSError *error = nil;
        // NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
         NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
         NSLog(@"%@",dict);
         if (!dict) {
             NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
             [dict setObject:ServerResponceError forKey:@"error"];
             block(dict);
             return ;
         }
         block(dict);
    
     }];
    
    }
    +(NSMutableData*) contentDataFormStringWithValue:(NSString*)strValue 
    withKey:(NSString *) key
    {
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSMutableData *data=[[NSMutableData alloc]init];
    [data appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:[[NSString stringWithFormat:@"%@",strValue] dataUsingEncoding:NSUTF8StringEncoding]];  // title
    return data;
    }
    
    +(NSMutableData*) contentDataFormImage:(UIImage*)image withKey:
    (NSString *) key
    {
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSMutableData *body = [NSMutableData data];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"ipodfile.jpg\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    NSData *imageData=UIImageJPEGRepresentation(image, 0.40);
    [body appendData:imageData];
    
    return body;
    }
    
    0 讨论(0)
提交回复
热议问题