【问题标题】:Uploading image to server Detail Explanation for Beginner上传图片到服务器 初学者详细说明
【发布时间】:2016-12-02 12:56:56
【问题描述】:

我正在努力从过去两天将图像上传到服务器,因为关于通过 AFNetworking 和 NSURLSession 上传图像以及其他上传图像的方法有很多问题我要问的是我没有找到一个答案解释了关于事物如何工作以及引擎盖下发生了什么的整个概念我



    //Init the NSURLSession with a configuration
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];

//Create an URLRequest
NSURL *url = [NSURL URLWithString:@"yourURL"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

//Create POST Params and add it to HTTPBody
NSString *params = @"api_key=APIKEY&email=example@example.com&password=password";
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

//Create task
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    //Handle your response here
}];

[dataTask resume];


用户XJones 也是关于这个话题最受欢迎的回答是:-

Here's code from my app to post an image to our web server:

// 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:@""]; 

// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];                                    
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];

// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BoundaryConstant];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];

// post body
NSMutableData *body = [NSMutableData data];

// add params (all params are strings)
for (NSString *param in _params) {
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}

// add image data
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0);
if (imageData) {
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imageData];
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}

[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];

// setting the body of the post to the reqeust
[request setHTTPBody:body];

// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

// set URL
[request setURL:requestURL];


但我的意思是我自己学习,如果没有解释,初学者很难理解,所以我所要求的只是解释,如果有人难以理解,请详细解释整个过程花在这个问题上,因为信不信由你,我发现这是迄今为止最难的话题,因为主要原因是没有关于整个过程的教程,而且如果有人现在可以迈出一步并解释它的概念,对初学者也没有任何解释'对明天要学习的学生来说会更容易。因此,任何可以详细解释这一点以及上传过程的工作原理以及一些参考步骤的人将不胜感激。

注意:假设我有一个 API 和一个密钥“图像”。

【问题讨论】:

    标签: ios objective-c xcode networking nsurlsession


    【解决方案1】:

    这里我们将看看图片上传以及一些**参数,因为大多数时候我们上传图片以及一些参数,例如userId。

    • 在深入我们的主题之前,让我提供代码source,我们将在下面看到的所有细节都来自其他一些堆栈溢出线程和一些来自其他站点,我将提供所有链接你的参考。

      -(void)callApiWithParameters:(NSDictionary *)inputParameter images:(NSArray *)image  imageParamters:(NSArray *)FileParamConstant{
      
      //1
         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
      
         [request setHTTPShouldHandleCookies:NO];
         [request setTimeoutInterval:30];
         [request setHTTPMethod:@"POST"];
      
      //2
         NSString *boundary = @"------CLABoundaryGOKUL";
      
      //3
         NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
         [request setValue:contentType forHTTPHeaderField: @"Content-Type"];
      
      //4
         NSMutableData *body = [NSMutableData data];
      
         for (NSString *key in inputParameter) {
      
         [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
         [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
         [body appendData:[[NSString stringWithFormat:@"%@\r\n", [inputParameter objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
        }
      
         for (int i = 0; i < image.count; i++) {
      
            NSData *imageDatasss = UIImagePNGRepresentation(image[i]);
      
            if (imageDatasss)
            {
                [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", FileParamConstant[i]] dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[@"Content-Type:image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:imageDatasss];
                [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
           }
        }
      
        [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
      
      //5
        [request setHTTPBody:body];
      
      //6
        [request setURL:[NSURL URLWithString:@"http://changeThisWithYourbaseURL?"]];//Eg:@"http://dev1.com/PTA_dev/webservice/webservice.php?"
      
      //7
        [NSURLConnection sendAsynchronousRequest:request
                                     queue:[NSOperationQueue mainQueue]
                         completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
      
                             NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
      
                             //8
                             if ([httpResponse statusCode] == 200) {
                                 NSDictionary * APIResult =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
                                 NSLog(@"Response of %@: %@",[inputParameter valueForKey:@"service"],APIResult);
      
                             }else{
                                 //9
                                 NSLog(@"%@",error.localizedDescription);
                             }
                         }];
      
      
       }
      

      注意:因为这是一个广泛的主题,我提供了详细信息的文档链接。

      1. 我们使用 ** NSMutableURLRequest** 而不是 ** NSURLRequest** 因为我们将向其附加一些数据。如果您需要对可变 url 请求进行更深入的说明,请查看documentation
        • setHTTPShouldHandleCookies 在这里我们必须决定我们是否要使用cookies。要了解更多关于visit
        • setTimeoutInterval 这有助于为 url 请求设置时间限制。在给定时间后添加时间间隔(以秒为单位),请求将被终止。
        • setHTTPMethodmany 方法。但是我们在很多情况下使用 GETPOST 方法。POST 和 GET 之间的区别是 herehere
      2. 边界有助于将参数彼此分开,以便服务器可以识别它们。边界可以是任何你想要的东西,可以随意编辑。
      3. 这里我们使用multipart/form-data;边界= 作为内容类型。要了解我们为什么要使用这种内容类型,请查看this 线程。
      4. NSMutableData * body 我们会将所有参数和值附加到此数据,然后将 setHTTPBody 附加到 UrlRequest

        • 如果这就是我们调用“callApiWithParameters”方法的方式

           - (IBAction)Done:(id)sender{
                  NSDictionary * inputParameters = [NSDictionary dictionaryWithObjectsAndKeys:
                                @"1",@"user_id" ,
                                "XXX",@"name" ,
                                nil];
                   NSArray * image = [NSArray arrayWithObjects:[UIImage imageNamed:@"Test"],[UIImage imageNamed:@"Test1"],nil];
                   NSArray * imageParameters = [NSArray arrayWithObjects:@"img_one",@"img_two",nil];
                   [self callApiWithParameters:inputParameters images:image imageParamters:imageParameters];
            }
          
        • 那么数据(即正文)将如下所示

    Content-Type=multipart/form-data; boundary=------CLABoundaryGOKUL
    
    --------CLABoundaryGOKUL
    Content-Disposition: form-data; name=user_id
    
    1
    --------CLABoundaryGOKUL
    Content-Disposition: form-data; name=name
    
    XXX
    --------CLABoundaryGOKUL
    Content-Disposition: form-data; name=img_one; filename=image.jpg
    
    Content-Type:image/jpeg
    
    //First image data appended here
    
    --------CLABoundaryGOKUL
    Content-Disposition: form-data; name=img_two; filename=image.jpg
    
    Content-Type:image/jpeg
    
    //Second image data appended here.
    
    • 以上给出的数据将清楚地解释发生了什么,所有参数和键都已附加在数据Here中,您可以找到有关发送多部分/表单的更多详细信息。

      1. 现在只需将以上数据添加到[request setHTTPBody:body];的请求中
      2. setURL 在此方法中添加您应用的基本 url。
      3. 现在我们需要做的就是与服务器建立连接并发送请求。这里我们使用 NSURLConnection 发送请求。关于 NSURLConnection 的说明 为 URL 请求加载数据并执行处理程序当请求完成或失败时阻塞操作队列。
      4. statusCode 有助于了解我们是否从服务器获得了成功的响应。如果 200 表示正常,500 表示内部服务器错误等。更多详细信息here

      5. 在其他情况下处理错误。

    仅供参考我已经解释了我能做什么,请参考链接以获得更好的理解。

    编辑:

    只需更改 imageParamater 数组中的名称,为满足您的要求,将 img_one & img_two 更改为 image

     - (IBAction)Done:(id)sender{
         //Change input parameters as per your requirement.
         NSDictionary * inputParameters = [NSDictionary dictionaryWithObjectsAndKeys:
                                      @"1",@"user_id" ,
                                      "XXX",@"name" ,
                                      nil];
        NSArray * image = [NSArray arrayWithObjects:[UIImage imageNamed:@"Test"],nil]; //Change Test with your image name
        NSArray * imageParameters = [NSArray arrayWithObjects:@"image",nil];//Added image as a key.
        [self callApiWithParameters:inputParameters images:image imageParamters:imageParameters];
                  }
    

    并使用您的示例基本 URL 更改点 6,

    //6

     [request setURL:[NSURL URLWithString:@"http://google.com/files/upload.php?"]];
    

    【讨论】:

    • 太好了,这就是我要找的东西,感谢你的努力兄弟。
    • 嘿,我认为我有一个密钥“图像”和一个 Api,例如“google.com/files/upload.php”,我需要在这个问题中进行哪些必要的更改才能获得回复?如果您根据我给出的要求上传不同的答案,那将非常有帮助,在此先感谢。
    • 您需要将图像上传到 API google.com/files/upload.php 并使用密钥 image 对..?
    • 检查编辑后的答案可能满足您的要求。
    【解决方案2】:

    我认为它对你有帮助...

    - (void)sendImageToServer
    {
        UIImage *yourImage= [UIImage imageNamed:@"image.png"];
        NSData *imageData = UIImagePNGRepresentation(yourImage);
        NSString *base64 = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
        NSString *strImage = [NSString stringWithFormat:@"data:image/png;base64,%@",base64];
    
        NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithObjectsAndKeys:strImage,@"image", nil];
        NSError * err;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&err];
        NSString *UserProfileInRequest = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        NSData *data=[UserProfileInRequest dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
        NSString *len = [NSString stringWithFormat:@"%ld", (unsigned long)[data length]];
    
        // Init the URLRequest
    
        NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
        [req setURL:[NSURL URLWithString:@"http://YOUR_URL"]];
        [req setHTTPMethod:@"POST"];
        [req setValue:len forHTTPHeaderField:@"Content-Type"];
        [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        [req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        [req setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [req setHTTPBody:data];
    
        NSURLSession *session = [NSURLSession sharedSession];
        [[session dataTaskWithRequest:req completionHandler:^(NSData *dt, NSURLResponse *response, NSError *err){
            //Response Data
            NSMutableDictionary *dic = [NSJSONSerialization JSONObjectWithData:dt options:kNilOptions error:&err];
            NSLog(@"%@", [dic description]);
    
        }]resume];
    }
    

    【讨论】:

    • 嘿@Ravi 我感谢你的时间,但问题是我已经有很多解决方案但没有解释我想知道整个过程,比如首先我们将图像转换为 nsdata,而不是发出 url 请求然后更进一步,这些额外的字段是什么,例如设置值、标题等。并且 NSURLConnection 也被 NSURLSession 弃用
    • 好吧..我会在明天编辑我的答案然后你可以检查我的答案。
    • 那太好了:)
    • 你能逐行解释这个过程吗?
    • 它也显示错误:- Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=无值。}
    【解决方案3】:

    使用 AFNetworking 来完成这项任务,这将提供非常简单可靠的解决方案。

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      相关资源
      最近更新 更多