Swift Use Unicode Character in Localization.Strings

Swift use unicode character in localization.strings

You have to follow localization.strings's unicode format, e.g.:

"your-key" = "\UF071";

iOS Localization: Unicode character escape sequences, which have the form '\uxxxx' does not work

NSString literals and strings-files use different escaping rules.

NSString literals use the same escape sequences as "normal" C-strings, in particular
the "universal character names" defined in the C99 standard:

\unnnn      - the character whose four-digit short identifier is nnnn
\Unnnnnnnn - the character whose eight-digit short identifier is nnnnnnnn

Example:

NSString *string = @"Espa\u00F1ol - \U0001F600"; // Español - br>

Strings-files, on the other hand, use \Unnnn to denote a UTF-16 character,
and "UTF-16 surrogate pairs" for characters > U+FFFF:

"spanish-key" = "Espa\U00f1ol - \Ud83d\Ude00";

(This is the escaping used in "old style property lists", which you can see when printing
the description of an `NSDictionary.)

This (hopefully) answers your question

When to use "\Uxxxx" and "\uxxxx"?

But: As also noted by @gnasher729 in his answer, there is no need to use Unicode
escape sequences at all. You can simply insert the Unicode characters itself,
both in NSString literals and in strings-files:

NSString *string = @"Español - ;

"spanish-key" = "Español - ;

What is the meaning of 'Swift are Unicode correct and locale insensitive' in Swift's String document?

To expand on @matt's answer a little:

The Unicode Consortium maintains certain standards for interoperation of data, and one of the most well-known standards is the Unicode string standard. This standard defines a huge list of characters and their properties, along with rules for how those characters interact with one another. (Like Matt notes: letters, emoji, combining characters [letters with diacritics, like é, etc.)

Swift strings being "Unicode-correct" means that Swift strings conform to this Unicode standard, offering the same characters, rules, and interactions as any other string implementation which conforms to the same standard. These days, being the main standard that many string implementations already conform to, this largely means that Swift strings will "just work" the way that you expect.

However, along with the character definitions, Unicode also defines many rules for how to perform certain common string actions, such as uppercasing and lowercasing strings, or sorting them. These rules can be very specific, and in many cases, depend entirely on context (e.g., the locale, or the language and region the text might belong to, or be displayed in). For instance:

  • Case conversion:
    • In English, the uppercase form of i ("LATIN SMALL LETTER I" in Unicode) is I ("LATIN CAPITAL LETTER I"), and vice versa
    • In Turkish, however, the uppercase form of i is actually İ ("LATIN CAPITAL LETTER I WITH DOT ABOVE"), and the lowercase form of I ("LATIN CAPITAL LETTER I") is ı ("LATIN SMALL LETTER DOTLESS I")
  • Collation (sorting):
    • In English, the letter Å ("LATIN CAPITAL LETTER A WITH RING ABOVE") is largely considered the same as the letter A ("LATIN CAPITAL LETTER A"), just with a modifier on it. Sorted in a list, words starting with Å would appear along with other A words, but before B words
    • In certain Scandinavian languages, however, Å is its own letter, distinct from A. In Danish and Norwegian, Å comes at the end of the alphabet: ... X, Y, Z, Æ, Ø, Å. In Swedish and Finnish, the alphabet ends with: ... X, Y, Z, Å, Ä, Ö. For these languages, words starting with Å would come after Z words in a list

In order to perform many string operations in a way that makes sense to users in various languages, those operations need to be performed within the context of their language and locale.

In the context of the documentation's description, "locale-insensitive" means that Swift strings do not offer locale-specific rules like these, and default to Unicode's default case conversion, case folding, and collation rules (effectively: English). So, in contexts where correct handling of these are needed (e.g. you are writing a localized app), you'll want to use the Foundation extensions to String methods which do take a Locale for correct handling:

  • localizedUppercase/uppercased(with locale: Locale?) over just uppercased()
  • localizedLowercase/lowercased(with locale: Locale?) over just lowercased()
  • localizedStandardCompare(_:)/compare(_:options:range:locale:) over just <

among others.

Localizable.strings with special characters

Why don't you ask the person to give the localized strings file with proper values not what you have currently in unicodes:

Say the file should contain this:

"m3h" = "m³/h";

Detect when a unicode character cannot be displayed correctly

You can use CTFontGetGlyphsForCharacters() to determine if a font has a glyph for a particular code point (note that supplementary characters need to be checked as surrogate pairs):

CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica"), 12, NULL);
const UniChar code_point[] = { 0xD83C, 0xDCA1 }; // U+1F0A1
CGGlyph glyph[] = { 0, 0 };
bool has_glyph = CTFontGetGlyphsForCharacters(font, code_point, glyph, 2);

Or, in Swift:

let font = CTFontCreateWithName("Helvetica", 12, nil)
var code_point: [UniChar] = [0xD83C, 0xDCA1]
var glyphs: [CGGlyph] = [0, 0]
let has_glyph = CTFontGetGlyphsForCharacters(font, &code_point, &glyph, 2)

If you want to check the complete set of fallback fonts that the system will try to load a glyph from, you will need to check all of the fonts returned by CTFontCopyDefaultCascadeListForLanguages(). Check the answer to this question for information on how the fallback font list is created.



Related Topics



Leave a reply



Submit