Hi, I'm encountering a weird issue on iOS that happens:
- for files with diacritics in their name, like "Gòmez.pdf" or "Télé.mp4",
- when the iPhone or iPad main language is not set to English,
- if the file has been created with a relatively low-level Unix function like
fopen()orcopyfile().
Then, the file cannot be previsualized using QuickLook or opened using other apps. Most of the time it fails silently, but on some occasions I get the following error message: "You do not have permission to save the file "filename.pdf" in the folder "myFolder"".
The issue is present in, at least, iOS 16 and 26. It seems worse in iOS 26. It seems that all three conditions are required, I don't see the issue when the iPhone or iPad is set to use English as the main language. I also don't see the issue if I rename the files in the Files app.
I'm probably doing something wrong, but what can it be?
(it's kind of weird that my recommendation for users becomes: if you want to use international characters in your file names, you need to set the iPad language to English...)
Thanks for that info.
Based on that, I created a small test project to exercise my normalisation theory:
- Using Xcode 26.3 on macOS 26.2, I created a new project.
- I added
LSSupportsOpeningDocumentsInPlaceandUIFileSharingEnabledto itsInfo.plist[1]. - I wired up a button to my test code, which I’ve pasted in at the end of this reply.
- I ran the app on an iOS 26.2 device.
- I tapped my test button. It was able to create the files.
- I switched to the Files app.
- And navigated to On My iPhone > My App Name.
- I tapped
test, thentest dec (naïve), thentest pre (naïve). The first two worked; the last one failed as you described.
The difference between these file names is that the test dec (naïve) uses a decomposed ï (NFD) whereas test pre (naïve) uses a precomposed one (NFC). Clearly, that’s causing problems for Quick Look in the Files app and elsewhere.
So, there are two things for you to do here:
- Please file a bug against iOS about this. It should be able to handle both normal forms equivalently. Once you’re done, post your bug number here and I’ll add my own comments to it.
- In your app, you should be able to work around this by decomposing the paths that you pass to the low-level code that’s creating these files.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] I suspect that the latter is unnecessary, but I added it first and couldn’t be bothered removing it.
do {
let docDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
print("will create")
let content = Data("Hello Cruel World! \(Date.now)".utf8)
func writeContent(to name: String) throws {
var path = [UInt8](docDir.path.utf8)
path.append(UInt8(ascii: "/"))
path.append(contentsOf: name.utf8)
try content.withUnsafeBytes { buf in
let fd = path.withUnsafeBytes { pathBuf in
open(pathBuf.baseAddress!.assumingMemoryBound(to: CChar.self), O_CREAT | O_WRONLY, 0o666)
}
guard fd >= 0 else {
throw Errno(rawValue: errno)
}
defer { _ = close(fd) }
let ok = write(fd, buf.baseAddress!, buf.count) >= 0
if !ok {
throw Errno(rawValue: errno)
}
}
}
try writeContent(to: "test.txt")
try writeContent(to: "test pre (na\u{ef}ve).txt")
try writeContent(to: "test dec (nai\u{308}ve).txt")
print("did create")
} catch {
print("did not create, error: \(error)")
}