きりかノート 3冊め

おあそびプログラミング

第66回 Cocoa勉強会に行ってきた(6/14)

会場はいつもの新宿伊藤ビルの貸し会議室

以下発表など。内容的なことは勉強会のサイトのほうにレポートを書いたので、こちらは感想とか主観メインで。

発表「LightBlue Bean」(gadget)

BLE(Bluetooth Low Energy)で接続できる、いろんなセンサーついてる、Arduinoなどのフリスクサイズのデバイス。きょうびこの手のってすげえ小さくなってるよねえ。

当初の予定よりすごい遅れて勉強会の当日にSDKが公開されたんだけど、Objective-CAPIになってちょっとおどろき。Cの関数だけ並んでると思ってたよ。
あとで開発会社のWebサイト見たら、開発かかわってたらしいpopSLATEAPIのとこも"Coming soon!"て書かれててちょっと笑ってしまった。

発表「iOSアプリの署名」(iOS)

アプリのビルドと署名の分割について。去年の12月の続き。

iOSアプリぜんぜんやってないから理屈で考えつつ聞いてた。ふだんXcodeいっぱつでできるのは簡単で良いけど、逆に隠蔽されてて融通きかないところもあるよね。

発表「OS Xの画面開発」(Mac)

storyboardの話。既存のアプリでViewControllerに手を入れまくってるから、いまさらレスポンダーチェーンに入れられても困る、という参加者の意見にもなるほど。まあでも新規アプリでしか使わんよね。

発表「irMagician」(gadget)

MacやPCなど別機器からの指示を受けてIRリモコンになるirMagicianの話。

発表者の他のユーザからオプションパーツのリクエストが出たりと、「開発してるなあ」と本質的でないとこで感心してしまったり。

発表「Swift」(swift)

Appleの新言語、swiftについて。発表者が自分用にplaygroundで試しつつ作ったという、大ボリュームのスライドを見ながらみんなであれこれ。

C++からObjcive-Cに来た人と、Rubyから来た自分でけっこう感じ方がちがうなあと思った。自分としては「実行速度を言語でとりにきたか」というのが第一印象。WWDCのちょっと前にrustについてちょっと調べてたのもあるけれど。

次回の予定

8/2に開催予定です。

RubyCocoa 文字列のエンコーディング (続き)

先週の続き。

試しながら考えたや課題など。

st_tableによる変換表

Rubyのencoding indexとCFStringEncodingはどちもintなので特に問題なく。

これは「同じエンコーディングは同じ符号化(バイト列)」であることを前提にしてるので、RubyUTF-8-MacUTF-8にしてからCFStringに渡す、ということはできない。これを実現したい場合、入力エンコーディングに対して

といった情報をHashなどで持たせるような変換表にする必要があるだろう。このようにするべきかどうかは結論がでてない。

また、Rubyエンコーディングは拡張ライブラリ(?)になっていて必要なときに読み込みするようになっているので、最低限の変換表(ASCII-8BIT, UTF-8)だけ初期登録しておいて、あとは実行時に追加していくのが良いと思う。(そうしないとindexがわかっていても、エンコーディング本体がロードされてなくて妙な動作をしたりする。)ただこの「実行時に追加」をどうするのかが考えどころ。

名前(char *)の変換表を内部的に持つあたりかなあ。ということで次へ。

名前によるエンコーディング変換

RubyもCFStringも「エンコーディングの名前」を持っているので、これを使えばよいのでは?と試してみた。

CFStringEncodingで使えそうなのは、

  • IANA charset名 (CFStringConvertEncodingToIANACharSetName)
  • Windowsコードページ (CFStringConvertEncodingToWindowsCodepage)

あたり。IANAでない名前を取ることはできる(CFStringGetNameOfEncoding)けれど、名前から引くことはできないので除外。

RubyのEncodingで使えそうなのは

  • 名前 (Encoding#name)

あたり。RubyのEncodingは名前を複数持てるんだけど、Rubyのメソッドを通さないと拡張ライブラリからはひとつめ名称にしかアクセスできないっぽい。

で、とりあえずIANA charset名と名前で引けたものは自動的に変換テーブルに登録していくってのをやってみたんだけどうまくいかない。UTF-16がどうもうまくない。

NSString|CFStringは、Rubyの文字列とちがってある文字列を特定のエンコーディングとして認識しているのではなく、Cのバイト列との相互変換のときにエンコーディングを都度指定するようになっている。NSStringのインスタンスに対しては

  • fastestEncoding: バイト列にするときに時間がかからないもの。
  • smallestEncoding: バイト列にしたときそのサイズが小さいもの。
  • canBeConvertedToEncoding: 情報のロスなしに指定のエンコーディングに変換可能か。

などを問い合わせることができる。

この「エンコーディングそのものを持ってない。目的に応じて使えるエンコーディングを問い合わせることができる」てのがくせ者で、UTF-8で生成した文字列が、fastestEncodingでは(BEでもLEでもない)UTF-16を返すということがある。するとRuby側からUTF-8で渡した文字列がObjCから帰ってくるときにUTF-16になってしまう。これはNSString|CFStringの仕様的にどうにもならんのだけど気持ち悪い。

きょうびUTF-8がほとんどだと思うので、CFString(UTF-16)→Ruby Stringの場合はUTF-8に変換しちゃうほうがよいかもしれない。

変換できないエンコーディング

とりあえずUTF-8試してだめならバイト列という対応。internalやexternalというものがRubyにはあるので、それ使うほうがいいんじゃ?とも思ったけど、そのエンコーディングが変換可能なものかは実行時にならないとわからないのであまり良くないかなあと。

だいぶ(元の意味でも誤用の意味でも)煮詰まってきたので、ちょっと置いて今週は別の作業するつもり。