unable to download file
getting this error "Client closed connection before receiving entire response"
the file which i am trying to download is just 266KB
for (NSString *downloadURL in arr) {
// NSString *downloadURL = [d objectForKey:#"url"];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"URL for downloading : %#",downloadURL);
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [pathArray objectAtIndex:0];
NSString *downloadedZipPath = [documentsDirectory stringByAppendingPathComponent:TEMP_DICTIONARY];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:downloadURL]];
// [request addValue:#"bytes=x-" forHTTPHeaderField:#"Range"];
// [request setTimeoutInterval:20];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:downloadedZipPath append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
});
tried to increase api request time out but still not working
Try setting it to more time
[request setTimeoutInterval:20];
I have some error like this. But I think it is not the AF faults. When the thing's content-type you request is different from it's original content type this error will come out.
For Example:
When you request a mp4 file, the server should set the content-type to video/mpeg4, or you can change your request type from GET to POST.
Related
I want to access Twilio api using AFNetworking. I tried number of ways but not get success. Please help me, if anyone did Tiwilo post request using AFNetworking.
Case 1: This is my native objective-c working code.
NSString *urlString = [NSString stringWithFormat:#"https://%#:%##api.twilio.com/2010-04-01/Accounts/%#/SMS/Messages", kTwilioSID, kTwilioSecret, kTwilioSID];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
NSString *bodyString = [NSString stringWithFormat:#"From=%#&To=%#&Body=%#", from, to, message];
NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError)
{
DLog(#"Error: %#", connectionError);
completionBlock(connectionError, NO);
}
else
{
completionBlock(connectionError, YES);
}
}];
Case 2: Using AFNetorking: Code that is not working:
Code:
NSString *urlString = [NSString stringWithFormat:#"https://%#:%##api.twilio.com/2010-04-01/Accounts/%#/SMS/Messages", kTwilioSID, kTwilioSecret, kTwilioSID];
NSDictionary *dict = #{
#"From" : from,
#"To" : to,
#"Body" : message
};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:urlString parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"Success: %#", responseObject);
}
failure:
^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Related Error:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x1775e660 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set., NSUnderlyingError=0x175101b0 "Request failed: bad request (400)"}
Case 3: Using AFNetorking: Another Code that is also not working:
Code:
NSString *urlString = [NSString stringWithFormat:#"https://%#:%##api.twilio.com/2010-04-01/Accounts/%#/SMS/Messages", kTwilioSID, kTwilioSecret, kTwilioSID];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
NSString *bodyString = [NSString stringWithFormat:#"From=%#&To=%#&Body=%#", from, to, message];
NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error);
}];
[operation start];
Related Error:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x177a3e70 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
Thank you.
Ricky from Twilio here. First off a quick disclaimer. Making a request to Twilio directly from an iOS app requires you to embed your Twilio account credentials in the app, which is dangerous. My recommendation would be to send the SMS from a server side script that your app makes a request to in order to keep your credentials safe.
That being said, your code is really close. By default, Twilio's REST API returns XML. If you want to parse the response as it's returned by default you can update the code in version 2 to use the AFXMLParserResponseSerializer:
operation.responseSerializer = [AFXMLParserResponseSerializer serializer];
If you'd rather work with JSON then you update the Twilio URL you're making the POST request to and indicate you'd like a JSON response:
NSString *urlString = [NSString stringWithFormat:#"https://%#:%##api.twilio.com/2010-04-01/Accounts/%#/SMS/Messages.json", kTwilioSID, kTwilioSecret, kTwilioSID];
Hope that helps.
I'm doing a simple request in order to download PDF files and then write it to the file path.
Some of the PDF's are getting directed to the fail block.
The error code I'm getting is 200 and the error description is "transfer closed with 2231939 bytes remaining to read".
Below is the code snippet.
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:nil
timeoutInterval:120];
AFHTTPRequestOperation *downloadRequest = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[downloadRequest setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (operation.response.statusCode != 200) {
NSLog(#"Error code(S): %d",[operation.response statusCode]);
}else{
NSData *data = [[NSData alloc] initWithData:responseObject];
[data writeToFile:filePath atomically:YES];
NSLog(#"successful download to %#", filePath);
[data release];
}
[self fetchComplete:operation type:type];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error code: %d",[operation.response statusCode]);
NSLog(#"error discreption: %#",[error localizedDescription]);
[self fetchFailed:operation];
}];
Please, try this example. Hope this help!
// Step 1: create NSURL with full path to downloading file
// for example try this: NSString *fileUrl = #"https://pbs.twimg.com/profile_images/2331579964/jrqzn4q29vwy4mors75s_400x400.png";
// And create NSURLRequest object with our URL
NSURL *URL = [NSURL URLWithString:fileUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
// Step 2: save downloading file's name
// For example our fileName string is equal to 'jrqzn4q29vwy4mors75s_400x400.png'
NSString *fileName = [URL lastPathComponent];
// Step 3: create AFHTTPRequestOperation object with our request
AFHTTPRequestOperation *downloadRequest = [[AFHTTPRequestOperation alloc] initWithRequest:request];
// Step 4: set handling for answer from server and errors with request
[downloadRequest setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// here we must create NSData object with received data...
NSData *data = [[NSData alloc] initWithData:responseObject];
// ... and save this object as file
// Here 'pathToFile' must be path to directory 'Documents' on your device + filename, of course
[data writeToFile:pathToFile atomically:YES];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"file downloading error : %#", [error localizedDescription]);
}];
// Step 5: begin asynchronous download
[downloadRequest start];
I am having a hard time sifting through search results for how to do this and I can't find anything concrete in the documentation. I just want to download a file and store in the Documents directory. The file is of type .plist, but I don't need to parse the plist. Like I said I just need to save it to disk.
Do I use AFHTTPRequestOperationManager for this?
This is what I've been trying in general:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:url parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
DLog(#"downloaded plist");
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(#"JSON DataError: %#", error);
}];
If I use AFHTTPResponseSerializer I get this:
Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed: internal server error (500)"
If I use AFPropertyListResponseSerializer I get this:
Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/plain"
But I'm not even sure I'm using the correct API.
Please, try this example.
Hope this help!
// Step 1: create NSURL with full path to downloading file
// for example try this: NSString *fileUrl = #"https://pbs.twimg.com/profile_images/2331579964/jrqzn4q29vwy4mors75s_400x400.png";
// And create NSURLRequest object with our URL
NSURL *URL = [NSURL URLWithString:fileUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
// Step 2: save downloading file's name
// For example our fileName string is equal to 'jrqzn4q29vwy4mors75s_400x400.png'
NSString *fileName = [URL lastPathComponent];
// Step 3: create AFHTTPRequestOperation object with our request
AFHTTPRequestOperation *downloadRequest = [[AFHTTPRequestOperation alloc] initWithRequest:request];
// Step 4: set handling for answer from server and errors with request
[downloadRequest setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// here we must create NSData object with received data...
NSData *data = [[NSData alloc] initWithData:responseObject];
// ... and save this object as file
// Here 'pathToFile' must be path to directory 'Documents' on your device + filename, of course
[data writeToFile:pathToFile atomically:YES];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"file downloading error : %#", [error localizedDescription]);
}];
// Step 5: begin asynchronous download
[downloadRequest start];
Something else: What's the best way to find the user's Documents directory on an iPhone?
I'm trying to compile application on my iPad. I'm using AFNetworking to get list of files on my FTP. Application works on simulator, but when i start it on iPad i get (null) content of file with list. Here's code:
- (void) getListOfFiles {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"ftp://anonymous#ftphost/"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *path = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"list"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, NSHTTPURLResponse *response) {
NSLog(#"Success %#",operation.response);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
[operation start];
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSLog (#"%#",content);
}
So variable content = (null) only on iPad, and on Simulator everything is fine. Please help, i have lost any hope )
the AFHTTP*Operations are all asynchronous by default.
this is proper, since synchronous(blocking) calls block the main thread
you are starting the operation and take file content directly afterwards. This can't work reliably because the start call is ASYNC and only STARTS the op but doesnt wait for it
either wait for it ... which is BAD as it blocks the thread:
[operation start];
[operation waitUntilDone];
or MUCH BETTER modify getFiles to work asynchronously:
- (void) getListOfFiles {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"URL"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *path = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"list"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, NSHTTPURLResponse *response) {
NSLog(#"Success %#",operation.response);
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSLog (#"%#",content);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
[operation start];
}
Ok, problem solved. I can't write to bundle directory, so i nee to use next code instead:
NSArray *paths = NSSearchPathForDirectoiesDomain(NSDocumentDirectory,NSCachesDirectory,YES);
NSString *path = [[paths objectAtIndex:0] stingByAppendingPathComponent:#"list"];
I am using AFHTTPRequestOperation to get a couple of HTML pages to parse.
The problem i'm having, is if I use a wrong port number for example, when connecting to the server, the 'failed' error block doesn't fire. Instead the completion block fires but the responce string is nil.
I'm just switching over to AFNetworking from ASIHTTP, and with ASIHTTP this would produce an error.
Surely this should provide an error? How can I trap this?
NSString *urlString;
urlString = [NSString stringWithFormat:#"%#://%#:%#/",kHttp,_IP,_Port];
NSURL *url = [NSURL URLWithString:urlString];
// Set authorization
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[httpClient setAuthorizationHeaderWithUsername:_User password:_Pass];
NSURLRequest *request = [httpClient requestWithMethod:#"POST" path:#"Info.htm" parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([self parseInfoLive:operation.responseString])
_count_parsed++;
if (_count_parsed == 2)
[[NSNotificationCenter defaultCenter] postNotificationName:#"downloadsComplete" object:nil];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error during connection: %#",error.description);
[[NSNotificationCenter defaultCenter] postNotificationName:#"errorConnecting" object:nil];
}];
[operation start];
This seems to be a bug in AFNetworking, even 2.5 years after this question. This occurs when response contains a special character(it can appear as a space since sometimes even text viewers too can't parse it). You can try converting recieved JSON string to NSUTF8StringEncoding and then use it as NSData, if needed.
NSURL *url = <YOUR REQUEST URL>
NSString *data = [NSString stringWithContentsOfURL:url];
NSData *metOfficeData = [data dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = [NSError new];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:metOfficeData options:kNilOptions error:&error];