SwiftUI: 読みがなを自動入力する
はじめに
iOS/macOSにはCFStringTokenizer
というものがあって、漢字をローマ字に変換できたりします。
ですが、実際にこれを用いて漢字を読みがなにしようとすると、かなり手こずります。
自作の買い物メモアプリ「マジ買う!」の開発時に実装したのですが、なんとなく動くところまでは良かったものの、ちゃんと動くまでは結構大変でした。
本記事では、そこの処理だけを取り出したサンプルアプリを紹介します。
GitHubにあげてあります。
以前の記事「SwiftUI: iOSで入力補助メニューを表示する」とあわせて見てもらえると良いかも知れません。
「マジ買う!」では、買う物マスタに表示名と読みがなの両方を持たせています。
(この読みがなも勝手に生成します。ただしiOSが読み間違えることもあるので編集できるようにしています)
買い物文字列が入力されたら、本記事の処理を用いて入力の進むつど読みがなに変換します。
そして入力した文字列での検索のほか、読みがなでも検索して候補を表示するようにしています。
動作のイメージ
サンプルアプリを動かすと、以下のように漢字を打つたびに読みがなが自動で更新されます。
打った文字を覚えておいて何かしているのではなくて、打たれている漢字を読んでいます。
「例」を打った時点では読みがなは「れい」ですが、続けて「え」を打って「例え」となった瞬間に読みがなが「たとえ」になります。
また、AIなどと違ってこの処理はローカルで動いていて外部ネットワークは使いません。
いくつか工夫した点
細かくはソースコードを見てもらえば良いのですが、いくつか工夫している点があります。
自前でローマ字をひらがなに直す
OSにローマ字→ひらがな変換をやらそうとしたんですが、どうしてもやらかすパターンが多く、それならもう自前でやるか、ということにしました。
アルファベット混在パターンをなんとかする
CFStringTokenizer
はなかなか賢くて、「エアーサロンパスex」だと「えあーさろんぱすex」なんですが「エアーサロンパスEX」と大文字にすると「えあーさろんぱすいーえっくす」と読むんですね。
ですが、「いーえっくす」は良いとして、「ex」と返されるとローマ字→ひらがなにしたときに「えx」になってしまいます。
この辺をちょっと工夫してあります。
サンプルにはテストケースも付けてあります。
いくつかこのテーマに関するテストケースが入れてあります。
読めないパターンがあるのでどうにかする
CFStringTokenizer
はだいたいの漢字を無理矢理読むんですが、ごく稀に読めない字があります。
トークンが進んでいるのに、ローマ字は空になります。進んだ以上、何かが必ず入っているだろうと思っていると失敗します。
使い方だけ簡単に
いちいちコードを読みたくないという人もいると思いますので、使い方だけ簡単に説明します。
冒頭のリポジトリから「YomiganaUtils.swift」というファイルだけ持ってきます。
そのファイルを自分のプロジェクトに入れます。
あとは読ませたい文字列を引数に「let yomigana = YomiganaUtils.getYomiganaOf(text)
」のようにするだけです。
あら簡単。
サンプルの画面のコードも簡単なんで載せておきます。
ちょっと簡単すぎますね。
struct ContentView: View {
@State var text: String = ""
@State var yomigana: String = ContentView.emptyYomiganaMessage
static let emptyYomiganaMessage = "漢字を入力するとここに読みがなが自動で入ります"
var body: some View {
Form {
Section("漢字文字列") {
TextField("文字列を入力", text: $text)
}
Section("読みがな") {
Text(yomigana)
.foregroundStyle(text.isEmpty ? .tertiary : .secondary)
}
}
.onChange(of: text) { (oldValue, newValue) in
if text.isEmpty {
yomigana = ContentView.emptyYomiganaMessage
}
else {
yomigana = YomiganaUtils.getYomiganaOf(text)
}
}
}
}
Discussion