AFNetworking 1.x to 3.x migration - get download progress? - objective-c

I need to download image with progress bar. This is what I've got for in AFNetworking 1.x which is not working for AFNetworking 3.x.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.mediaItem.media_item_hd_url]];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFImageResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
UIImage *image = responseObject;
_image = image;
[self.delegate browserItem:self loaded:1.0 finished:YES];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];
[op setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
CGFloat progress = ((CGFloat)totalBytesRead)/((CGFloat)totalBytesExpectedToRead);
[self.delegate browserItem:self loaded:progress finished:NO];
}];
[[NSOperationQueue mainQueue] addOperation:op];
Finally this is what I could come up with, which is not complete. I have no idea how to use progress in code block.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.mediaItem.media_item_hd_url]];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(#"File downloaded to: %#", filePath);
// UIImage *image = response;
// _image = image;
[self.delegate browserItem:self loaded:1.0 finished:YES];
}];
[downloadTask resume];

You can get best framework RSNetworkKit which handles all the network call with an ease. It has internally implemented AFNetworking 3.0. It'll gives you download progress in single method either you upload, download.
It has also an enhanced method to show progress on UIImageView.
You can find it here. https://github.com/rushisangani/RSNetworkKit

Related

Get Api is not working properly

i am working on get api when hit the api in app i am not getting updated response when i remove the app from simulator and device its working fine.guys what i am doing wrong please help me.i have already tried Afnetworking simple Api nsurl session.
NSString *strURL = [NSString stringWithFormat:#"https://mysponsers.com/m/comments/publicpost/674"];
NSURL *url = [NSURL URLWithString:strURL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:url];
[httpClient getPath:strURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
id json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
NSLog(#"RESPONSE--->1%#",json);
} failure:^(AFHTTPRequestOperation* operation, NSError *error) {
//fail!
NSLog(#"Error String is %#", error.localizedDescription);
}];
Here is the code i am using afnetworkikng for hitting the api.
Thank You
You can try with latest version of AFNetworking library or you can simply use this code also.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://mysponsers.com/m/comments/publicpost/674"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(#"%#", httpResponse);
}
}];
[dataTask resume];
You can install or update AFNetworking via cocoapods by adding this (pod 'AFNetworking', '~> 3.1.0') in your pod file.
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
// Change your api content-type here:
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
manager.requestSerializer = requestSerializer;
[manager GET:#"{ Write your url here }"
parameters:nil
progress:nil
success:^(NSURLSessionDataTask *operation, id responseObject) {
NSString *response = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Success response: %#", response);
}
failure:^(NSURLSessionDataTask *operation, NSError *error) {
NSHTTPURLResponse *response = (NSHTTPURLResponse *)operation.response;
NSLog(#"Failure response: %#", response);
}];

How to download a file/Data after verifying the "Content_Type" from **decidePolicyForNavigationResponse** in WKWebview:

How to retrieve the actual file/Data after doing some check inside this decidePolicyForNavigationResponse delegate method:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
}
Any leads are welcomed...Thank you
I'm a beginner but if you want to download a file on a WKWebview, you need to use AFNetworking, the code looks like this :
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = WebView.URL;
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(#"File downloaded to: %#", filePath);
}];
[downloadTask resume];
Hope this helps you

AFNetworking background file upload

I want to upload files to my server from my app. The code below is working great when app is active. If I press home button or open another app uploading stops.
I activated background fetch but still not working.
Afnetworking has background support but I cant figure out how I implement this feature to my code.
NSString *str=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Archive.zip"];
NSDictionary *parameters = #{#"foo": #"bar"};
NSURL *filePath = [NSURL fileURLWithPath:str];
AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
NSData *imageData=[NSData dataWithContentsOfURL:filePath];
NSMutableURLRequest *request =
[serializer multipartFormRequestWithMethod:#"POST" URLString:#"http://url"
parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData
name:#"image"
fileName:#"Archive.zip"
mimeType:#"application/zip"];
}];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFHTTPRequestOperation *operation =
[manager HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure %#", error.description);
}];
[operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
long long totalBytesWritten,
long long totalBytesExpectedToWrite) {
NSLog(#"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
}];
[operation start];
Change this line
[operation start];
to this
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
// Handle iOS shutting you down (possibly make a note of where you
// stopped so you can resume later)
}];
[manager.operationQueue addOperation:operation];
You can look at these links
AFHTTPRequestOperation doesn't work after stand by mode
and Alternative for enqueueHTTPRequestOperation in AFNetworking 2.0

AFNetworking JSON Request, neither success nor error block called

I'm trying to learn AFNetworking so have written a simple block. I'm trying to retrieve & log the json from the site url below.
NSString *string =
#"http://transportapi.com/v3/uk/bus/stop/490012745J/live.json?api_key=6ee115459cbeccdb902b14d39b61330d&app_id=9deefeb1&group=route";
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *mydict = (NSDictionary *)responseObject;
NSString *key;
for(key in mydict){
NSLog(#" key %#", key);
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"ERROR");
}];
But neither the success or the failure block is being called. Can someone point out what I've done wrong?
You're not actually firing the operation you need to add
[[NSOperationQueue mainQueue] addOperation:operation];

AFNetworking upload progress sending SOAP NSData

I am using AFNetworking and would like to upload an NSData object to my server. I am trying to upload to our SOAP server, so I have XML that I have converted to an NSData object. For some reason, the follow does NOT work:
// Back to NSData
NSData *convertedFile = [xml dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:siteConfiguration.soapURL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFormData:convertedFile name:assetCreation.name];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
// Progress
float totalProgress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
progress(totalProgress, totalBytesWritten, totalBytesExpectedToWrite);
if (totalBytesExpectedToWrite == totalBytesWritten) {
completion();
}
}];
[operation start];
But when not using the multipartFormRequestWithMethod block, it DOES work and the file is correctly uploaded, but there is NO progress shown, as the callback is only called once:
// Back to NSData
NSData *convertedFile = [xml dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:siteConfiguration.soapURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod: #"POST"];
[request setHTTPBody:convertedFile];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
// Progress
float totalProgress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
progress(totalProgress, totalBytesWritten, totalBytesExpectedToWrite);
if (totalBytesExpectedToWrite == totalBytesWritten) {
MatrixAsset *asset = [[MatrixAsset alloc] init];
completion(asset);
}
}];
[operation start];
It seems that my server really wants to be sent the HTTPBody with my NSData object. Is it possible to do the same with the AFNetworking progress callback?
Ok, I got it working. Looks like I was going about it wrong:
// Setup the connection
NSString *wsdlURL = [NSString stringWithFormat:#"%#?WSDL", siteConfiguration.soapURL];
NSURL *serviceUrl = [NSURL URLWithString:wsdlURL];
NSMutableURLRequest *serviceRequest = [NSMutableURLRequest requestWithURL:serviceUrl];
[serviceRequest setValue:#"text/xml" forHTTPHeaderField:#"Content-type"];
[serviceRequest setHTTPMethod:#"POST"];
[serviceRequest setHTTPBody:[xml dataUsingEncoding:NSUTF8StringEncoding]];
// Operation
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:serviceRequest];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
// Progress
float totalProgress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
progress(totalProgress, totalBytesWritten, totalBytesExpectedToWrite);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
MatrixAsset *asset = [[MatrixAsset alloc] init];
completion(asset);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error.localizedDescription);
NSLog(#"error: %#", error.localizedFailureReason);
}];
[operation start];
You need SOAPAction to continue:
[serviceRequest setValue:#"SOAP_ACTION_URL" forHTTPHeaderField:#"SOAPAction"];