以下、自分なりに調べて考えてことですが。
自信がない部分もありますので、参照は自己責任でお願いいたします。


事象

あるiOSアプリAは、 iTunes経由でファイルを取り込むことができます。
取り込んだファイルはアプリ内で複製して、ファイル検索や、閲覧などができる機能があります。

そのアプリのバージョンアップ作業をしていたのですが、
あるiOSバージョンより、ファイルや検索や閲覧ができない現象が起こることが分かりました。


原因は

いきなり原因を書きますが、
おそらくiOSのあるバージョンより、ファイルの読み込み形式・Unicode正規化形式が変わったため、起こるようになったと思ってます。


詳細1

Unicode正規化形式ですが、MacとWindowsで違うようです。

  • Mac作成したファイル形式 => NFD
  • Windowsで作成したファイル形式 => NFC


この違いは、簡単に言うと濁点文字の読み込み認識が異なるということのようです。

具体的には
NFC形式の「が」という文字を
Macでは2文字、Windowsでは1文字として認識します。
ただし、MacのFinder上ではWindowsと同じNFCで認識するような挙動が見受けられました。



Finderのファルダ名適当に「かが」としてものを作ります。そのフォルダ名をコピーして、VSCodeに貼り付ける。
=> 3文字と認識される。


*右下3selected


VSCodeから「かが」と打つ
=> 2文字と認識される。

*右下2selected




詳細2

先ほど、 > Macのファイル形式はNFD

と書きましたが、iOSでもver10.3からこのNFD形式を採用するようになったようです。
なので、10.3以前では起こらずに、これ以降で本件が発生します。

また、
アプリにiTunes経由で送ったファイルはNFC形式で送られるようです。
Windows、Macどちらで作ったファイルもNFCとなるようですが、ただ これも先ほど、 > MacのFinder上ではWindowsと同じNFCで認識するような挙動

と書いた通り、ファイルを作った時点でNFCとされており、iTunesは関係ないかもしれません。

とにかく、
iTunes経由で来たファイルをコピーしたりすると、タイトル等はNFC形式のままとなる。
iOSver10.3以降のアプリでは、文字はNFDとなるので、
もし先ほどの例の > 「かが」

など、濁点を含んだファイルを検索や閲覧しようとしても、認識されない。


対策

このままでは不便なので、
NFCの文字をNFDのように読み込むような関数が用意されている。
文字列stringValueに関して、

//objective-c
[stringValue decomposedStringWithCanonicalMapping]

//swift
stringValue.decomposedStringWithCanonicalMapping

とすれば、変換される。
「decomposedStringWithCanonicalMapping」は、NFCをNFDに修正するもの。

これらの種類には

・ NFC(正規化形式C)に変換する => precomposedStringWithCanonicalMapping
・ NFD(正規化形式D)に変換する => decomposedStringWithCanonicalMapping
・ NFKC(正規化形式KC)に変換する => precomposedStringWithCompatibilityMapping
・ NFKD(正規化形式KD)に変換する => decomposedStringWithCompatibilityMapping

がある。

今回はdecomposedStringWithCanonicalMappingを使った。

似たようなので、
decomposedStringWithCompatibilityMappingがあるが、これは全角と半角の変換も行ってしまうみたい。