0

我需要将图像上传到我的 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];
4

1 回答 1

1

几个反应:

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

    NSURLSession *session = [NSURLSession sharedSession];
    

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

    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. 我不知道你为什么NSData要从UIImage. 如果这是UIImage您动态创建的(例如屏幕快照),那么很好,这就是您必须做的。但是,如果您可以返回到原始资产(例如,来自 的原始资产ALAssetLibrary、我们在imageWithContentsOfFileorimageWithContentsOfURL中使用的文件等),通常效率会更高(无论是较小的资产还是您可以直接从持久存储上传)。

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

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

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

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

于 2014-03-09T05:48:32.013 回答