web-dev-qa-db-ja.com

AFNetworking 2.0トラックファイルのアップロードの進行状況

私はAFNetworking 2.0に比較的慣れていません。以下のコードスニペットを使用して、写真を自分のURLに正常にアップロードできました。増分アップロードの進行状況を追跡したいのですが、バージョン2.0でこれを行う例が見つかりません。私のアプリケーションはiOS 7なので、AFHTTPSessionManagerを選択しました。

誰でもこのスニペットを変更してアップロードの進行状況を追跡する方法の例を提供できますか?

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"myimage.jpg"], 1.0);

[manager POST:@"http://myurl.com" parameters:dataToPost constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileData:imageData name:@"attachment" fileName:@"myimage.jpg" mimeType:@"image/jpeg"];
} success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"Success %@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"Failure %@, %@", error, [task.response description]);
}];
27

AFHTTPSessionのインターフェイスは、進捗ブロックを設定するメソッドを提供していません。代わりに、次のことを行う必要があります。

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

さらに、UIImageを介して画像を読み取り、JPEGを使用して再度圧縮してNSDataを取得する必要はありません。 +[NSData dataWithContentsOfFile:]を使用して、バンドルからファイルを直接読み取ります。

55
StatusReport

確かに、AFHTTPSessionManagerのインターフェースは、アップロードの進行状況を追跡するメソッドを提供していません。 ButAFURLSessionManagerが行います。

AFURLSessionManagerの継承クラスとして、AFHTTPSessionManagerは次のようにアップロードの進行状況を追跡できます。

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

外側

- (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
    }
}

ここに方法2があります(更新されました)

進捗状況を追跡するためにKVOを使用すると、観測中にselfが生きている必要があります。よりエレガントな方法は、次のようなAFURLSessionManagerのメソッドsetTaskDidSendBodyDataBlockです。

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];
14
dopcn