This question already has answers here:
UIDocumentInteractionController no longer works in iOS6
(2 answers)
Closed 9 years ago.
In my app I use UIDocumentInteractionController to open a pdf document into acrobat reader (or any others viewers) but since iOS6 it doesn't work anymore.
I have try a lot of things, the last is from here :
UIDocumentInteractionController *docController = [[UIDocumentInteractionController alloc]init];
docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:documentsDirectory]];
docControler.UTI = #"com.adobe.pdf";
docController.delegate = self;
CGrect navRect = self.view.frame;
[docController presentOpenInMenuFromRect:navRect inView:self.view animated:YES];
When this code is running, my app totally freeze.
I have try with "presentOpenInMenuFromBarButtonItem" but I have the same issue.
assign the controller to a strongly referenced property:
#property (nonatomic, strong) UIDocumentInteractionController *docController;
I've used UIDocumentInteractionController successfully in iOS 6. Sample code:
self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:myPDFPath]];
[self.documentInteractionController presentOpenInMenuFromBarButtonItem:self.actionButton animated:YES];
You need to retain a reference to the UIDocumentInteractionController or it will be released before it's job is done.
Also, it looks like you're using the path of the documents folder, not the path to a particular file. I don't think this will work - pass the path to a specific file.
Related
I have been messing with this For days . I am new to xcode.. but just dont Get why I keep getting this error. I have tried and tried ... im hoping that someone can help me out. thank you for your time
- (void)longPressAction:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint touchLocation = [gestureRecognizer locationInView:self.webView];
NSString *javascript = [NSString stringWithFormat:#"document.elementFromPoint(%f, %f).src", touchLocation.x, touchLocation.y];
NSString *imageUrl = [self.webView stringByEvaluatingJavaScriptFromString:javascript];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:imageData];
// Show the editor
ImageEditorViewController *editView = [[ImageEditorViewController alloc] initWithImageAndSaveName:image saveName:[imageUrl lastPathComponent]];
[self.navigationController pushViewController:editView animated:YES];
}
Look in the .h file for "ImageEditorViewController" and see if it has a method declaration in there for "initWithImageAndSaveName:saveName:'".
Also make sure the ImageEditorViewController.h file is imported into the .m file that contains your "longPressAction" method.
It is simply trying to tell you that there is no method that exists with that name. There are two places where you could write that method. One would be in the header file between #interface and #end. The other location would be to put it in-between the #implementation and #end part of the .m file. I would recommend the latter, unless you are planning on subclassing this class and having another class use the method. It's just a little cleaner to only declare it in the #implementation and then privately reference it in your own methods.
Basically, though, to keep it short and simple, that method does not currently exist, and you need to implement it if you want to use it.
my app make a simple file called log.txt
the URL of this file (viewed in xcode) is file://localhost/var/mobile/Applications/NUMBER OF THE APPLICATION/Documents/log.txt
So I can see this file in the finder ...
I wanted to add the "open in" feature to my app to provide the user to share this file (via mail or imessage) or open this file in another compatible app.
Here is what I do :
-(void) openDocumentIn {
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:docFile]; //docFile is the path
//NSLog(#"%#",fileURL); // -> shows the URL in the xcode log window
UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
documentController.delegate = self;
documentController.UTI = #"public.text";
[documentController presentOpenInMenuFromRect:CGRectZero
inView:self.view
animated:YES];
}
Then the call to this function :
-(IBAction)share:(id)sender {
[self openDocumentIn];
}
When I run the app, I click on this "share" button, but nothing appends except showing me the path of the URL in the log window ...
I missed something ...
Thanks
EDIT : finally, it works on my real iphone ... there was no text viewer in the simulator !!! --'
EDIT 2 : it shows the apps that are available (pages, bump ...) but crashes finally :((( ! see here for the crash picture
Its a memory management issue. The main reason it crashes is because the object is not retained. Thats why if you declare it in the .h file and write an #property for retain when you do assign it the object gets retained.
So in your interface file (.h) you should have
#property (retain)UIDocumentInteractionController *documentController;
Then in your .m (implementation file) you can do
#synthesize documentController;
- (void)openDocumentIn{
// Some code here
self.documentController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
documentController.delegate = self;
documentController.UTI = #"public.text";
[documentController presentOpenInMenuFromRect:CGRectZero
inView:self.view
animated:YES];
// Some more stuff
}
Here is how it works for me :
I just put the declaration "UIDocumentInteractionController *documentController" in the .h file and it works !
I really don't know why, but ....
I'm trying to developed a really simple browser to be part of an iPad app. That browser will have tabs. All tabs are based on a .xib with an UIWebView filling almost all .xib frame.
I store all them inside an NSMutableArray, called tabsArray.
So, here's how I add a new tab to the array:
declaration:
.h
#property (nonatomic,strong) NSMutableArray *tabsArray;
#property (nonatomic,strong) UIDetailWebController *pagina;
.m
self.pagina = [[UIDetailWebController alloc] initWithNibName:#"UIDetailWebController" bundle:nil];
[tabsArray insertObject:pagina atIndex:currentViewTag+1];
how I display it on screen:
[self.view addSubview:[[tabsArray objectAtIndex:currentViewTag+1] view]];
And, finally, here's how I'm trying to "release" the UIWebView when user closes a tab (with a specific index):
[[[tabsArray objectAtIndex:index] view] removeFromSuperview];
[[tabsArray objectAtIndex:index] setWebView:nil];
[[tabsArray objectAtIndex:index] setView:nil];
[tabsArray removeObjectAtIndex:index];
My problem is: It appears that by doing this I simply don't release it. Memory consumption keeps the same, and If I'm playing an youtube video, the audio continues to play.
I'm kind of new on programming, and started iOS development by iOS 5, with ARC, so probably I'm letting slide some basic detail related to memory management.
SOLUTION:
Ok, I found out that what was retaining webview was the implementation of PullToRefreshView (https://github.com/chpwn/PullToRefreshView). When I set it's delegate to nil; everything just works!
The property pagina is is a strong property, so it retains the value that you assign to it in:
self.pagina = [[UIDetailWebController alloc] initWithNibName:#"UIDetailWebController" bundle:nil];
So you should set it to nil:
[tabsArray removeObjectAtIndex:index];
self.pagina = nil; // Add this line.
Finally, not that the following lines may not be needed:
[[tabsArray objectAtIndex:index] setWebView:nil];
[[tabsArray objectAtIndex:index] setView:nil];
And that the line:
[[[tabsArray objectAtIndex:index] view] removeFromSuperview];
may be simplified into:
[self.pagina removeFromSuperview];
I think the problem is that you store all your UIDetailWebControllers in an array. The array is keeping a strong pointer to your DetailWebController.
You should use:
[tabsArray removeObjectAtIndex:index];
And then set
self.pagina = nil;
After calling [self.pagina removeFromSuperView]; it should work.
I have a little issue from removeFromSuperView as it's not at least working with iPad2 with iOS 5. I'm displaying a custom UIView alert before my table populates with data and once done, I'm removing it from the super view. with every other device it's working fine except in iPad2 (iOS5). Am I missing anything?
.h
#private
SaveUIDisplayViewController *wbsSummaryLoadView;
.m
// Displaying
wbsSummaryLoadView = [[SaveUIDisplayViewController alloc] initWithNibName:#"SaveUIDisplayViewController" bundle:nil];
[[wbsSummaryLoadView view] setFrame:[self view].bounds];
[wbsSummaryLoadView setupSavingViewWithTitle:NSLocalizedString(#"Loading...", #"")];
[[self view] addSubview:wbsSummaryLoadView.view];
// Removing
[wbsSummaryLoadView.view removeFromSuperview];
[wbsSummaryLoadView release];
wbsSummaryLoadView = nil;
Once you add a view you can release it right away. (a copy is creating by using addSubview)
Try:
[[self view] addSubview:wbsSummaryLoadView.view];
[wbsSummaryLoadView release];
and then you don't need to care, because if you release whole view you release that added view as well.
You are storing two different objects. When you create the SaveUIDisplayViewController, you are declaring a new instance in that method. When you are removing it, you are using (I guess) the member variable.
SaveUIDisplayViewController *wbsSummaryLoadView = [[SaveUIDisplayViewController alloc] initWithNibName:#"SaveUIDisplayViewController" bundle:nil];
This will hide any declaration of wbsSummaryLoadView that you have defined in the header of the object.
And when you come to remove it
[wbsSummaryLoadView.view removeFromSuperview];
Has to have wbsSummaryLoadView declared somewhere so (this is where I'm guessing as you haven't posted your .h file) if this is declared in the header, then it won't be the same as the one when you created it (in fact it will probably be nil at this point)
I m using ASIHTTP Request sample source code for downloading urls.
My question is that how to pause and resume the downloading files.
Please Help.
Deprecation Notice
ASIHTTP was deprecated around 2011, if you want network connectivity now, you should look up AFNetworking for ObjC or Alamofire for Swift, or stick to the native support:
For native support, in iOS 7 Apple added the NSURLSession, which can start download tasks (NSURLSessionDownloadTask), and these can be cancelled and restarted, check the method downloadTaskWithResumeData(_:) from NSURLSession, that has a very good explanation.
ASIHTTP is no longer needed, if you gotta are keeping a legacy app running, well, good luck.
Original Answer
Posted on 2011
ASI itself can resume a download from a file using [myASIRequest setAllowResumeForFileDownloads:YES];, check out the How-to-Use for an example.
Edit: Ok, there's no easy way to pause a download (a [myRequest pause] would be ideal). After reading and trying for a while, turns out that cancelling the request and resending it again is the only way.
For example, here's an example class I made:
#interface TestViewController : UIViewController <ASIHTTPRequestDelegate>
{
ASIHTTPRequest *requestImage;
UIImageView *imageViewDownload;
}
#property (nonatomic, retain) IBOutlet UIImageView *imageViewDownload;
- (IBAction)didPressPauseButton:(id)sender;
- (IBAction)didPressResumeButton:(id)sender;
To start (or restart) the download:
- (IBAction)didPressResumeButton:(id)sender
{
if (requestImage)
return;
NSLog(#"Resumed");
// Request
requestImage = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:#"http://www.myheadhealth.com/_IMAGES/cheese.jpg"]];
// Using a temporary destination path just for show.
// Better pick a suitable path for your download.
NSString *destinationDownloadPath = [NSTemporaryDirectory() stringByAppendingPathComponent:#"cheese.jpg"];
NSString *temporaryDownloadPath = [NSTemporaryDirectory() stringByAppendingPathComponent:#"cheese.jpg-part"];
requestImage.downloadDestinationPath = destinationDownloadPath;
requestImage.temporaryFileDownloadPath = temporaryDownloadPath;
requestImage.allowResumeForFileDownloads = YES;
requestImage.delegate = self;
[requestImage startAsynchronous];
}
In the exmaple above, I'm loading a random image of cheese I found, and storing a temporary download, and a full download.
Canceling the request will keep the contents of the temporary file intact, in fact, I made an UIImageView, and when pressing "Cancel" I could see a part of the downloaded file. If you want to try it out:
- (void)didPressPauseButton:(id)sender
{
if (requestImage)
{
// An imageView I made to check out the contents of the temporary file.
imageViewDownload.image = [UIImage imageWithContentsOfFile:requestImage.temporaryFileDownloadPath];
[requestImage clearDelegatesAndCancel];
requestImage = nil;
NSLog(#"Canceled");
}
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
imageViewDownload.image = [UIImage imageWithContentsOfFile:request.downloadDestinationPath];
requestImage = nil;
}