I am trying to cancel an Asynchronous Download using ASIHTTPRequest with no joy. I am downloading a movie to disk on the appearance of a ViewController. What I want is when the user click close to dismiss the view controller I want to cancel the download. Here is the code I have so far:
Making the request:
-(void)retrieveLatestFile{
NSURL *url = [NSURL URLWithString:[appDelegate.urlToLoad stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
ashiRequest = [[ASIHTTPRequest requestWithURL:url] retain];
[ashiRequest setUsername:#"Appidae"];
[ashiRequest setPassword:#"Dubstance1"];
[ashiRequest setDelegate:self];
[ashiRequest startAsynchronous];
[ashiRequest setDownloadProgressDelegate:progressView];
NSLog(#"Value: %f", [progressView progress]);
if ([progressView progress]==1) {
[self hideInfoPane];
}
//NSLog(#"Max: %f, Value: %f", [myProgressIndicator maxValue],[myProgressIndicator doubleValue]);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tempPath = [NSString stringWithFormat:#"%#/download/%#/%#", documentsDirectory, appDelegate.languageFolder,appDelegate.filename];
NSLog(#"Path: %#", tempPath);
[ashiRequest setDownloadDestinationPath:tempPath];
}
Cancel the the downloading:
- (IBAction)closeDocDisplay:(id)sender {
// Cancels an asynchronous request
[ashiRequest clearDelegatesAndCancel];
[self dismissModalViewControllerAnimated:YES];
}
Everything is working, the download is fine and the movie plays properly but when I dismiss the View Controller the request is not canceled and my file is still downloading (network activity indicator spins on the status bar. Even the ASIHTTP delegate error doesn't get called
Try using
ashiRequest.delegate = nil;
[ashiRequest cancel];
This should work.
I figured out what was wrong. I was using Reachability to call my retrieveLatestFileMethod. That's fine if Reachability is being used just once in the app, maybe from the delegate. But I had a few instances of it so it keept calling the same functions and downloads.
Related
I'm doing a shop part for iOS application which has two page (first page for show list of voicePack in shop and second page for show detail of voice inside of voicePack).
when click on any cell in the voicePackList go to next page and in next page exists one button with name : DOWNLOAD that I want when I click on that button the voice downloaded and saved in document folder. this is the code that I made inside the button pressed processing:
- (void)downloadingVoice {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(#"Starting Download ...");
NSString *downloadUrl = #"10.3.1.228:9000/files";
NSURL *url = [NSURL URLWithString:downloadUrl];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if (urlData) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *voiceDirectory = [paths objectAtIndex:0];
NSString *voicePaths = [NSString stringWithFormat:#"%#%#", voiceDirectory,#"voice.mp3"];
dispatch_async(dispatch_get_main_queue(), ^{
[urlData writeToFile:voicePaths atomically:YES];
NSLog(#"Saved voice files");
});
}
});
}
- (void)btnDownloadClicked:(id)sender {
NSLog(#"Downloading Voice . . .");
[self downloadingVoice];
}
and here are how I put the button below the list of voices:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 60.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
// if(tableView == self.shopTableView) {
UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
UIButton *download = [UIButton buttonWithType:UIButtonTypeCustom];
[download setTitle:#"Download" forState:UIControlStateNormal];
[download addTarget:self action:#selector(btnDownloadClicked:) forControlEvents:UIControlEventTouchUpInside];
[download setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
download.frame = CGRectMake(0, 0, 130, 30);
[footerView addSubview:download];
return footerView;
}
when I click the button and put some breakpoints, it's end after if (urlData) when I check the urlData and downloadUrl, it says:
2015-09-17 10:53:01.926 Selfie[87197:674517] Starting Download ...
(lldb) po urlData
error: Couldn't materialize: couldn't get the value of variable urlData: no location, value may have been optimized out
Errored out in Execute, couldn't PrepareToExecuteJITExpression
(lldb) po downloadUrl
error: Couldn't materialize: couldn't get the value of variable downloadUrl: variable not available
Errored out in Execute, couldn't PrepareToExecuteJITExpression
anyone please help me to solve this.. I'll be really thank you for your help..
First of all, you are fetching voice data synchronously which is not advisable as this hangs your main thread. You can use your main thread to show the loading overlay and allow user to cancel the download operation if it is taking too much of time. Please use below method to make an Asynchronous call rather.
Secondly, can you please ensure the URL you are pointing to is open on the network you are trying to access the files. If this is a local server, better put localhost rather than IP address.
- (void)fetchFilesAsynchronously {
NSURL *myUrl = [NSURL URLWithString:#"http://10.3.1.228:9000/files"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:myUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0];
// Add headers as per your need
[urlRequest setValue:#"value" forHTTPHeaderField:#"key"];
// Add body as per your need
NSDictionary *body = #{#"key" : #"value"};
NSData *requestBodyData = [NSJSONSerialization dataWithJSONObject:body options:NSJSONWritingPrettyPrinted error:nil];
[urlRequest setHTTPBody:requestBodyData];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *iResponse, NSData *iData, NSError *iConnectionError) {
// Handle response here
}];
}
Third, for your debugger issue, please take a look at this thread.
Im trying to implement loading progress by MBProgressHUD.
Here is my code:
//Previously defined #property(nonatomic) NSString *sec;
-(void) viewDidLoad{
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
[HUD showWhileExecuting:#selector(loadData) onTarget:self withObject:nil animated:YES];
//testing the "return" value
NSLog(#"%#", sec);
}
-(void) loadData{
//get data from file named "results.csv"
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *saving = [docPath stringByAppendingPathComponent:#"results.csv"];
if([[NSFileManager defaultManager] fileExistsAtPath: saving]){
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:saving];
NSString *dataResults = [[NSString alloc]initWithData:[fileHandle availableData] encoding:NSUTF8StringEncoding];
[fileHandle closeFile];
sec = dataResults;
sec = [sec substringFromIndex: [sec length] - 20];
}
}
As you can see in the "loadData" method I need to set the "sec" NSString as the content that saved in the "results.csv" file.
You can see another thing, that after the HUD code: "showWhileExecuting" I was put NSLog to test if it really gets the content of the file and it returns (NULL)!!
Before I added this HUD thing, It did get the real value from the file, but now its return null.
Off-course when I put the NSLog code line at the end of the "loadData" method, it prints a real value instead of (NULL).
So, the big problem that I cant get the variables from the HUD method.
The only solution that I was thinking of, was to create another file and there store all the new variables, but its not help's me.
Anyone know what Im talking about and can help me?
What you see is normal. Your NULL showing NSLog is executed immediately after the showWhileExecuting call, before the loadData has been scheduled to run. You should implement the delegate protocol MBProgressHUDDelegate,
- (void)hudWasHidden:(MBProgressHUD *)hud{
NSLog(#"%#", sec);
}
When loadData completes, the HUD will hide, and call this method. That is when the result of loadData is available to you.
obcit: not tested, from memory, with an 'antique' MBProgressHUD , but a good chance it should work for you.
I'm quite the beginner to iOS Programming, and I googled how to get the UI Activity View implemented, but I'm getting errors that I do not quite understand. Anyone that can help me figure out what the errors mean in more specific detail and how to fix them, it would be greatly appreciated.
#pragma mark - SHARING OPTIONS (using a DocumentInteractionController) =============
/* =================
NOTE: The following methods work only on real device, not iOS Simulator, and you should have apps like Instagram, iPhoto, etc. already installed into your device!
================= */
-(void)shareImageToAllAppsAvailable {
NSLog(#"This code works only on device. Please test it on iPhone!");
// makes an NSURL file to the processed Image that needs to be saved
NSURL *fileURL;
docIntController.delegate = self;
//Saves the Image to default device directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"My Selfie.jpg"];
UIImage *image = combinedImage;
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
//Load the Image Path
NSString *getImagePath = [documentsDirectory stringByAppendingPathComponent:#"My Selfie.jpg"];
// this blank line here creates error 'use of undeclared identifier 'showActivityViewController''
// Create the URL path to the Image to be saved
fileURL = [[NSURL alloc] initFileURLWithPath:getImagePath];
// Open the Document Interaction controller for Sharing options
-(void)showActivityViewController
{
//-- set up the data objects
NSString *textObject = _aTextView.text;
UIImage *image = [UIImage imageNamed:#"My Selfie.jpg"];
NSArray *activityItems = [NSArray arrayWithObjects:textObject, url, image, nil];
//-- initialising the activity view controller
UIActivityViewController *avc = [[UIActivityViewController alloc]
initWithActivityItems:activityItems
applicationActivities:nil];
//-- define the activity view completion handler
avc.completionHandler = ^(NSString *activityType, BOOL completed){
NSLog(#"Activity Type selected: %#", activityType);
if (completed) {
NSLog(#"Selected activity was performed.");
} else {
if (activityType == NULL) {
NSLog(#"User dismissed the view controller without making a selection.");
} else {
NSLog(#"Activity was not performed.");
}
}
};
}
You're missing a closing } before your -(void)showActivityViewController declaration.
It looks like you're trying to call that method by defining it within another method, which is not valid Objective-C. Use the self construct to reference methods defined in the same class.
#pragma mark - SHARING OPTIONS (using a DocumentInteractionController) =============
/* =================
NOTE: The following methods work only on real device, not iOS Simulator, and you should have apps like Instagram, iPhoto, etc. already installed into your device!
================= */
-(void)shareImageToAllAppsAvailable {
NSLog(#"This code works only on device. Please test it on iPhone!");
// makes an NSURL file to the processed Image that needs to be saved
NSURL *fileURL;
docIntController.delegate = self;
//Saves the Image to default device directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"My Selfie.jpg"];
UIImage *image = combinedImage;
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
//Load the Image Path
NSString *getImagePath = [documentsDirectory stringByAppendingPathComponent:#"My Selfie.jpg"];
// this blank line here creates error 'use of undeclared identifier 'showActivityViewController''
// Create the URL path to the Image to be saved
fileURL = [[NSURL alloc] initFileURLWithPath:getImagePath];
// Open the Document Interaction controller for Sharing options
[self showActivityViewController]; //added
} //added
-(void)showActivityViewController
{
//-- set up the data objects
NSString *textObject = _aTextView.text;
UIImage *image = [UIImage imageNamed:#"My Selfie.jpg"];
NSArray *activityItems = [NSArray arrayWithObjects:textObject, url, image, nil];
//-- initialising the activity view controller
UIActivityViewController *avc = [[UIActivityViewController alloc]
initWithActivityItems:activityItems
applicationActivities:nil];
//-- define the activity view completion handler
avc.completionHandler = ^(NSString *activityType, BOOL completed){
NSLog(#"Activity Type selected: %#", activityType);
if (completed) {
NSLog(#"Selected activity was performed.");
} else {
if (activityType == NULL) {
NSLog(#"User dismissed the view controller without making a selection.");
} else {
NSLog(#"Activity was not performed.");
}
}
};
}
If I put download then suddenly I Lock the Iphone with Passcode, The downloading progress is getting stopped with in a fraction of seconds. the Dropbox service is not continuing to downloading the progress.
Here this method is for download operation.
-(void)downloadFile:(DBMetadata*)file
{
if (!file.isDirectory)
{
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
localPath = [documentsPath stringByAppendingPathComponent:file.filename];
[[self restClientForDownload] loadFile:file.path intoPath:localPath];
}
}
you have to call rest client methods from Main thread. If you're starting the connection from the the main thread, just use GCD to create and start the connection on the main thread -
dispatch_async(dispatch_get_main_queue(), ^
{
NSURLConnection *downManager = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
[downManager start];
});
I have the following code, which loads a pdf from the apps documents into a UIWebView.
-(IBAction)viewMyPdf:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *path = [documentsPath stringByAppendingPathComponent:#"myfilename.pdf"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[webView setScalesPageToFit:YES];
[self performSelector:#selector(theTest) withObject:nil afterDelay:2.0];
}
-(void)theTest {
NSLog(#"Hello");
[webView.scrollView setZoomScale:5.0 animated:NO];
webView.scrollView.contentOffset = CGPointMake(480, 360);
}
As you can see, at the end I am calling theTest to zoom into and set an appropriate position to start with (As I don't want to begin with the pdf fitting to the page). This has a delay of 0.2 which is undesirable because the time delay can vary and so the zoom effect may not happen (if load takes longer than 0.2s) or it feels very buggy and jumpy (depending on how much sooner it loads, than the 0.2 delay).
Is there a robust way to zoom in and position my pdf once it is loaded into the UIWebView?
EDIT: -(void)webViewDidFinishLoad:(UIWebView *)webView { does not seem to help either. It prints the NSLog but the zoom does not work. The webview does have its delegate set accordingly.
Why don't you try the QuickLook framework, if I understood well your question could do exactly what you are looking for. See that tutorial