AirPrintはBonjourを話すとは限らない

!=
先日AirPrint対応のプリンタをandroidから制御してみようというエントリを起こしたのだが、これは困難なのかもしれないと思いはじめている。

無知な私はAirPrintはBonjourに対応した印字機能を持つプリンタのことを指すのではないかと勝手に思い込んでいたのだが、そうではなく、AirPrintはあくまでApple独自の特定の機器のドライバを必要といないゼロ・コンフィグレーション技術を用いたプロトコルであり、Bonjourの基礎的な技術は使用していると思われるが、AirPrint対応のプリンタがBonjourを使って全て制御できるわけではないということぽい。

ネットの情報を総合するとAirPrintで解っていることは

    • AirPrintは印字制御にインタネット印刷プロトコル(IPP)を使用する
    • AirPrintはプリンタの探索にマルチキャストDNS (mDNS)を使用する
    • AirPrintサービスタイプとして"_ipp"のサブタイプである"_universal"を使用する
    • AirPrintプリンタの情報を取得するために追加のテキストレコード"URF"を必要とする

この辺位。

用途としては同じ「ゼロ・コンフィグレーション」であってもAirPrintはBonjourとは違い、コミュニティに対して詳細な仕様は公開されておらず※、androidからAirPrintプロトコルを操作するソフトウェアは公開されていない。

上記の情報を見る限りでは、Boujourを使ってプリンタをネットワークにサービスとして登録し、プリンタを使う側は同じくBonjourを使って探索、発見して、IPPプロトコルを使ってプリンタとお話すれば良いように思えるが、非公開である以上、推測でしかない。

※ 他の仕様と同様にAppleNDAを締結したベンダーにのみ公開されていると思われる。

Personal Media eXchange


Personal Media eXchange - Google Play の Android アプリ

Personal Media eXchange(以下、PMX)は、NTTドコモのモバイルWi-Fiルーター「BF-01D」に対応し、モバイルWi-Fiルーターのインターネット接続状態や、バッテリー残量が一目で分かるほか、基本的な設定などが行なえるアプリです。
手元のAndroid端末にアプリをインストールすれば、モバイルWi-Fiルーターを鞄や、ポケット等に入れたまま、手軽に状態確認や、基本設定の変更、内蔵メモリのファイル閲覧ができます。

こんなアプリがあったなんて全然知らなかった。
くだらないショートメッセージ飛ばして来る位なら、こういう情報を送ってくださいな。

AirPrintとandroid

AirPrint対応のプリンタを買う予定なのだが、MacやiOSから普通に使えるのは当たり前として、androidからも同様にアクセスしたい。そのためのアプリがあるであろうことは想像がつくのだが、折角なので自力でやってみたいのだ。

1. 環境の準備

開発環境は整っているのであとはデバイスつまりAirPrintに対応したプリンタをとっとと用意すればいいことなのだが、財政事情もあり実際に買うのは夏以降になりそうなので、それまではプリンタを買わずに環境を用意したい。

聞いたところではWindows上でiTunes共有を有効にした場合、Bonjour※サービスとして登録されるそうなのでそれを使っても良いのだが、できれば想定しているプリンタを使いたいところだ。

2. Printer Simulator


開発環境としてXcodeをインストールしていれば、iPhoneシミュレータがインストールされているはずだが、実はそれと一緒にプリンタシミュレータがインストールされている。


これを起動するとこのように5つの仮想プリンタデバイスがシステムに登録される


それぞれの仮想プリンタは全てBonjourサービスとして登録されているので、これをテストに使うことにする。


このようにiOSシミュレータからはプリンタとして見える。(実際に印刷もできる)

次回はandroidからこのプリンタを探索(ディスカバリ)するコードをテストしてみよう。

Bonjour とはAppleが開発したゼロ・コンフィギュレーション技術の実装。LANにおいて、何の設定も行わず機器を使用可能にすることができる。AirPrintもこのBonjourサービスの上で動作することを前提としている。

ハイパーコンセプションタイム

突然だが、人間には思考が通常時よりも段違いに効率よく行われる時があり、それには特定の行動パターンが影響しているように思う。
そのような超思考の時間を仮に「ハイパーコンセプションタイム」と呼ぶことにしよう。

例えば私の場合、ハイパーコンセプションタイムが訪れるのは帰宅してシャワーを浴びている時である。
髪を洗う際にはシャンプーを手に取り髪に馴染ませ、一旦流してもう一度シャンプーを手に取り、今度はしっかりと頭皮を洗い、その後コンディショナーを付けて丹念にすすぐ。

この一連の動作のために私の上半身はかかり切りであり、身体全体はとても忙しいはずなのだが、その時脳はシャンプーことなどは一切考えておらず、例えば今日発生したバグの原因が何かとか、明日の会議でプレゼンする内容とか、次に開発するサービスのアイディアなどをすさまじい勢いで考えていることが多い。良い解決策やアイディアが浮かぶのは大抵このときだ。同じような体験は通勤路を早足で歩いている時にも起こる。

この時考えごとをしている頭の回転の良さたるや、どんなに仕事に集中している時でもちょっと到達できない次元なのである。

思うに、髪を洗う動作や歯を磨く動作等の体が完全に覚え込んでルーチンワークと化した作業を行う場合、大脳皮質のいわゆる「運動連合野」は活動しているのだが、論理的な事を考えるとされている「前頭連合野」は殆どフリーの状態であり、そこから更に思考能力を押し上げるなんらかの秘密があり、これがハイパーコンセプションタイム状態を作り出しているのではないかと思うのだ。

この辺の事を真面目に研究した論文や読み物が無いかなと探しているのだが、中々見つからない。

REkit

zuccoi/REKit · GitHub

REkitはMac/iOSのFoundationクラスであるNSObjectを拡張するカテゴリで提供されており、Objective-Cの動的な機能とBlocksを活用して、Objective-Cのイディオムを拡張することができる。

  • REResponder

オブジェクトインスタンスのメソッドをランタイムにBlockで記述した内容に置き換えることができる。

  • REObserver

従来からあるKVOの機能をBlocksを使い、より簡単に書くことができる。

両者とも非常に強力で動的な機能をobjective-Cプログラマが享受できるが、特に前者のREResponderは上手く使うとAOPのように関心事をロジックから切り離すことができたり、モックやプロキシなどを生成したりと使い道次第で様々な用途に使えるのではないだろうか。

ちなみにREADMEを見ると解るが、REkitの開発者はKazki Miura氏つまり日本の方である。

OCUnitテストターゲットにて"ld: file not found"でビルドできない

ld: file not found: /Users/kazz/Library/Developer/Xcode/DerivedData/プロダクト名-eiottghqglskmzegzcmbbdbkgyhh/Build/Products/Debug-iphonesimulator/プロダクト名.app/プロダクト名
clang: error: linker command failed with exit code 1 (use -v to see invocation)

古いプロジェクトを引っ張りだして来てOCUnitテストをしようとしたらビルドが通らない。

こんな時はプロジェクトのアプリケーションターゲットとテストプロジェクトで矛盾が起きていることが多い。

具体的には、テストターゲットのBuild Setting中のBundle Loaderパラメタの値がアプリケーションターゲットのProduct Nameと矛盾しているのが原因だ。

プロジェクトを作成した後にプロダクト名を変更したりすると、なぜかハードコードされているこのパラメタはテストターゲットの設定だけが古いままになり、整合性が取れなくなってしまうことがあるのだ。

こんなことで午前中潰してしまった。とほほほ。

iOS6.0以降、GCDの'dispatch_release'はARC環境では使えない

以前GCD(Grand Central Dispatch)のエントリを書いた時に

dispatch_release(group)
グループは有限のリソースのため、使用が終わったら必ず解放する必要がある。(ARCの影響を受けないことに注意)

と書いたが、iOS 6.1のプロジェクトを新たに作成して以前のコードを取り込んだ所、以下のエラーでコンパイルが通らない

'release' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'release'

どうやらiOS6.0以降扱いが変わったらしい。
今までエラーになっていなかったのはXcodeにて"iOS Deplyment Target"を5.xにしていたために、後方互換性が働いていたのだろう。