1

I am using sendAsynchronousRequest:queue:completionHandler: upload a file (I have ripped out some old third party library in favor of a direct call with this native method. I have left the NSURLRequest and dictionary as is.). I cannot figure out how to tell how it is finished pushing the file. I would think that in the completionHandler that would be called periodically and that we could inspect the params passed in, but they don't seem to contain what I need.

- (void)sendToServer:(NSString*)url asset:(MYAsset *)asset path:(NSString *)file completion:(MYUploaderBoolBlock)completion{
    NSDictionary *uploadParameters = asset.s3Info;
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:uploadParameters[@"my_url"]]];
    request.HTTPMethod = @"PUT";
    request.timeoutInterval = 300;
    [request addValue:uploadParameters[@"date"] forHTTPHeaderField:@"Date"];
    [request addValue:uploadParameters[@"authorization"] forHTTPHeaderField:@"Authorization"];
    [request addValue:uploadParameters[@"content_type"] forHTTPHeaderField:@"Content-Type"];
    [request addValue:asset.md5 forHTTPHeaderField:@"Content-MD5"];
    [request addValue:@"public-read" forHTTPHeaderField:@"x-amz-acl"];
    [request addValue:[@(asset.sizeInKB) stringValue] forHTTPHeaderField:@"Content-Length"];
    request.HTTPBodyStream = [NSInputStream inputStreamWithFileAtPath:file];

    DDLogInfo(@"Uploading %@ to server", uploadParameters[@"my_url"]);
    DDLogInfo(@"HTTP Headers: %@", [request allHTTPHeaderFields]);

    [NSURLConnection sendAsynchronousRequest:request
                                       queue:self.queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
                               if ([data length] > 0 && error == nil){
                                   // I am expecting that this can be used to detect progress of the file upload
                                   // as well as completion?
                                   NSLog(@"received data %d/%d =%f%", data.length, response.expectedContentLength, data.length/(float)response.expectedContentLength);
                                   if(data.length == response.expectedContentLength){
// This never fires because expectedContentLength is always -1
                                       completion(YES);
                                   }
                               }
                               else if ([data length] == 0 && error == nil){
                                   NSLog(@"reply empty");
                               }
                               else if (error != nil && error.code == -1001){
                                   NSLog(@"timed out");
                               }
                               else if (error != nil){
                                   NSLog(@"Error %@", error.localizedDescription);
                                   completion(NO);
                               }
                           }];

}
Dan Shelly
  • 5,991
  • 2
  • 22
  • 26
VaporwareWolf
  • 10,143
  • 10
  • 54
  • 80
  • I've sure been happy using the [AFNetworking](https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m) stuff. – HalR Apr 27 '13 at 21:13

2 Answers2

3

According to the documentation, the completion handler block is called once at the end of the asynchronous send.
if error is nil, the operation succeeded (not sure why you test the data length).

Dan Shelly
  • 5,991
  • 2
  • 22
  • 26
  • Ah, my mistake. I overlooked where it says "queue when the request completes or fails.". Thank you for catching that. How does one monitor progress of an upload since the delegate methods that provide this functionality are fully deprecated around iOS 4.3? It do not see any methods in this class that provide that functionality. – VaporwareWolf Apr 26 '13 at 21:48
  • After another look at the documentation (for OSX) it looks like they kept those delegates around in OSX, but not in iOS. Documentation here: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/Reference/Reference.html – VaporwareWolf Apr 26 '13 at 21:50
  • Ah, I see that there is a different class to use. This looks like what I am searching for. http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDownloadDelegate_Protocol/NSURLConnectionDownloadDelegate/NSURLConnectionDownloadDelegate.html – VaporwareWolf Apr 26 '13 at 21:54
  • You would also like to test if the `statusCode` of the `response` is 200. – Léo Natan Apr 27 '13 at 12:32
0
Gabrail
  • 216
  • 2
  • 16
  • I am using NSURLConnection. The delegate methods you are talking about are not included after iOS 4.3. There are some other methods still around but they do not provide the functionality required. ASIHTTPRequest is no longer in active development or supported. The code I'm modifying was actually already using GTM fetcher, but I was looking to remove that library if it can just use native code. – VaporwareWolf Apr 27 '13 at 21:43