Swift UIDocumentInteractionController not launching for preview my file - ios

My scenario, I am storing local some files and getting path to assigning UIDocumentInteractionController file path but UIDocumentInteractionController not opening.
My Code Below
func filepreview(filepath: String) {
let dc = UIDocumentInteractionController(url: URL(fileURLWithPath: filepath))
dc.delegate = self
dc.presentPreview(animated: true)
}
Warning: Attempt to present on
whose view is not in the window
hierarchy!

Related

Cannot preview .xlsx file using UIDocumentInteractionController in swift 4

I have an application which will download .xlsx, .pdf files from a given url. When downloaded will show a local notification. Upon clicking the notification , preview of the downloaded file should be shown. I can download and preview a pdf file, but when it comes to .xlsx file, I can't preview it. I used UIDocumentInteractionController and UIDocumentInteractionControllerDelegate to interact with the file's path to preview it.
func showFileWithPath(path: String)
{
print(path)
let isFileFound:Bool? = FileManager.default.fileExists(atPath: path)
if isFileFound == true
{
let viewer = UIDocumentInteractionController(url: URL(fileURLWithPath: path))
viewer.delegate = self
viewer.presentPreview(animated: true)
}
}
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController
{
return self.navigationController!
}
This showFileWithPath(path: String) method will be called in UserNotification delegate method and the path of the file is passed as the parameter. This code is working fine for pdf files. But when it comes to .xlsx files, the preview is not showing any contents, just showing loading. The same case when tried with QuickLook Framework.

Swift: UIDocumentInteractionController is not working?

UIDocumentInteractionController is not working with large pdf files with multiple pages.
Here in my code,
var docController:UIDocumentInteractionController!
...
DispatchQueue.main.async (execute: { [weak self] in
self?.docController = UIDocumentInteractionController(url: pdfFileURL!)
self?.docController.delegate = self
self?.docController.name = pdfFileURL?.lastPathComponent
self?.docController.presentPreview(animated: true)
})
and delegate method,
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
This is the warning in console,
2017-05-26 12:46:51.178894 MyApp [3350:1136818] [default] View service did terminate with error: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted} #Remote
Below attached is the blank image,
Please help me out thanks.
Try Like This:
Declare : var interaction: UIDocumentInteractionController?
Then add
interaction = UIDocumentInteractionController(url: URL(string: "<PDF FILE PATH>")!)
interaction.delegate = self
interaction.presentPreview(animated: true) // IF SHOW DIRECT
OR if need any suggestion popup
interaction.presentOpenInMenu(from: /*<SOURCE BUTTON FRAME>*/, in: self.view, animated: true)
Implement Delegate -> UIDocumentInteractionControllerDelegate
public func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
public func documentInteractionControllerDidEndPreview(_ controller: UIDocumentInteractionController) {
interaction = nil
}
Be sure that your file is actually pdf file by checking its extension or if url path contains ".pdf"
Otherwise it will recognize it as text file and will not open it.
I just implemented UIDocumentInteractionController last week and it's working fine.
Do one thing declare as UIDocumentInteractionController as var below to class
then do allocation and initialization in viewDidLoad()as I did
documentInteractionController = UIDocumentInteractionController.init()
documentInteractionController?.delegate = self
and at the time of presenting I make it like this
documentInteractionController?.url = url
documentInteractionController?.presentPreview(animated: true)
Hope it will resolve your problem.
(1) This issue usually occur in simulator. Check it on real device.
If that not the case
(2) Try this,
class ViewController: UIViewController, UIDocumentInteractionControllerDelegate {
var docController:UIDocumentInteractionController!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if let fileURL = NSBundle.mainBundle().pathForResource("SamplePDF1", ofType: "pdf") { // Use if let to unwrap to fileURL variable if file exists
docController = UIDocumentInteractionController(URL: NSURL(fileURLWithPath: fileURL))
docController.name = NSURL(fileURLWithPath: fileURL).lastPathComponent
docController.delegate = self
docController.presentPreviewAnimated(true)
}
}
func documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) -> UIViewController {
return self
}
func documentInteractionControllerDidEndPreview(controller: UIDocumentInteractionController) {
docController = nil
}
If you're loading a file from Bundle, this is a known bug in iOS 11.2.x. A workaround is copying the file to tmp:
let docUrl = Bundle.main.url(forResource: "Doc", withExtension: "pdf")!
// copy to tmp, because there is a bug in iOS 11.2.x,
// which will make pdf in UIDocumentInteractionController blank
let temporaryDirectoryPath = NSTemporaryDirectory()
let tmpDir = URL(fileURLWithPath: temporaryDirectoryPath, isDirectory: true)
let tmpUrl = tmpDir.appendingPathComponent("Doc.pdf")
do {
if FileManager.default.fileExists(atPath: tmpUrl.path) {
try FileManager.default.removeItem(at: tmpUrl)
}
try FileManager.default.copyItem(at: docUrl, to: tmpUrl)
let reader = UIDocumentInteractionController(url: tmpUrl)
reader.delegate = self
reader.presentPreview(animated: true)
} catch let error {
print("Cannot copy item at \(docUrl) to \(tmpUrl): \(error)")
}
Reference: https://forums.developer.apple.com/thread/91835
It does not issue with UIDocumentInteractionController.
In my case the PDF file is corrupted, that's why it is showing me the same screen.
Try to upload/open verified pdf file and you can preview same with UIDocumentInteractionController

iOS Action Extension share from GarageBand

I am building an action extension for GarageBand on iOS which transforms and uploads audio but no matter what I try, I just could not get to the exported file.
Let’s consider the following code — it should:
find and load shared audio from extensionContext
initialise audio player
play the sound
It works if I run the extension in Voice Memos.app — the url to the file looks like this: file:///tmp/com.apple.VoiceMemos/New%20Recording%202.m4a
Now, If I run the code in GarageBand.app, the url points to (what I presume) is GarageBand’s app container, as the url looks something like /var/…/Containers/…/Project.band/audio/Project.m4a, and the audio will not be loaded and cannot therefore be manipulated in any way.
// edit: If I try to load contents of the audio file, it looks like the data only contains aac header (?) but the rest of the file is empty
What is interesting is this: The extension renders a react-native view and if I pass the view the fileUrl (/var/…Project.band/audio/Project.m4a) and then pass it down to XMLHTTPRequest, the file gets uploaded. So it looks like the file can be accessed in some way?
I’m new to Swift/iOS development so this is kind of frustrating for me, I feel like I tried just about everything.
The code:
override func viewDidLoad() {
super.viewDidLoad()
var audioFound :Bool = false
for inputItem: Any in self.extensionContext!.inputItems {
let extensionItem = inputItem as! NSExtensionItem
for attachment: Any in extensionItem.attachments! {
print("attachment = \(attachment)")
let itemProvider = attachment as! NSItemProvider
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeAudio as String) {
itemProvider.loadItem(forTypeIdentifier: kUTTypeAudio as String,
options: nil, completionHandler: { (audioURL, error) in
OperationQueue.main.addOperation {
if let audioURL = audioURL as? NSURL {
print("audioUrl = \(audioURL)")
// in our sample code we just present and play the audio in our app extension
let theAVPlayer :AVPlayer = AVPlayer(url: audioURL as URL)
let theAVPlayerViewController :AVPlayerViewController = AVPlayerViewController()
theAVPlayerViewController.player = theAVPlayer
self.present(theAVPlayerViewController, animated: true) {
theAVPlayerViewController.player!.play()
}
}
}
})
audioFound = true
break
}
}
if (audioFound) {
break
}
}
}

PDF file not open in UIDocumentInteractionController

I am working on the simulator any there are no apps like adobe to open the pdf files....i am using UIDocumentInteractionController to open the pdf file like below.
let url=URL(fileURLWithPath: "/Users/sai/Library/Developer/CoreSimulator/Devices/425D8615-ADEC-4334-A639-C30B1E675EFA/data/Containers/Data/Application/AB3787BF-F6AC-4111-9847-A0FDC4E899F8/tmp/samplepdf.pdf")
print("--------------------------------- str is \(url)")
if (url != nil) {
// Initialize Document Interaction Controller
self.documentInteractionController = UIDocumentInteractionController(url: url)
// Configure Document Interaction Controller
self.documentInteractionController?.delegate = self
// Preview PDF
self.documentInteractionController?.presentOptionsMenu(from: self.view.frame, in: self.view, animated: true)
}
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
My screen is getting displayed like below
No pdf is being displayed here...is it because there is no app in my simulator which could open pdf files?
Not sure if any Simulator apps will handle pdf documents - maybe News? But you can just add a webView to a view controller and use that to view your pdf.
#IBOutlet weak var webView: UIWebView!
Do the usual safety checks on your url and then:
webView.loadRequest(NSURLRequest(url: url as URL) as URLRequest)
I think there is a path issue.
Replace
let url=URL(fileURLWithPath: "/Users/sai/Library/Developer/CoreSimulator/Devices/425D8615-ADEC-4334-A639-C30B1E675EFA/data/Containers/Data/Application/AB3787BF-F6AC-4111-9847-A0FDC4E899F8/tmp/samplepdf.pdf")
With
let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("samplepdf.pdf")
for Swift 3/Xcode 8
let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("samplepdf.pdf") as NSURL
Hope that will help.

UIDocumentInreactionController won't allow NSURL for .URL (Swift)

I'm basically taking a screenshot of a view, saving it to my camera roll , getting the NSURL path and exporting to Whatsapp
//Create the UIImage
UIGraphicsBeginImageContext(view.frame.size)
view.layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//Save it to camera roll round 2
var library = ALAssetsLibrary()
library.writeImageToSavedPhotosAlbum(image.CGImage, metadata: nil, completionBlock: {
(path:NSURL!, error:NSError!) -> Void in
if NSThread.currentThread() == NSThread.mainThread(){
println("\(path)")
var controller = UIDocumentInteractionController()
controller.delegate = self
controller.UTI = "net.whatsapp.image"
controller.URL = path
controller.presentOpenInMenuFromRect(CGRectZero, inView: self.view, animated: true)
}
})
I'm getting this error :
Assertion failure in -[UIDocumentInteractionController setURL:],
/SourceCache/UIKit/UIKit-3318.16.21/UIDocumentInteractionController.m:1024
But according to Apple's Documentation , it has to be a NSURL (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDocumentInteractionController_class/#//apple_ref/occ/instp/UIDocumentInteractionController/URL)
Any ideas?
Once a image is saved in camera roll or somewhere outside of your application, you can access it using URL with 'assets-library scheme'.
But UIDocumentInteractionController's URL property only supports URL with 'file scheme'.
So you need to save your image to your application's temporary directory and set 'path' property to it's file scheme URL.

Resources