QuickLook

RSS for tag

Create previews of files to use inside your app or perform simple edits on previews using QuickLook.

QuickLook Documentation

Posts under QuickLook tag

30 Posts
Sort by:
Post not yet marked as solved
2 Replies
472 Views
I am creating a MacOS app embedding the QuickLook extension in it. The other day, I uploaded it to App Store Connect and had it reviewed. But it was rejected due to the following reason. Your app incorrectly implements sandboxing, or it contains one or more entitlements with invalid values. Please review the included entitlements and sandboxing documentation and resolve this issue before resubmitting a new binary. com.apple.security.temporary-exception.files.absolute-path.read-only / This entitlement is also included in my app's meta data on my account page of App Sore Connect. Including it, I can find the following two entitlements related to "temporary-exception" in the meta data. com.apple.security.temporary-exception.files.absolute-path.read-only: ( "/" ) com.apple.security.temporary-exception.mach-lookup.global-name: ( "com.apple.testmanagerd", "com.apple.dt.testmanagerd.runner", "com.apple.coresymbolicationd" ) To tell the truth, about Sandbox entitlements for QuickLook extension, what I intentionally set on the Xcode project are the next two items only. And actually I have not ever recognized that the entitlements related to "temporary-exception" above are included in my app's bundle. com.apple.security.app-sandbox: true com.apple.security.files.user-selected.read-only: true I think these "temporary-expection" entitlements are essential ones for the QuickLook extension and it looks like that Xcode automatically attached them in the process of creating app's build. If they are forced to be attached by getting the QuickLook extension sandboxed, I don't know what I should do. Although I explained my thought to the reviewer, but I could not change the situation. Is there no way to get solution besides removing the QuickLook extension from my app ?
Posted
by
Post not yet marked as solved
0 Replies
347 Views
Is there any way to identify if the QLPreviewController is in markup mode? I have a custom QLPreviewController which is used to preview and edit images in my app. I need to identify when entering the markup mode and make some changes in the navigation bar based on this. But I could not find any variable or delegate methods to identify this. Any help will be appreciated.
Posted
by
Post marked as solved
2 Replies
583 Views
Hi! I'm participating in the Swift Student Developer competition this year, which requires developers to present a Swift Playground to Apple. I'm used to making normal Xcode projects, and am having trouble finding a Swift Playgrounds version of the Copy Bundle Resources build phase (I don't think it is possible to edit build phases in a Swift Playground). I created a '.usdz' file from a 3D model I designed using Reality Converter and added it to the root of my Swift Playground project. I access the file programmatically from the App Bundle like so (fileName is a non-nullable String): guard let path = Bundle.main.path(forResource: fileName, ofType: "usdz") else { fatalError("Couldn't find the USDZ file.") } At runtime, this throws the Couldn't find the USDZ file error, as the file isn't being copied to the App Bundle. In a normal Xcode project, according to this StackOverflow question, I can get xcodebuild to copy my file over by specifying it in the Copy Bundle Resources build phase, however, in a Swift Playground (required by Apple), I am restricted from modifying Xcode's buildphases (the option is not present when clicking on the default target - the only options are General, Signing & Capabilites and Package Dependencies). How can I ensure that resources are copied over to the App Bundle at buildtime in a Swift Playground? If this is not possible, are there any other options besides using the Bundle.main.path API for accessing the USDZ file (to load a QuickLook preview) at runtime?
Posted
by
Post marked as solved
1 Replies
399 Views
Hi folks, My app is reading proprietary files with the file name extension .JPX - which is out of my control. In addition I’m providing QuickLook and Thumbnail extensions, used system-wide and in my app. Unfortunately iOS is assigning the JPEG-2000 file type (UTI „public.jpeg-2000“) to this file extension, and therefore - to work with associated files - my app is importing this UTI and both extensions are listing „public.jpeg-2000“ in their info.plist as QLSupportedContentTypes. This works to some extent in simulators and when debugging from Xcode on a device: Files with the file extension „.JPX“ are listed with thumbnails provided by my extension, although the preview seems to invoke the system-provided viewer and fails. Not perfect, but good enough as my app requires an icon preview (aka thumbnail) in its UIDocumentBrowserViewController. But when I try to submit my app incl. extensions to the Apple App Store / TestFlight asset validation is reporting an error: „Asset validation failed. Invalid Info.plist value. The value for the key ‚QLSupportedContentTypes‘ in bundle … is invalid. [public.jpeg-2000] are system-supported types.“ How to assign QuickLook / Thumbnail extensions to 3rd party files types whose extension is conflicting with a system-supported UTI? I just spent one of my TSIs for this question - as my Apple developer membership is renewed shortly - but maybe this community as some smart tip to share... Appreciate any help, Mattes
Posted
by
Post not yet marked as solved
0 Replies
339 Views
Hello, I am trying to write a simple QuickLook generator, which takes a file, runs an external binary to produce the data, and then creates and shows an image in a preview. The input files are uncommon data formats, and the binary in this case converts these to PNG. I have tried multiple methods and followed many discussions on these forums and StackOverflow, but unfortunately I am yet to get it working. That said, the program I have builds and runs using the qlmanage tool, however when running in Finder or on the server qlmanage -x the program fails. As I understand, it when using QuickLook in Finder it calls the QuickLook daemon quicklookd which is also called when using the qlmanage -x CLI command, but please correct me if I am wrong about this. The basic idea for all generator functions is: create NSTask or Process and run the third-party binary, using the requested file path as input run the task, pipe output, and read output convert the piped output to NSImage show image Attempt 1 (old-style qlgenerator plugin in Obj-C): Initially I tried adding the binary as an asset to the QuickLook Preview target and the generator would work as mentioned using qlmanage, however it would not work using qlmanage -x or from Finder. Here is the preview function: OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) { NSLog(@"QuickLook plugin started"); NSInteger width = 512; NSURL *fileURL = (__bridge NSURL *)url; NSString *escapedFilePath = [fileURL.path stringByReplacingOccurrencesOfString:@" " withString:@"\\ "]; NSLog(@"Original Path: %@", fileURL.path); NSLog(@"Escaped Path: %@", escapedFilePath); NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.pjharrison.qlgwyddion"]; NSURL *nsURLExecutable = [bundle URLForAuxiliaryExecutable:@"gwyddion-thumbnailer"]; if (nsURLExecutable) { // The resource was found, and nsURLData is not nil. // Proceed with using nsURLData. NSLog(@"Resource 'gwyddion-thumbnailer' found in the bundle."); } else { // The resource was not found. Handle the situation accordingly. NSLog(@"Resource 'gwyddion-thumbnailer' not found in the bundle."); } NSTask *task = [[NSTask alloc] init]; NSLog(@"Pathhhh %@", nsURLExecutable.path); [task setExecutableURL:nsURLExecutable]; [task setArguments:@[@"kde4", [@(width) stringValue], escapedFilePath]]; NSLog(@"Task set"); NSString *argumentString = [task.arguments componentsJoinedByString:@" "]; NSLog(argumentString); NSPipe *pipe = [NSPipe pipe]; NSFileHandle *file = pipe.fileHandleForReading; [task setStandardOutput:pipe]; NSLog(@"Pipe set"); [task launch]; NSLog(@"Task launched"); NSData *data = [file readDataToEndOfFile]; NSLog(@"Got data"); [task waitUntilExit]; NSLog(@"Task completed"); NSInteger taskStatusCode = [task terminationStatus]; NSLog(@"Task finished with status code %ld", taskStatusCode); NSString *dataLength = [NSString stringWithFormat:@"%lu", data.length]; NSLog(dataLength); CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData((CFDataRef)data); CGImageRef cgImage = CGImageCreateWithPNGDataProvider(imageDataProvider, NULL, true, kCGRenderingIntentDefault); if (cgImage) { CGFloat height = CGImageGetHeight(cgImage); CGFloat width = CGImageGetWidth(cgImage); CGSize size = CGSizeMake(width, height); // Preview will be drawn in a vectorized context CGRect rect = CGRectMake(0, 0, width, height); CGContextRef cgContext = QLPreviewRequestCreateContext(preview, size, true, NULL); CGContextDrawImage(cgContext, rect, cgImage); NSLog(@"Image drawn"); QLPreviewRequestFlushContext(preview, cgContext); NSLog(@"Flushed"); // release resources if (cgContext) { CFRelease(cgContext); NSLog(@"Context released"); } CGImageRelease(cgImage); NSLog(@"Image released"); } else { NSLog(@"cgImage is NULL"); } return noErr; } Inspection console logs would give various Operation not permitted errors when run from the quicklookd server. I suspect that possibly this is due to App Sandboxing issues. Attempt 2 After coming across various articles online by @eskimo and others, including the official docs and various other posts, I have tried to sign the binary executable as described in the documentation and embed it in the project. Unfortunately after signing the app I have not been able to get the executable to run. When called from the QuickLook Preview function, the process returns with an error code. Perhaps the issue is here and the executable has not been signed properly? Attempt 3 I have also tried to create a Swift-based app and add a QuickLook Extension to the app (creating an app with a .appex) using a similar flow as tried in Attempt 1. Also no luck here so far. At this point I am stuck and would appreciate any help or pointers! Many thanks in advance.
Posted
by
Post not yet marked as solved
0 Replies
371 Views
Hi all, I have created a QuickLook Preview for my custom datatype in my app. I use SwiftUI wrapped in UIKit for the preview. My issue is that when I try and play audio using AVAudioPlayer, I receive a status code 50 error. Does anyone know if there are seperate permissions I need to request before being able to do this? Here are the errors I get while trying to set my audio session as active and play on the avaudioplayer Thanks for your help and advice! The operation couldn’t be completed. (OSStatus error -50.) nwi_state: registration failed (9) connection <connection: 0x100e0b270> { name = com.apple.audio.AudioQueueServer, listener = false, pid = 0, euid = 4294967295, egid = 4294967295, asid = 4294967295 } : error <dictionary: 0x251524530> { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" => <string: 0x2515246c8> { length = 18, contents = "Connection invalid" } } auto-cancelling <connection: 0x100e0b270> { name = com.apple.audio.AudioQueueServer, listener = false, pid = 0, euid = 4294967295, egid = 4294967295, asid = 4294967295 } 0x2816bf680 reply: XPC_ERROR_CONNECTION_INVALID throwing swix::exception: !(is_valid()) AQ_API_V2Impl.cpp:134 AudioQueueNew: <-AudioQueueNew failed -302 rebuilding null connection 0x2816bf680 reply: XPC_ERROR_CONNECTION_INVALID connection <connection: 0x100822a90> { name = com.apple.audio.AudioQueueServer, listener = false, pid = 0, euid = 4294967295, egid = 4294967295, asid = 4294967295 } : error <dictionary: 0x251524530> { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" => <string: 0x2515246c8> { length = 18, contents = "Connection invalid" } } throwing swix::exception: !(is_valid()) auto-cancelling <connection: 0x100822a90> { name = com.apple.audio.AudioQueueServer, listener = false, pid = 0, euid = 4294967295, egid = 4294967295, asid = 4294967295 } AQ_API_V2Impl.cpp:134 AudioQueueNew: <-AudioQueueNew failed -302
Posted
by
Post not yet marked as solved
0 Replies
250 Views
I am using QlPreviewController in my applications, I am download the data one by one using observer, The observer detects currentIndexItem in the preview controller, The image is only download when the currentIndexItem will changed ,After downloading i will refresh the currentPreviewItem , My Problem is , while downloading an files in first item and i am moving to the next items , which also downloading an files,And both screens are freezing , after click the menu button, in the sections show images is loaded , but not reflected. While i am calling download data, The thread is changed to Background thread DispatchQueue.global().async { interactor.processData(kbPath: categoriesPath) } }else{ interactor.processData(kbPath: categoriesPath) } This is the downloading file which will happens in Background thread, The above code will change let url = fileData.contentUrl let fileName = fileData.name let contentUrl = fileData.contentUrl let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let destinationURL = documentsURL.appendingPathComponent(fileName) // Check if the file already exists at the destination URL if FileManager.default.fileExists(atPath: destinationURL.path){ return completion(.success(File(data: destinationURL, name: fileName, contentUrl: contentUrl, hasData: true))) } // If the file doesn't exist, proceed with downloading let request = URLRequest(url: URL(string: url)!) let task = URLSession.shared.downloadTask(with: request) {(tempFileURL, response, error) in if let error = error { print("Error downloading file: \(error)") completion(.failure(.FailedToDownload)) return } guard let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode == 200,let tempFileURL = tempFileURL else { print("Failed to download file. Invalid response.") completion(.failure(.FailedToDownload)) return } do { try FileManager.default.moveItem(at: tempFileURL, to: destinationURL) completion(.success(File(data: destinationURL, name: fileName, contentUrl: url, hasData: true))) } catch { print("Error moving file: \(error)") completion(.failure(.FailedToDownload)) } } task.resume() } After Downloading the data , it will inform to the viewcontroller to check the thread and call DispatchQueue.main.async { handler() } }else{ handler() } This is my Observer if context == &previewControllerContext{ if keyPath == "currentPreviewItemIndex" { let currentIndex = preview.currentPreviewItemIndex //api calls for the specific files if currentIndex < previewData.count && !previewData[currentIndex].hasData { self.loadingView.startAnimating() let builder = Builder() self.previewData[currentIndex].hasData = true builder.build(instance: self, categoriesPath: .KBDownloadFile(fileData: self.previewData[currentIndex])) } } }else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } After downloaded image the result will notify and i will refresh the current previewItem self.preview.refreshCurrentPreviewItem() The Issue video link -> https://drive.google.com/file/d/18pBZawbvcUU3SA5vS53X9R9q-AGMG5Sv/view Any one facing this issues with this ,my thought this issues is thread based , but i will handle the thread
Posted
by
Post not yet marked as solved
0 Replies
315 Views
Though I cannot find any documentation, it seems that UIPasteboard cannot be used from a Quick Look Preview app extension. I have such an extension, which contains a view that supports copying text as follows: - (IBAction)copy:(nullable id)sender { UIPasteboard * pboard = UIPasteboard.generalPasteboard; pboard.string = _rep.text; } This is invoked from a context menu (edit menu) item. This works fine In the simulator, but on device the pasteboard remains empty and errors like the following are emitted: -[PBServerConnection pasteboardWithName:createIfNeeded:authenticationBlock:dataOwnerBlock:error:] failed with error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.pasteboard.pasted was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.pasteboard.pasted was invalidated: failed at lookup with error 159 - Sandbox restriction.} It's unclear to me why such functionality would be problematic and necessary to block. It would be nice if this were documented clearly, as I wasted a lot of time trying to figure out why this was not working. (And no, I have not filed a feedback report or TSI yet, as I'm presently very short on time, and I don't have a sample project prepared to demonstrate the issue.)
Posted
by