0

I'm converting some code from Objective-C to Swift and I have a very simple function that reads text from a file into a string.

@implementation DecodeFile
- (NSString * _Nullable)readFile:(nonnull NSURL *)selectedFile {
    NSString *utf8 = [[NSString alloc] initWithContentsOfURL:selectedFile encoding:NSUTF8StringEncoding error:nil];
    if (utf8) { return  utf8; }
    NSString *ascii = [[NSString alloc] initWithContentsOfURL:selectedFile encoding:NSASCIIStringEncoding error:nil];
    if (ascii) { return  ascii; }
    
    return nil;
}
@end

If utf8 fails, it attempts ascii. This works perfectly fine, but my Swift implementation fails with an ASCII file that succeeds using Obj-C!

print(try? String(contentsOf: selectedFile, encoding: .utf8)) <-- nil
print(try? String(contentsOf: selectedFile, encoding: .ascii)) <-- nil

print(String(data: data, encoding: .utf8)) <-- nil
print(String(data: data, encoding: .ascii)) <-- nil

// Obj-C implementation
print(DecodeFile().read(selectedFile)) <-- WORKS

Why would this fail, and how can I get the same behaviour from Swift as Obj-C?

8
  • 2
    Don't use try?. Use try/catch and print error in the catch so you can see why it fails. Commented Jan 6 at 17:31
  • 4
    BTW - ASCII is a subset of UTF-8. If the file is ASCII, decoding as UTF-8 will succeed. Commented Jan 6 at 17:33
  • To rephrase Hangars' statement: there's no input of any text encoding which fails when trying utf8 and succeeds with ASCII. So, your statement in the title "Swift ASCII string fails, but works in Objective-C" can never happen - unless something else is badly wrong (for example, but very unlikely, the implementation of Objective-C's character encoding). Can you please provide the input? Commented Jan 6 at 18:15
  • It seems that’s exactly what’s happened. Objective-C .ascii falls back to .windowsCP1252. So when UTF fails, the ASCII also fails but falls back to WinCP. Commented Jan 6 at 23:29
  • Btw this API is only really for small scripts and fiddling around. It blocks the thread, so for a real app you should use the async file APIs instead, which you can await without blocking the thread Commented Jan 6 at 23:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.