iOS内ドキュメントがSQLite検索時にヒットしない

2014.03.11.火
技術

iOSアプリ内のドキュメントをiOSアプリ内のSQLiteで検索しようとしてヒットしない現象に見舞われたので、開発日誌ネタとして掲載します。


iOSアプリ内にドキュメントを格納、iOSアプリ内のSQLiteに当該ドキュメントのファイル名などを登録。
アプリ内でボタンがタップされた際に、SQLiteの検索処理を実行といった感じのアプリです。
SQLiteの検索処理で、ドキュメント情報を取得しようとしてましたが、上手く検索できないケースがありました。

上手く検索できないケースは、濁点等が含まれている日本語ファイル名な様子。
例えば、iOSアプリ内に『キー・ポイント.pdf』というドキュメントがあった場合。


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];

    NSFileManager *fm = [NSFileManager defaultManager];

    NSArray *list = [fm contentsOfDirectoryAtPath:docDir error:nil];

    for (NSString *path in list) {
        NSLog(@"utf8Mac = %@ UTF8String = %s", path, [path UTF8String]);
    }



こんな感じで取得したiOSドキュメントのファイル名は
utf8Mac = キー・ポイント.pdf UTF8String = „Ç≠„ɺ„ɪ„Éõ„Çö„ǧ„É≥„Éà.pdf


と表示される。

一方、
    NSString *strKeyPoint = @"キー・ポイント.pdf";
    NSLog(@"strKeyPoint = %@ UTF8String = %s", strKeyPoint, [strKeyPoint UTF8String]);


こんな感じでソース内で同じファイル名を指定した場合には、ファイル名は
strKeyPoint = キー・ポイント.pdf UTF8String = „Ç≠„ɺ„ɪ„Éù„ǧ„É≥„Éà.pdf


と表示される。

色々調べた結果、文字コードが違うのが原因だった様子。
iOSドキュメントでは、UTF8-MACという文字コードが使われているらしいのに対して、コード上で生成した文字列ではUTF-8。
わかりにくいですが、「キー・ポイント」の「ポ」らしき文字が、UTF8では濁点付き文字が『„Éù』となっているのに対して、UTF8-MACでは『„Éõ„Çö』となっています。
UTF8-MACでは濁点が2つの文字で構成されているのに対して、UTF-8では1つの文字で構成されているっぽいです。
同じ「キー・ポイント」でも中身が違っていたため、SQLiteで上手く検索できなかったようです。

解決方法としては、UTF8-MACなファイル名をコード内でUTF-8でエンコードしてやれば、期待通りになります。
    NSMutableString *strUtf8 = [NSMutableString stringWithString:strUtf8Mac];
    CFStringNormalize((CFMutableStringRef)strUtf8, kCFStringNormalizationFormC);
    NSLog(@"utf8 = %@ UTF8String = %s", strUtf8, [strUtf8 UTF8String]);


なコードで
    utf8 = キー・ポイント.pdf UTF8String = „Ç≠„ɺ„ɪ„Éù„ǧ„É≥„Éà.pdf


となり、めでたく同じ中身となりSQLiteでの検索でもヒットするようになりました。
以上、子ネタでした。