Swift中NSData第二次无法访问文件及邮件附件添加问题
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 returnsnilsilently).
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
MFMailComposeViewControllerinstance 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

