【问题标题】:Swift: How to Open local pdf from my app to iBooksSwift:如何将本地 pdf 从我的应用程序打开到 iBooks
【发布时间】:2015-01-15 08:07:12
【问题描述】:

我之前在objective-c。目标 C 中的以下代码运行良好:

在。 h

@property (retain)UIDocumentInteractionController *docController;

在.m

    NSString *path = [[NSBundle mainBundle] pathForResource:@"book" ofType:@"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];


docController = [UIDocumentInteractionController interactionControllerWithURL:targetURL];

if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"itms-books:"]]) {

    [docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
    NSLog(@"iBooks installed");

} else {

    NSLog(@"iBooks not installed");

}

但现在我正在尝试使用 swift 打开,这是我的 swift 代码:

      if let path = NSBundle.mainBundle().pathForResource("book", ofType: "pdf") {
        if let targetURL = NSURL.fileURLWithPath(path) {

            let docController = UIDocumentInteractionController(URL: targetURL)
            let url = NSURL(string:"itms-books:");

            if UIApplication.sharedApplication().canOpenURL(url!) {

                docController.presentOpenInMenuFromRect(CGRectZero, inView: self.view, animated: true)

                println("iBooks is installed")

                }else{

                println("iBooks is not installed")
            }

        }
    }

但是当我选择 iBooks 打开 pdf 时它会崩溃。谁能帮帮我!

【问题讨论】:

    标签: ios objective-c xcode swift


    【解决方案1】:

    我认为 Bojan Macele 有一个很好的答案,我使用了他的代码,我只是认为它需要一些解释。我在应用程序崩溃时也遇到了一些麻烦。只需确保 docController 在您要使用它的函数之外声明。我在我的类声明下声明了这个变量。

    import UIKit
    
    class ViewController: UIViewController {
    
        var button : UIButton?
        var docController: UIDocumentInteractionController?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            button = UIButton(frame: CGRectMake(10, 50, 100, 50))
            button?.backgroundColor = UIColor.blackColor()
            self.view.addSubview(button!)
            button?.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchDown)
    
        }
    
        func buttonPressed(sender: UIButton){
            println("button pressed")
    
    
            if let path = NSBundle.mainBundle().pathForResource("test", ofType: "pdf") {
                if let targetURL = NSURL.fileURLWithPath(path) {
                    docController = UIDocumentInteractionController(URL: targetURL)
                    let url = NSURL(string:"itms-books:");
                    if UIApplication.sharedApplication().canOpenURL(url!) {
                        docController!.presentOpenInMenuFromRect(CGRectZero, inView: self.view, animated: true)
                        println("iBooks is installed")
                    }else{
                        println("iBooks is not installed")
                    }
    
                }
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    

    所以我只是在做一个演示项目来让它工作。就是这个。它需要在函数之外声明的原因是内存管理问题。一旦程序到达 buttonPressed 的末尾,它就不再知道 docController 是什么。然后,它尝试使用非持久变量 docController 打开 iBooks,因此它崩溃了。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      试试这个:

      var docController: UIDocumentInteractionController?
      
      if let path = NSBundle.mainBundle().pathForResource("book", ofType: "pdf") {
          if let targetURL = NSURL.fileURLWithPath(path) {
      
              docController = UIDocumentInteractionController(URL: targetURL)
              let url = NSURL(string:"itms-books:");
      
              if UIApplication.sharedApplication().canOpenURL(url!) {
      
                  docController!.presentOpenInMenuFromRect(CGRectZero, inView: self.view, animated: true)
      
                  println("iBooks is installed")
      
                  }else{
      
                  println("iBooks is not installed")
              }
      
          }
      }
      

      【讨论】:

        【解决方案3】:

        斯威夫特 4.2

        // Necessary property in UIViewController class or heir. If you're want move this 
        // to another class you're needing to create an additional property for UIView/UIViewController
        var docController: UIDocumentInteractionController?
        
        // Function for opening
        func openDocument(name: String, type: String = "pdf", animated: Bool = true) {
        
          guard let path = Bundle.main.path(forResource: name, ofType: type) else { return }
        
          let targetURL = NSURL.fileURL(withPath: path)
        
          docController = UIDocumentInteractionController(url: targetURL)
          let url = NSURL(string:"itms-books:")
        
          guard UIApplication.shared.canOpenURL(url! as URL) else { return }
        
          // if the code will be not in UIView/UIViewController write here self.addedProperty2ViewController.view instead view 
          docController!.presentOpenInMenu(from: .zero, in: view, animated: animated)
        }
        

        【讨论】:

        • 您能解释一下您的解决方案在做什么吗?仅仅粘贴代码通常不是很有用。
        • 这是以前的解决方案,但对于 swift 3。我复制了以前的解决方案,之后必须更改 Swift 3 的一些方法。如果这是不好的做法,我会在你回答后删除这篇文章。顺便说一句,您可以写信给先前解决方案的作者,以便他更新帖子。
        • 谢谢。我实现了它并得到了一个“控制器过早地消失”的错误。我必须在父视图控制器中使 docController 成为变量,而不是在函数中声明它才能使其工作。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 2014-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多