QLPreviewController not working in iOS 6 - objective-c

In iOS 6 the QLPreviewController no longer loads a PDF from a URL. It works fine in iOS 5. I have implemented the QLPreviewControllerDataSource methods as documented here.
#pragma mark - QLPreviewControllerDataSource
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
return 1;
}
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index;
{
NSURL *fileURL = [NSURL URLWithString:#"http://www.bliley.net/XTAL/PDF_Instructions/Test_File.pdf"];
return fileURL;
}
This works perfectly in iOS 5, however in iOS 6 the console outputs:
Couldn't issue file extension for path: /XTAL/PDF_Instructions/Test_File.pdf

Have you tried using fileURLWithPath instead of URLWithString? I had other issues that were fixed by doing so.
Also not sure if QLPreviewController will handle remote URLs. If not, you could download the file and then display it.

I downloaded the file from remote url and saved locally, then I display the PDF using the QLPreviewController .In iOS 6 its working.
First i saved the file from remote url using the following code :
NSString *local_location;
NSString *path = [[NSBundle mainBundle] pathForResource:#"sampleData" ofType:#"plist"];
path = NSTemporaryDirectory();
local_location= [path stringByAppendingPathComponent:[NSString stringWithFormat:#"My_Invoice.pdf"]];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: remoteurl]];
[request setDownloadDestinationPath:local_location];
[request startSynchronous];
For showing the Pdf :
QLPreviewController* preview = [[QLPreviewController alloc] init];
preview.dataSource = self;
[self presentModalViewController:preview animated:YES];
QLPreviewController delegate methods are :
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return 1;
}
- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
return [NSURL fileURLWithPath:local_location];
}

I am having a similar issue and seems like it might stem from a stricter enforcement of the file-type URL of QLPreviewItem
#property (readonly) NSURL *previewItemURL;
Discussion
This property is used by a Quick Look preview controller to get an item’s URL. In typical use, you would implement a getter method in your preview item class to provide this value.
The value of this property must be a file-type URL.
If the item is not available for preview, this property’s getter method should return nil. In this case, the Quick Look preview controller displays a “loading” view.
Availability
Available in iOS 4.0 and later.
Declared In
QLPreviewItem.h
UPDATE: I have opened a bug with Apple dealing with this issue for iOS 6 and it seems they have aced it as a bug so may offer a fix in the near future. The bug I opened had to do with using custom NSURLProtocols for the preview, but may apply to other aspects as well.
Link to class

But note that QLPreviewController expects a URL to a local resource
You would need to download and save the PDF file locally first and then create a proper file URL to the local file.

Related

NSSpeechSynthesizer does not write AIFF-file

using Xcode 5.1.1 on OS X 10.9.4,
consider the following code snippets:
- (IBAction)speak:(id)sender // text to loudspeaker, this works
{
[self setup]; // provide the synthesizer with its parameters
[speaker startSpeakingString: [textEntry stringValue]];
}
- (IBAction)storeSpeech:(id)sender // does not work
{
[self setup]; // provide the synthesizer with its parameters
[NSURL *outputFile =
[NSURL URLWithString:#"speech.aiff"];
[speaker startSpeakinString: [textEntry stringValue]
toURL:outputFile]; // the aiff-file is not created, why not?
}
Method speak outputs to the computers speaker. This works ok.
Method storeSpeech does not create any aiff-file. WHY NOT?
"speech.aiff" isn't much of a URL, is it?
Either use a URL that starts with file:// or use a path and a method that creates a file URL.

How do you set what about:home is on webView, Obj-C

I am creating a Cocoa web browser, and I noticed that if the webview loads a nil location, it just loads about:home. Since I have not set it, the page just appears white. Is there a way I can change what about:home looks like. Even if it is a simple .rtf file or something.
I looked around, but don't see any way to do this. Am I suppose to create a NSURL and set it to whatever file?
Thanks. Oh, and if code is ever needed, I would be glad to add it.
Try something like this:
// Inside your App Delegate
-(void)applicationDidFinishLaunching:(NSNotification *)notification {
// Assuming WebView is called myWebView
NSString *currentURL = [myWebView mainFrameURL];
if(!currentURL) {
NSString *homeResource = [[NSBundle mainBundle] pathForResource:#"home" ofType:#"html" inDirectory:#"default"];
NSURL *homeURL = [NSURL fileURLWithPath:homeResource];
NSURLRequest *request = [NSURLRequest requestWithURL:homeURL];
[myWebView loadRequest:request];
}
}
You'll need to have a pre-made file called home.html within a folder called default located in the Resources section of your project.
I suppose this isn't exactly replacing about:home, but you can always check for about:home and handle that appropriately as well.

Drag Files come across Sandbox(__CFPasteboardIssueSandboxExtensionForPath)

I processed drag operation from browser view to custom view.It work well in snow lepoard,but not in Mountain Lion with sandbox.
in browser view:
NSMutableArray* urls = [[[NSMutableArray alloc] init] autorelease];
..............put some NSUrl to urls array....................
[pasteboard writeObjects:[NSArray arrayWithArray:urls]];
in my receive custom view:
NSArray* pasteboardItems = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSString class]] options:nil];
NSArray* pasteboardItems2 = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:nil];
NSArray* pasteboardItems3 = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSImage class]] options:nil];
NSLog(#"%#",pasteboardItems);
NSLog(#"%#",pasteboardItems2);
NSLog(#"%#",pasteboardItems3);
my log is:
2012-08-09 18:33:43.886 iCollage[6885:303] __CFPasteboardIssueSandboxExtensionForPath: error for [/Users/xxxx/Library/Containers/xxxxxxxxxxxx/Data/Downloads/1343902069.jpg]
2012-08-09 18:33:44.546 iCollage[6885:303] ( "file://localhost/Users/xxx/Library/Containers/xxxxxxxx/Data/Downloads/1343902069.jpg")
2012-08-09 18:33:44.547 iCollage[6885:303] ( "file://localhost/Users/xxxxx/Library/Containers/xxxxxx/Data/Downloads/1343902069.jpg")
2012-08-09 18:33:44.547 iCollage[6885:303] ()
my question is:
1.how to fix this error __CFPasteboardIssueSandboxExtensionForPath;I refer the docs and found nothing about that.I am ensuer that i have the permission to access the file!google says, may be "startAccessingSecurityScopedResource" will help me, then i try and failed
2.why pasteboardItems2 have value?i write to pasteboard only url but not string.It disgusted me that I can get the url both from NSString type and NSUrl type! (I try drag a file from iFinder, the url will only exist in pasteboardItems but not pasteboardItems2).Anybody know why? I think the first problem will auto fixed when some one help me fix this problem.
I believe Apple answer question 1:
Important: Although you can support dragging file paths, in general,
you should avoid doing so unless you are certain that the destination
app will never be run in an app sandbox. If you use an NSString, OS X
has no way to know whether that string should be interpreted as a
path; thus, OS X does not expand the destination app’s sandbox to
allow access to the file or directory at that location. Instead, use
an NSURL, a bookmark, or a filename pasteboard type.
WRT to question 2, it looks like you have pasted URLs so reading NSURL objects would seem to be correct. However I think you should implement the dragging using the following code (also from the link above):
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
int numberOfFiles = [files count];
// Perform operation using the list of files
}
return YES;
}
You need to generate security-scoped URL bookmark data on the sender side, and turn that data back into a URL on the receiver side. There's some other stuff you have to do after that when you want to actually access the URL; the documentation elaborates.
The receiving application, when running in a sandbox, will not be able to handle bare paths. This is a core part of being sandboxed; you are not allowed to use bare paths or their corresponding URLs to access files that aren't in your sandbox container and haven't been explicitly handed to you by the user.
Your pasteboardItems read object of NSString type, but you dragged a file(with jpg extension), you should register for NSString type in your init method:
[self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeString]];
You need to have Document Types defined in your application so that the sandboxing mechanism knows your application should be opening files with those extensions. You can do this by clicking the project on the left in Xcode, and in the Info tab, under Document Types add a new document type for each extension.
You just need to fill in the name and extensions field.
Also if you want to persist your permission to access the files dragged onto your application, you can use this class to wrap up all that logic. https://github.com/leighmcculloch/AppSandboxFileAccess

Adding QLPreviewController as subview doesn't load PDF

I'm trying to add a QLPreviewController's view as a subview (no--I cannot use a nav controller or modal). It only shows the fabric background of the QLPreviewController.
I create one and add it as a subview:
QLPreviewController* preview = [[[QLPreviewController alloc] init] autorelease];
preview.dataSource = self;
preview.delegate = self;
preview.view.frame = CGRectMake(0, 0, self.pdfPreviewView.frame.size.width, self.pdfPreviewView.frame.size.height);
self.pdfPreviewView.previewController = preview;
[self.pdfPreviewView addSubview:preview.view];
[preview reloadData];
My QLPreviewControllerDataSource methods work fine (viewing 1 pdf at a time):
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index
{
NSString *path = [[ResourceManager defaultManager] pathForPDF:self.currentPDF];
NSURL *url = [NSURL fileURLWithPath:path];
if ([QLPreviewController canPreviewItem:url]) {
return url; // This always returns
}
return nil; // This line is never executed
}
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
{
return 1;
}
The data source method always returns the file url, and QLPreviewController says it can open the file, but it never actually does. I just get the background. The self.currentPDF is set before I create the QLPreviewController and does contain the correct information (from CoreData).
The delegate methods never get called. But I'm also not using it in a standard way, so that's not totally unexpected.
I've also tried calling [preview setNeedsLayout], [preview setNeedsDisplay'], and [preview refreshCurrentPreviewItem] but those just call the data source methods and don't change anything.
The PDFs are valid. I can open them in both Xcode and Preview, so that's not the problem. I'm kind of stumped as to why this won't work. Any help would be appreciated in getting this to work.
Turns out I was sending QLPreviewController the wrong path. It wasn't finding the PDF in the bundle correctly. I needed to use pathForResource:ofType:inDirectory.

Detect if NSString contains a URL and generate a "link" to open inside the app a Safari View

I have am reading a twitter feed in my iPhone application and can do it correctly, but I'd like to evolve it in a way to detect if the whole NSString contains any URL or URLs and create a "link" that will open a UIWebView within the same application.
Can you guide me on how to perform this task?
-(void) setTextTwitter:(NSString *)text WithDate:(NSString*)date
{
[text retain];
[textTwitter release], textTwitter = nil;
textTwitter = text;
[date retain];
[dateTwitter release], dateTwitter = nil;
dateTwitter = date;
[self setNeedsDisplay];
}
Check out Craig Hockenberry's IFTweetLabel, which can be found here.
Or you can use the label provided by Three20 library, which can be found here.
Or the simplest solution: use UIWebView with dataDetectorTypes set to UIDataDetectorTypeLink.
Cheers, Paul