AFNetworking 2.0 track file upload progress

后端 未结 2 1476
生来不讨喜
生来不讨喜 2020-12-07 14:49

I am relatively new to AFNetworking 2.0. Using the code snippet below, I\'ve been able to successfully upload a photo to my url. I would like to track the incremental uploa

相关标签:
2条回答
  • 2020-12-07 15:34

    The interface of AFHTTPSession doesn't provide a method to set a progress block. Instead, you'll have to do the following:

    // 1. Create `AFHTTPRequestSerializer` which will create your request.
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    
    // 2. Create an `NSMutableURLRequest`.
    NSMutableURLRequest *request =
        [serializer multipartFormRequestWithMethod:@"POST" URLString:@"http://www.myurl.com"
                                        parameters:dataToPost
                         constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                           [formData appendPartWithFileData:imageData
                                                       name:@"attachment"
                                                   fileName:@"myimage.jpg"
                                                   mimeType:@"image/jpeg"];
                         }];
    
    // 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created.
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    AFHTTPRequestOperation *operation =
        [manager HTTPRequestOperationWithRequest:request
                                         success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                           NSLog(@"Success %@", responseObject);
                                         } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                           NSLog(@"Failure %@", error.description);
                                         }];
    
    // 4. Set the progress block of the operation.
    [operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
                                        long long totalBytesWritten,
                                        long long totalBytesExpectedToWrite) {
      NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
    }];
    
    // 5. Begin!
    [operation start];
    

    In addition, you don't have to read the image via UIImage and then compress it again using JPEG to get an NSData. Just use +[NSData dataWithContentsOfFile:] to read the file directly from your bundle.

    0 讨论(0)
  • 2020-12-07 15:46

    It's true the interface of AFHTTPSessionManager doesn't provide a method to track the upload progress. But the AFURLSessionManager does.

    As a inherited class of AFURLSessionManager AFHTTPSessionManager can track upload progress like this:

    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer]  multipartFormRequestWithMethod:@"POST" URLString:kUploadImageURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData:UIImageJPEGRepresentation(image, 0.5) name:@"uploadFile" fileName:@"image" mimeType:@"image/jpeg"];
    } error:nil];
    
    NSProgress *progress;
    NSURLSessionDataTask *uploadTask = [[AFHTTPSessionManager sharedManager] uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (!error) {
            //handle upload success
        } else {
            //handle upload failure
        }
    }];
    [uploadTask resume];
    [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:NULL];
    

    outside

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
            NSProgress *progress = (NSProgress *)object;
            //progress.fractionCompleted tells you the percent in CGFloat
        }
    }
    

    Here is method 2(updated)

    use KVO to track progress means self need to be alive during observation. The more elegant way is AFURLSessionManager's method setTaskDidSendBodyDataBlock, like this:

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager setTaskDidSendBodyDataBlock:^(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        //during the progress
    }];
    
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer]  multipartFormRequestWithMethod:@"POST" URLString:kUploadImageURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData:UIImageJPEGRepresentation(image, 0.5) name:@"uploadFile" fileName:@"image" mimeType:@"image/jpeg"];
    } error:nil];
    
    NSURLSessionDataTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (!error) {
            //handle upload success
        } else {
            //handle upload failure
        }
    }];
    [uploadTask resume];
    
    0 讨论(0)
提交回复
热议问题