You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift实现文档目录PDF预览及UIViewController邮件发送方案咨询

Solution: Preview PDF & Send Email in Swift UIViewController

Let’s break this down step by step—first accessing your PDF in the Documents directory, then previewing it in a view controller, and finally integrating email sending with the preview workflow.

1. Accessing the PDF in the Documents Directory

First, you need a reliable way to locate your saved PDF file. Here’s how to retrieve the Documents directory path and target your specific PDF:

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

// Replace "Order.pdf" with your actual PDF filename
func getOrderPDFURL() -> URL? {
    let docsDir = getDocumentsDirectory()
    return docsDir.appendingPathComponent("Order.pdf")
}

Always add a check to confirm the file exists before proceeding:

if let pdfURL = getOrderPDFURL(), FileManager.default.fileExists(atPath: pdfURL.path) {
    // PDF exists—proceed to load/preview
} else {
    // Handle missing PDF error
}

2. Previewing the PDF in a UIViewController

The modern, native way to preview PDFs on iOS is using PDFKit (available from iOS 11 onwards). Here’s a complete view controller implementation:

Step 1: Import Required Frameworks

Add these imports at the top of your file:

import UIKit
import PDFKit

Step 2: Build the Preview View Controller

class PDFPreviewViewController: UIViewController {
    
    private var pdfView: PDFView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupPDFView()
        loadPDF()
        addSendEmailButton() // Add this to trigger email later
    }
    
    private func setupPDFView() {
        pdfView = PDFView()
        pdfView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(pdfView)
        
        // Make the PDF view fill the entire screen
        NSLayoutConstraint.activate([
            pdfView.topAnchor.constraint(equalTo: view.topAnchor),
            pdfView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            pdfView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            pdfView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
        
        // Configure user-friendly settings
        pdfView.displayMode = .singlePageContinuous
        pdfView.autoScales = true
        pdfView.backgroundColor = .white
    }
    
    private func loadPDF() {
        guard let pdfURL = getOrderPDFURL(), FileManager.default.fileExists(atPath: pdfURL.path) else {
            showErrorAlert(message: "Order PDF not found in documents directory")
            return
        }
        
        if let pdfDocument = PDFDocument(url: pdfURL) {
            pdfView.document = pdfDocument
        } else {
            showErrorAlert(message: "Failed to load the PDF file")
        }
    }
    
    // Helper to show error alerts
    private func showErrorAlert(message: String) {
        let alert = UIAlertController(title: "Oops", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
    
    // Reuse the directory helper functions from section 1
    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
    
    func getOrderPDFURL() -> URL? {
        let docsDir = getDocumentsDirectory()
        return docsDir.appendingPathComponent("Order.pdf")
    }
}

3. Adding Email Sending Functionality

To send the PDF via email, use MFMailComposeViewController. Integrate this into your preview view controller:

Step 1: Import MessageUI

Add this import to your file:

import MessageUI

Step 2: Add Send Button & Email Composer

Add these functions to your PDFPreviewViewController:

private func addSendEmailButton() {
    let sendButton = UIBarButtonItem(title: "Send Order", style: .done, target: self, action: #selector(sendEmailTapped))
    navigationItem.rightBarButtonItem = sendButton
}

@objc private func sendEmailTapped() {
    guard MFMailComposeViewController.canSendMail() else {
        showErrorAlert(message: "Email is not configured on this device")
        return
    }
    
    guard let pdfURL = getOrderPDFURL(), let pdfData = try? Data(contentsOf: pdfURL) else {
        showErrorAlert(message: "Could not attach the order PDF")
        return
    }
    
    let mailComposer = MFMailComposeViewController()
    mailComposer.mailComposeDelegate = self
    
    // Customize your email content
    mailComposer.setSubject("Your Order Confirmation")
    mailComposer.setMessageBody("Please find your order details attached below.", isHTML: false)
    
    // Attach the PDF file
    mailComposer.addAttachmentData(pdfData, mimeType: "application/pdf", fileName: "Order.pdf")
    
    present(mailComposer, animated: true)
}

Step 3: Handle Email Composer Dismissal

Add this extension to conform to the mail delegate:

extension PDFPreviewViewController: MFMailComposeViewControllerDelegate {
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true)
        
        // Give user feedback based on result
        switch result {
        case .sent:
            let successAlert = UIAlertController(title: "Success", message: "Order email sent!", preferredStyle: .alert)
            successAlert.addAction(UIAlertAction(title: "OK", style: .default))
            present(successAlert, animated: true)
        case .failed:
            showErrorAlert(message: "Failed to send email: \(error?.localizedDescription ?? "Unknown error")")
        case .saved:
            let savedAlert = UIAlertController(title: "Saved", message: "Email saved to drafts", preferredStyle: .alert)
            savedAlert.addAction(UIAlertAction(title: "OK", style: .default))
            present(savedAlert, animated: true)
        default:
            break // No action needed for cancelled emails
        }
    }
}

Key Tips

  • PDFKit vs WKWebView: PDFKit is purpose-built for PDFs (supports zoom, page navigation, and annotations), making it the better choice for native PDF previews. WKWebView works too but lacks PDF-specific features.
  • Error Handling: Always validate file existence and email configuration to avoid crashes and improve user experience.
  • Testing: When testing email functionality, use a real device (simulators don’t support email sending).

内容的提问来源于stack exchange,提问作者Bob Mehr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 23:57:44