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

Swift中NSData第二次无法访问文件及邮件附件添加问题

Fixing the Second-Time File Access Issue with NSData & MFMailComposeViewController

Hey there, let's break down why you're running into trouble accessing that PDF file the second time around, and how to fix it.

First off, a couple of red flags in your current code that might be causing the issue:

  • Manual string-based path concatenation (newDir+"/file.pdf") is error-prone—you might end up with invalid paths (like duplicate slashes) without realizing it.
  • Using NSData(contentsOfFile:) gives you no visibility into why the read failed on the second attempt (it just returns nil silently).

Here's how to resolve this step by step:

1. Ditch String Paths—Use URLs Instead

URLs are the safe, recommended way to handle file paths in iOS. They automatically handle path separators and avoid common string concatenation mistakes:

let filemgr = FileManager.default
let dirPaths = filemgr.urls(for: .documentDirectory, in: .userDomainMask)
let docsURL = dirPaths[0]

// Build folder and file URLs properly
let folderURL = docsURL.appendingPathComponent("folder")
let fileURL = folderURL.appendingPathComponent("file.pdf")

2. Use Swift's Data with Error Handling

Instead of NSData, use Swift's native Data type with a do/catch block. This will tell you exactly why the file read fails (e.g., file missing, permission issues):

// Initialize your mail controller (create a fresh instance for each email attempt)
let mail = MFMailComposeViewController()

do {
    let fileData = try Data(contentsOf: fileURL)
    // Add the attachment with correct MIME type
    mail.addAttachmentData(fileData, mimeType: "application/pdf", fileName: "file.pdf")
} catch {
    // Debug the error to find the root cause
    print("Failed to read PDF file: \(error.localizedDescription)")
    
    // Add extra checks to diagnose further
    if !filemgr.fileExists(atPath: fileURL.path) {
        print("Error: File does NOT exist at \(fileURL.path)")
    }
    if !filemgr.isReadableFile(atPath: fileURL.path) {
        print("Error: File exists but isn't readable (permission issue?)")
    }
}

3. Check for Hidden File Changes

If the first read works but the second doesn't, ask yourself:

  • Is any other code deleting/moving the PDF file after the first access?
  • Are you reusing the same MFMailComposeViewController instance instead of creating a new one for each email attempt? (It's best to create a fresh instance every time you need to send mail.)

4. Verify Folder Existence

Make sure the "folder" directory actually exists before trying to access the file. If it's created dynamically, add a check:

if !filemgr.fileExists(atPath: folderURL.path) {
    do {
        try filemgr.createDirectory(at: folderURL, withIntermediateDirectories: true)
    } catch {
        print("Failed to create folder: \(error)")
    }
}

By switching to URLs and adding proper error handling, you'll either fix the issue immediately or get a clear error message that points to the real problem (like a missing file or permission error).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:01:29