【问题标题】:How to upload to ASP.NET in Objective-C using NSURLSession如何使用 NSURLSession 在 Objective-C 中上传到 ASP.NET
【发布时间】:2014-04-12 06:17:32
【问题描述】:

我需要将图像上传到我的 ASP.Net 网站,我已经让它与 NSURLConnection 一起使用,但是当我需要上传非常大的文件时,由于缺少 ram 将文件传输到 NSData 然后上传而崩溃它。所以我发现了新的 API NSURLSession 和方法 uploadTaskWithRequest:withFile 以允许传输更大的文件。我已经更改了 ASP.NET 服务器上的最大文件限制以允许大文件,并对其进行了测试,它适用于大文件(100MB+),但有时手机没有足够的内存来分配文件的 NSData,当我使用 NSURLConnection 时。我已经多次尝试 NSURLSession 没有成功。

这是我尝试过的一个例子:

    NSString *urlString = [NSString stringWithFormat:@"https://examplesecuresite.com/Index.aspx?username=%@", username];
    NSMutableURLRequest *request =
    [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"PUT"];

    // 3
    NSData *noteContents = UIImageJPEGRepresentation(image, 1);

    // 4
    NSURLSession *session = [[NSURLSession alloc] init];
    NSURLSessionUploadTask *uploadTask = [session
                                          uploadTaskWithRequest:request
                                          fromData:noteContents];
    [uploadTask resume];

【问题讨论】:

  • 顺便说一句,围绕请求的性质存在一大堆可能的问题,根据迄今为止提供的内容,我们无法回答。如果您提供了有效的NSURLConnection 源的副本,这可能有助于我们确认在转换为NSURLSession 的过程中没有引入任何问题。

标签: objective-c nsurlsession nsurlsessiontask


【解决方案1】:

几个反应:

  1. 这不是您创建NSURLSession 的方式。您应该使用共享会话:

    NSURLSession *session = [NSURLSession sharedSession];
    

    或使用委托创建配置(显然,实现NSURLSessionTaskDelegateNSURLSessionDelegate 协议)并使用它:

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
                                                               fromData:noteContents];
    

    或者创建一个没有委托的配置(但创建带有完成块的上传任务)并使用它:

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:noteContents completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"%@", error);
            return;
        }
    
        // do whatever other checking you want of the response here
    }];
    
  2. 我不知道您为什么要从 UIImage 检索 NSData。如果这是您动态创建的UIImage(例如屏幕快照),那么很好,这就是您必须做的。但是如果你可以回到原始资产(例如来自ALAssetLibrary的原始资产,我们在imageWithContentsOfFileimageWithContentsOfURL中使用的文件等),通常会更有效(无论是较小的资产还是您可以直接从持久存储上传)。

    不幸的是,使用质量设置为1.0UIImageJPEGRepresentation 通常会检索到比原始资产大得多的NSData。 (此外,我们保留任何元数据,如果有的话,它的内存效率要高得多,等等。)您可以使用0.90.8 的因子,这是有损的,但会导致文件更小。如果你真的想要无损的东西,UIImagePNGRepresentation 通常会生成比UIImageJPEGRepresentation 更小的文件,质量设置为1.0

  3. 如果您担心内存效率高的方法,这似乎不再有效。您正在 RAM 中上传 NSData。任何将数据加载到 NSData 的方法都不会比其他方法更有效。

    如果您想提高内存效率,请完全避免将图像加载到 NSData 中(如果可以的话),只需将 uploadTaskWithRequest:fromFile: 与原始资源一起使用。

  4. 顺便说一句,如果您将图像保存在持久存储中的文件中,我不会觉得您必须转移到NSURLSession 只是为了解决内存问题。令我震惊的是,您可以使用基于委托的NSURLConnection,从connection:needNewBodyStream: 返回NSInputStream,而不是将图像加载到NSData

【讨论】:

  • 在我使用 NSURLConnection 上传之前,我在上传时有一个多部分文档,但在这种情况下,我只是上传原始文件,这当然会在我的asp.net 文件,有没有办法在使用uploadTaskWithRequest:fromFile: 时发送正文数据和文件,或者只是修复 asp.net 以接受原始文件?感谢您的帮助:)
  • @user3001058 如果您的服务器代码需要一个多部分文档,那么您必须发送一个多部分文档。如果您想更改它以接受原始文件,那么您必须更改两个服务器代码和客户端代码以接受和发送原始文件。我不确定,但在我看来,发送原始图像文件是有风险的,因为我不确定服务器如何知道它得到了一切。
  • @user3001058 如果您主要关心的是 RAM,我倾向于保持消息格式相同,但修复您的客户端代码以流式传输它,而不是将其暂存在 NSData 中。可以在NSURLConnectionNSURLSession 中完成(但我认为您需要使用完整的多部分文档/有效负载暂存您自己的文件,或者可能编写您自己的NSInputStream 子类来动态构建消息正文) .但是,如果您使用 UIImageJPEGRepresentation 加载图像,所有这些似乎都没有实际意义。
  • 我也在做视频,上传原始视频(500MB +)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
  • 2014-02-14
  • 2016-02-28
  • 1970-01-01
  • 2019-02-14
  • 2011-10-25
相关资源
最近更新 更多