Swift-在我的iPhone上自动将pdf文件保存到文件应用程序

Swift-在我的iPhone上自动将pdf文件保存到文件应用程序,swift,pdf,download,nsfilemanager,nsdocumentdirectory,Swift,Pdf,Download,Nsfilemanager,Nsdocumentdirectory,我急需帮助 我正在尝试创建一个应用程序,允许用户从一个链接保存pdf文件,例如我在subjectLinks数组中给出的示例,所有这些链接都指向一个pdf页面,我正在尝试下载它并将其保存在我的应用程序中。到目前为止,我已经搜索了所有地方,并找到了一种使用文件应用程序的方法,因此我在代码中所做的是下载pdf数据,并使用UIDocument和presentPreview打开它以显示它,并且我已经设法允许用户共享下载的文件并将其保存到文件中 但是,问题出现了,因为我想这样做,当用户单击“下载”时,文件会

我急需帮助

我正在尝试创建一个应用程序,允许用户从一个链接保存pdf文件,例如我在subjectLinks数组中给出的示例,所有这些链接都指向一个pdf页面,我正在尝试下载它并将其保存在我的应用程序中。到目前为止,我已经搜索了所有地方,并找到了一种使用文件应用程序的方法,因此我在代码中所做的是下载pdf数据,并使用UIDocument和presentPreview打开它以显示它,并且我已经设法允许用户共享下载的文件并将其保存到文件中

但是,问题出现了,因为我想这样做,当用户单击“下载”时,文件会自动保存到目录中的“文件”应用程序中,用户无需单击选项按钮,然后选择“保存到文件”,然后查找保存位置。这可能吗

如果不可能,至少当用户选择选项按钮并单击“保存到文件”时,它会自动创建一个单独的目录,用户可以在其中查看并保存pdf文件

我想这样做,因为在大多数情况下,当选择“保存到文件”时,“在我的iPhone上”不可用,因为没有目录或类似的文件,所以只能保存到google drive或iCloud drive,这是一个很大的不便

抱歉发了这么长的邮件。但如果有人能帮我解决问题,我将不胜感激。提前感谢您:)

注:到目前为止,我的代码中的所有内容都运行得非常好,只是我完全不知道如何实现上面概述的功能

import UIKit
import StoreKit

class TableViewController: UITableViewController {

let documentInteractionController = UIDocumentInteractionController()

let subjectLinks = ["https://pastpapers.papacambridge.com/Cambridge%20International%20Examinations%20(CIE)/AS%20and%20A%20Level/Accounting%20(9706)/2015%20Jun/9706_s15_qp_42.pdf", "https://pastpapers.papacambridge.com/Cambridge%20International%20Examinations%20(CIE)/AS%20and%20A%20Level/Economics%20(9708)/2017%20Jun/9708_s17_qp_12.pdf", "https://pastpapers.papacambridge.com/Cambridge%20International%20Examinations%20(CIE)/AS%20and%20A%20Level/Mathematics%20(9709)/2018-May-June/9709_s18_qp_12.pdf"]

override func viewDidLoad() {
    super.viewDidLoad()
    documentInteractionController.delegate = self as? UIDocumentInteractionControllerDelegate
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return subjectLinks.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    cell.textLabel?.text = subjectLinks[indexPath.row]
    return cell
}

override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
    // 1
    let shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "Download" , handler: { (action:UITableViewRowAction, indexPath: IndexPath) -> Void in
        // 2
        let downloadMenu = UIAlertController(title: nil, message: "Download this paper", preferredStyle: .actionSheet)

        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)

        downloadMenu.addAction(UIAlertAction(title: "Download", style: UIAlertActionStyle.destructive, handler: { action in self.storeAndShare(withURLString: self.subjectLinks[indexPath.row])}))
        downloadMenu.addAction(cancelAction)

        self.present(downloadMenu, animated: true, completion: nil)
    })
    // 3
    let rateAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "Rate" , handler: { (action:UITableViewRowAction, indexPath:IndexPath) -> Void in
        // 4
        let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .actionSheet)

        let appRateAction = UIAlertAction(title: "Rate", style: UIAlertActionStyle.default, handler: {action in SKStoreReviewController.requestReview()})
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)

        rateMenu.addAction(appRateAction)
        rateMenu.addAction(cancelAction)

        self.present(rateMenu, animated: true, completion: nil)
    })
    // 5
    return [shareAction,rateAction]
}

}
    extension TableViewController {
    /// This function will set all the required properties, and then provide a preview for the document
    func share(url: URL) {
        documentInteractionController.url = url
        documentInteractionController.uti = url.typeIdentifier ?? "public.data, public.content"
        documentInteractionController.name = url.localizedName ?? url.lastPathComponent
        documentInteractionController.presentPreview(animated: true)
    }

    /// This function will store your document to some temporary URL and then provide sharing, copying, printing, saving options to the user
    func storeAndShare(withURLString: String) {
        guard let url = URL(string: withURLString) else { return }
        /// START YOUR ACTIVITY INDICATOR HERE
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else { return }
            let fileManager = FileManager.default
            do {
                let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
                let fileURL = documentDirectory.appendingPathComponent("fileName.pdf")
                try data.write(to: fileURL)

                DispatchQueue.main.async {
                    self.share(url: fileURL)
                }
            } catch {
                print(error)
            }
            }.resume()
    }
}
extension TableViewController: UIDocumentInteractionControllerDelegate {
    /// If presenting atop a navigation stack, provide the navigation controller in order to animate in a manner consistent with the rest of the platform
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        guard let navVC = self.navigationController else {
            return self
        }
        return navVC
    }
}

下载任何pdf文件并自动保存在iPhone文件夹内的示例

    let urlString = "https://www.tutorialspoint.com/swift/swift_tutorial.pdf"
    let url = URL(string: urlString)
    let fileName = String((url!.lastPathComponent)) as NSString
    //Mark:  Create destination URL
    let documentsUrl:URL =  (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL?)!
    let destinationFileUrl = documentsUrl.appendingPathComponent("\(fileName)")
    //Mark: Create URL to the source file you want to download
    let fileURL = URL(string: urlString)
    let sessionConfig = URLSessionConfiguration.default
    let session = URLSession(configuration: sessionConfig)
    let request = URLRequest(url:fileURL!)
    let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
        if let tempLocalUrl = tempLocalUrl, error == nil {
            //Mark: Success
            if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                print("Successfully downloaded. Status code: \(statusCode)")
            }
            do {
                try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
                do {
                    //Mark: Show UIActivityViewController to save the downloaded file
                    let contents  = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
                    for indexx in 0..<contents.count {
                        if contents[indexx].lastPathComponent == destinationFileUrl.lastPathComponent {
                            let activityViewController = UIActivityViewController(activityItems: [contents[indexx]], applicationActivities: nil)
                            self.present(activityViewController, animated: true, completion: nil)
                        }
                    }
                }
                catch (let err) {
                    print("error: \(err)")
                }
            } catch (let writeError) {
                print("Error creating a file \(destinationFileUrl) : \(writeError)")
            }
        } else {
            print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "")")
        }
    }
    task.resume()
    
    
let urlString=”https://www.tutorialspoint.com/swift/swift_tutorial.pdf"
让url=url(字符串:urlString)
将fileName=String((url!.lastPathComponent))设为NSString
//标记:创建目标URL
让documentsUrl:URL=(FileManager.default.URL(对于:.documentDirectory,在:.userDomainMask中)。第一个作为URL?)!
让destinationFileUrl=documentsUrl.appendingPathComponent(“\(文件名)”)
//标记:创建要下载的源文件的URL
让fileURL=URL(字符串:urlString)
让sessionConfig=URLSessionConfiguration.default
let session=URLSession(配置:sessionConfig)
let request=URLRequest(url:fileURL!)
让task=session.downloadTask(带:request){(tempocalur,response,error)在
如果让templocalur=templocalur,则错误==nil{
//马克:成功
如果让statusCode=(响应为?HTTPURLResponse)?.statusCode{
打印(“已成功下载。状态代码:\(状态代码)”)
}
做{
请尝试FileManager.default.copyItem(位于:tempLocalUrl,收件人:destinationFileUrl)
做{
//标记:显示UIActivityViewController以保存下载的文件
let contents=try FileManager.default.contentsOfDirectory(位于:documentsUrl,包括属性forkeys:nil,选项:.skipsHiddenFiles)

对于0中的indexx..未经用户同意保存文件?你吓到我了。hahaha@ElTomato no别担心,它只在用户单击下载并选择保存时保存文件,它只会自动将文件保存到某个位置,用户无需选择。