FTP is fundamentally broken at the protocol level. You won’t be able to make non-ASCII file names work with FTP in the general case. I talk about FTP’s brokenness in detail in On FTP.
The issue you’re hitting is almost certainly related to normalisation. Back when I spent more time on file system stuff I wrote a couple of Q&As about this:
Sadly, while these are useful background, the specific advice they contain in quite naïve. These days I’m not convinced there is a good solution to this problem.
Foundation has a tendency — it’s debatable as to whether it’s a good or a bad thing — to convert file system path strings to their decomposed form. That behaviour originated in the days of HFS Plus, where the file system decomposed all file names.
Consider this small program:
import Foundation
func main() {
let u1 = URL(fileURLWithPath: "/na\u{00ef}ve")
let u2 = URL(fileURLWithPath: "/nai\u{0308}ve")
let u3 = URL(string: "file:///na\u{00ef}ve")!
let u4 = URL(string: "file:///nai\u{0308}ve")!
print((Data(u1.path.utf8) as NSData).debugDescription)
print((Data(u2.path.utf8) as NSData).debugDescription)
print((Data(u4.path.utf8) as NSData).debugDescription)
print((Data(u3.path.utf8) as NSData).debugDescription)
}
main()
It prints:
<2f6e6169 cc887665>
<2f6e6169 cc887665>
<2f6e6169 cc887665>
<2f6e61c3 af7665>
Note that, when using init(fileURLWithPath:)
, both the pre- and decomposed paths result in a decomposed path.
IIRC the FTP VFS plug-in is normalisation sensitive, so it finds the file if you give it the precomposed name but not if you give it the decomposed one.
As to how you get around this… sheesh… if I were in your shoes I just wouldn’t. There’s no point investing time in FTP. Moreover, this isn’t just about your time now: Any fix is going to complicate your ongoing maintenance.
If you really want to spend the time, it’s still tricky to fix. The problem is that the name might contain both pre- and decomposed sequences, so you can’t just convert the string to precomposed and retry with that. You’d have to iterate the parent directory and look through the results with a normalisation-insensitive match. And there are two problems with that:
-
The path to the directory might contain precomposed sequences, so you might need to recursively apply this process up the tree.
-
There might be multiple matches. A normalisation-insensitive file system can contain both na\u{00ef}ve
and nai\u{0308}ve
. If you find multiple matches, which one is correct?
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"