Download from Google Drive using OAuth2 - iphone

I am trying to download from Google Drive using OAuth2, but I am unable to authenticate url.
I get the following error:
2013-08-21 21:22:39.569 LoudCloud[4790:c07] Authorization
successful... 2013-08-21 21:22:40.262 LoudCloud[4790:c07] Error: Error
Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in
(200-299), got 401" UserInfo=0x98b90f0
{AFNetworkingOperationFailingURLRequestErrorKey=https://doc-0k-bg-docs.googleusercontent.com/docs/securesc/6gj8c1544p7s7pniqjbc4mq6j0fb056i/8bj1nr5shkpsku5m0mde1rr8v7n975ll/1377108000000/00742820994415136760/00742820994415136760/0B0kZ8xc_ZGhbWnZOQUVuTGtObjA?h=16653014193614665626&e=download&gd=true>,
NSErrorFailingURLKey=https://doc-0k-bg-docs.googleusercontent.com/docs/securesc/6gj8c1544p7s7pniqjbc4mq6j0fb056i/8bj1nr5shkpsku5m0mde1rr8v7n975ll/1377108000000/00742820994415136760/00742820994415136760/0B0kZ8xc_ZGhbWnZOQUVuTGtObjA?h=16653014193614665626&e=download&gd=true,
NSLocalizedDescription=Expected status code in (200-299), got 401,
AFNetworkingOperationFailingURLResponseErrorKey=}
CODE:
GTMOAuth2Authentication *auth =
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
clientID:kClientID
clientSecret:kClientSecret];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[auth authorizeRequest:req completionHandler:^(NSError *error) {
if (error == nil) {
NSLog(#"Authorization successful...");
}
else {
NSLog(#"Authorization failed...");
}
}];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:req];
op.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[op setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float percentage = ((float)((int)totalBytesRead) / (float)((int)totalBytesExpectedToRead)) * 100.0;
NSLog(#"Download percentage: %f", percentage);
}];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[op start];

Related

Not able to parse response in JSON response

I am using AFNetworking 3, Xcode 7.2 for iOS 9.
AFURLSessionManager *ses = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
ses.responseSerializer = [AFJSONResponseSerializer serializer];
//Request
[[AFJSONRequestSerializer serializer] setValue:#"application/json" forHTTPHeaderField:#"Accept"];
NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:#"GET" URLString:endPoint parameters:parameters error:nil];
NSURLSessionDataTask *dataTask = [ses dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"%# %#", response, responseObject);
}
}];
[dataTask resume];
but I am getting error response as:
Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/plain"
The request content type is still set to "text/plain"
I am not sure what I am missing .
I used http response serializer itself and it worked fine.
AFURLSessionManager *ses = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
ses.responseSerializer = [AFHTTPResponseSerializer serializer];
NSMutableDictionary * innerJson = [NSJSONSerialization
JSONObjectWithData:responseObject options:kNilOptions error:&error1];

How to avoid delay of webservice(ASIHTTPRequest) response in iPhone?

In my iPhone app handling web service for storing and retrieving data.Now i am using the following code for web service handling.
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"1" forKey:#"id"];
[request setTag:100];
[request setDelegate:self];
[request startAsynchronous];
By this code i got response in 'requestFinished' method.My problem is web service response is very delay(depends upon internet speed).How to make response from web service very fast?Please help me.
I think you want to send json objects by post method..delay is depend on your server(how fast it handle request and response back) but i suggest you to use progress bar and blocks to handle network request..
loadingHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
loadingHUD.labelText = NSLocalizedString(#"Downloading", nil);
loadingHUD.mode=MBProgressHUDModeAnnularDeterminate;
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) lastObject];
// Add your filename to the directory to create your saved file location
NSString* destPath = [documentDirectory stringByAppendingPathComponent:[fileName stringByAppendingString:#".mov"]];
NSURL *url = [NSURL URLWithString:mainURL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST" path:postURL parameters:postRequest];
NSLog(#"postRequest: %#", postRequest);
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:destPath append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"Successfully downloaded file to %#",[[NSString alloc] initWithData:operation.responseData encoding:NSASCIIStringEncoding]);
// Give alert that downloading successful.
NSLog(#"Successfully downloaded file to %#", destPath);
NSLog(#"response: %#", operation.responseString); // Give alert that downloading successful.
// [self.target parserDidDownloadItem:destPath];
loadingHUD.detailsLabelText = [NSString stringWithFormat:#"%# %i%%",#"Downloading",100];
[loadingHUD hide:TRUE];
[DBHelper savePurchaseId:fileName];
[self movieReceived];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
// Give alert that downloading failed
NSLog(#"Error: %#", error);
// [self.target parserDidFailToDownloadItem:error];
[loadingHUD hide:TRUE];
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite)
{
// Progress
progress = ((float)totalBytesWritten) / fileSize;
loadingHUD.progress = progress;
}];
[operation start];
}
We cant control the internet speed due to the different network provider or environment when the client is using your app.
But you can put your web-services to run in background without effecting your main function.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//code for webservices calling
dispatch_async(dispatch_get_main_queue(), ^{
//functions after your webservices done, for example reload the table or hide the loading bar.
});
});

AFHTTPClient does not send complete data

I am sending a wav file using the following code, however, the process stops at
Sent 131072 of 141359 bytes
So? Is there some problem with the code? Or am i missing something?
NSString *vidURL = [[NSBundle mainBundle] pathForResource:#"M1F1-int24WE-AFsp" ofType:#"wav"];
NSData *videoData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:vidURL]];
NSURL *url = [NSURL URLWithString:#"http://apps2.mobiiworld.com"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
// NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:#"Romantic.jpg"], 0.5);
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"/staging/krafttesting/upload.php" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData:videoData name:#"file" fileName:#"recording.wav" mimeType:#"audio/vnd.wave"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(#"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
}];
// [httpClient enqueueHTTPRequestOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {NSLog(#"Success");}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
NSLog(#"error: %#", error.userInfo);
}];
[operation start];
I got the solution. It seems AFHTTPClient works only when ARC is on. I had ARC off, due to which it was not working - Though i had no errors received.

AFNetworking with AFJSONRequestOperation and filedata never completes

I'm using AFNetworking to post json data to my webservice and get a json response back. However now I also want to add multipart formdata to these POST's. If I do this (even without the parameters I added first) the completion block never fires. The progress block DOES fire and I can see that the file uploads correctly.
Does anybody have any experience posting images like this with AFNetworking? I am using the latest AFNetworking source / version.
This is my initial code for posting a dictionary with json in it. This works fine.
NSMutableDictionary *postdata = [[NSMutableDictionary alloc] init];
[postdata setObject:[postdictionary JSONString] forKey:#"request"];
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:#"POST"
path:path
parameters:postdata];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {// Success} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {// Failure }];
[operation start];
This is the version of the code for submitting an image (doesn't work)
NSMutableURLRequest *jsonRequest jsonRequest = [httpClient multipartFormRequestWithMethod:#"POST" path:path parameters:postdata constructingBodyWithBlock: ^(id <AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"photo" fileName:#"photo.jpg" mimeType:#"image/jpeg"];
[formData throttleBandwidthWithPacketSize:5000 delay:0.1];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:jsonRequest];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(#"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Upload succes");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Upload failed");
}];
[operation start];
I use this code on a number of apps and havent had any problems with it (note I am using the AFJSONRequestOperation and AFRestClient)
set the request
// I have a shared singleton in a separate file APIClient.h
AFRESTClient *httpClient = [APIClient sharedClient];
NSURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:method parameters:params constructingBodyWithBlock: ^(id <AFMultipartFormData> formData)
{[formData appendPartWithFileData:imageData
name:#"image"
fileName:#"image.png"
mimeType:#"image/png"];
}];
then the operation,
AFJSONRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:request];
my progress block
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(#"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
CGFloat progress = ((CGFloat)totalBytesWritten) / totalBytesExpectedToWrite * 100;
[SVProgressHUD showProgress:50 status:[NSString stringWithFormat:#"%0.1f %%", progress]];
}];
success block (my API returns a stat -ok or fail, then the data (same as flickr API)
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id response) {
NSLog(#"response string: %#", operation.responseString);
NSString *resultStat = [response objectForKey:#"stat"];
if ([resultStat isEqualToString:#"ok"]) {
//success
// do something with your data that is returned from the API
} else {
//error
NSLog(#"Data Error: %#", response);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
[httpClient enqueueHTTPRequestOperation:operation];
cannot see any issues with your code, few possibilities:
try setting short timeout interval and check if request completes
[request setTimeoutInterval:5];
also try commenting out the throttling line and see if it changes anything

How do I set the data for a "PUT" request with AFNetworking?

I have started to use AFNetworking and it works well when it gets to making simple "GET"-request. However now I am trying to do a "POST"-request. I use the code below to do the "GET" request. When looking at the puthPath of AFHTTPClient there is no way to set the data to use for the body. My guess is that there is another way of fixing this. I have been looking at the AFHTTPOperation as a way of fixing this. However I am not getting this to work. The problem is that I do not know how to use it with Basic Authentication.
Could somebody give me a hint of how to do a simple "POST"-request with AFNetworking?
AFHTTPClient* client = [AFHTTPClient clientWithBaseURL:ServerURL];
[client setAuthorizationHeaderWithUsername:self.username
password:self.password];
NSString* resourcePath = [NSString stringWithFormat:#"/some/resource/%#",
endPath];
[client getPath:resourcePath
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Success code omitted
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Some error handling code omitted
}
];
I did not find any easy way to do this. But I did as recommended and created my own sub-class of AFHTTPClient. In the subclass I implemented the methods below. This makes it possible to perform both POST-request & PUT-requests with my own data.
- (void)postPath:(NSString *)path
parameters:(NSDictionary *)parameters
data:(NSData*)data
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
{
NSURLRequest *request = [self requestWithMethod:#"POST" path:path parameters:parameters data:data];
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
[self enqueueHTTPRequestOperation:operation];
}
- (void)putPath:(NSString *)path
parameters:(NSDictionary *)parameters
data:(NSData*)data
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
{
NSURLRequest *request = [self requestWithMethod:#"PUT" path:path parameters:parameters data:data];
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
[self enqueueHTTPRequestOperation:operation];
}
-(NSMutableURLRequest*)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
data:(NSData*)data;
{
NSMutableURLRequest* request = [super requestWithMethod:method
path:path
parameters:parameters];
[request setHTTPBody:data];
return request;
}
With AFNetworking 2.0, I just copy code from
- (AFHTTPRequestOperation *)PUT:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
and add a
[request setHTTPBody:data];
Here is it:
NSString* str = [bookDetailLink objectForKey:#"Body"];
NSData* data = [str dataUsingEncoding: NSUTF8StringEncoding];
NSMutableURLRequest *request = [self.manager.requestSerializer requestWithMethod:#"PUT" URLString:bookingDetailUrl parameters:nil error:nil];
[request setHTTPBody:data];
AFHTTPRequestOperation *operation = [self.manager HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *op, NSHTTPURLResponse *response) {
NSLog(#"%#", response);
}
failure:^(AFHTTPRequestOperation *op, NSError *error) {
NSLog(#"%#", error);
}];
[self.manager.operationQueue addOperation:operation];
I am integrating Skyscanner API to our iOS app using AFNetworking.
With AFNetworking 1.3.2 the following code works for me:
NSData *imageData = UIImageJPEGRepresentation(thumb, 0.85F);
AFHTTPClient *httpClient = [[AFHTTPClient alloc]
initWithBaseURL:[NSURL URLWithString:#"https://example.com/"]];
NSMutableURLRequest *request = [httpClient
requestWithMethod:#"PUT" path:#"/foo" parameters:nil];
[request setHTTPBody:imageData];
[request setValue:#"image/jpeg" forHTTPHeaderField:#"Content-Type"];
AFHTTPRequestOperation *operation = [httpClient
HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *op, NSHTTPURLResponse *response) {
NSLog(#"%#", response);
}
failure:^(AFHTTPRequestOperation *op, NSError *error) {
NSLog(#"%#", error);
}];
[operation start];
This results in a PUT request with correct headers, Content-Lenght and general RESTfulness :-)