草庐IT

ios - 将图像上传到服务器 初学者的详细说明

coder 2023-09-20 原文

我正在努力将过去两天的图像上传到服务器,因为有很多关于通过 AFNetworking 和 NSURLSession 上传图像的问题以及其他上传方法我想问的是我没有找到一个回答解释了关于事物如何工作以及幕后发生的事情的整个概念我搜索了 youtube 也所有的东西都在 Swift 中可用并且相信我根本没有任何解释从我的结果我发现这个答案看起来很熟悉我



    //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];


但我的意思是我是自学的,如果没有解释,初学者很难理解,所以我要的只是一个解释,一个关于整个过程的详细解释,如果有人很难理解的话花在这个问题上,因为不管你信不信,我发现这是迄今为止最难的话题,因为主要原因是没有关于整个过程的教程,如果有人现在可以一步一步解释它的概念,也没有对初学者的解释。明天要学习的学生会更容易。因此,如果有人能详细解释这一点以及上传过程的工作原理和一些引用步骤,我们将不胜感激。

Note : Consider I Have an API and a Key "image" .

最佳答案

这里我们将查看图片上传以及一些**参数,因为大多数时候我们上传图片时会附带一些参数,例如 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 在这里我们必须决定我们是否要使用cookie。了解更多关于visit
      • setTimeoutInterval 这有助于设置 url 请求的时间限制。在给定时间后添加以秒为单位的时间间隔,请求将被终止。
      • setHTTPMethodmany方法。但是我们在很多情况下使用GETPOST 方法。POST 和GET 之间的区别是herehere
    2. 边界有助于将参数彼此分开,以便服务器可以识别它们。边界可以是您希望随意编辑的任何内容。
    3. 这里我们使用multipart/form-data; boundary= 作为内容类型。要了解我们为什么要使用此内容类型,请查看 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. 将上述数据添加到请求中
    3. setURL 在此方法中添加您的应用程序的基本 url。
    4. 现在我们需要做的就是连接到服务器并发送请求。这里我们使用 NSURLConnection 发送请求。关于 NSURLConnection 的说明 加载 URL 请求的数据并执行处理程序当请求完成或失败时阻塞操作队列。
    5. statusCode 有助于确定我们是否从服务器获得成功响应。如果200 表示正常,500 表示内部服务器错误等。更多详细信息here .

    6. 处理 else 情况下的错误。

仅供引用我已经尽我所能解释了,请参阅链接以便更好地理解。

编辑:

只需更改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?"]];

关于ios - 将图像上传到服务器 初学者的详细说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38631178/

有关ios - 将图像上传到服务器 初学者的详细说明的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  4. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  5. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  6. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  7. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  8. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  9. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  10. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

随机推荐