Home > Back-end >  How do I deal with the String.Encoding initializer never failing?
How do I deal with the String.Encoding initializer never failing?

Time:06-30

if let encoding = String.Encoding(rawValue: 999) {
  // ...
}

Produces a compiler error saying "Initializer for conditional binding must have Optional type, not 'String.Encoding'" because despite the docs saying the String.Encoding initializer is failable, it is not and will happily create non-existent encodings.

How do I check if the encoding returned by initializer is an actual encoding?

The two ideas I have are

  1. Check the String.Encoding description is not empty. This assumes that supported encodings must have a description
  2. Encode something - e.g. "abc".data(using: encoding) == nil - which assumes that the string "abc" can be encoded by all supported encodings

CodePudding user response:

The documentation is misleading, String.Encoding has a non-failable

 public init(rawValue: UInt)

initializer. A list of all valid string encodings is String.availableStringEncodings, so you can use that to check the validity:

let encoding = String.Encoding(rawValue: 999)
print(String.availableStringEncodings.contains(encoding)) // false

CodePudding user response:

You can use CoreFoundation's CFStringIsEncodingAvailable() function to check if the encoding is valid, and also if it can be used on that particular device.

However, as MartiR pointed out, CFStringIsEncodingAvailable needs a CFStringEncoding to work with, so the String.Encoding needs to be converted first to a CF one.

let encoding = String.Encoding(rawValue: 999)
let cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding.rawValue)

if CFStringIsEncodingAvailable(cfEncoding) {
  // ...
}

, or, as MartinR nicely suggested, the result of CFStringConvertNSStringEncodingToEncoding can also be used:

if CFStringConvertNSStringEncodingToEncoding(encoding.rawValue) != kCFStringEncodingInvalidId {
  // ...
}
  • Related