HMDT Blog | ページ 10

iOSでは何故responder chainは重要でないのか


最近はOS Xプログラミングもよくやっているんだけど、iOSではあまり気にしないけど、OS Xではとっても意識するものは、responder chainですね。responder chainについては、Appleのドキュメント「Event Delivery: The Responder Chain」を参照してください。または、昔に書いた「ダイナミックObjective-C (89) デザインパターンをObjective-Cで – Chain of Responsibility (1)」もあわせてどうぞ。

どういうものかというと、普通iOSでボタンにターゲットとアクション設定するときは、addTarget:action:forControlEvents:を使うでしょ。このとき、ターゲットとなる第一引数に特定のオブジェクトじゃなくて、nilを指定します。そうすると、ボタンを押したときのアクションは、そのイベントを受け取ってくれる人(actionに対応するメソッドを持っている人)まで数珠つなぎに送られていくのです。これが、反応の連鎖をたどる、ということでresponder chainって呼ばれます。

OS Xプログラミングをやっていると、このresponder chainをとてもよく使うんですよ。なんでかなと考えてみると、OS Xで何らかの操作を行うときは、まず対象をマウスで選択して、メニューからコマンドを実行する、という流れになります。このとき、操作対象とメニューのコマンドには、強い結びつきがないんですね。たとえば、コピーというコマンドは、いろんな対象に対して送られる可能性があります。

それに対してiOSでは、多くの場合1つのタッチ操作で、対象の選択とコマンドの実行を実現しています。つまり、対象とコマンドが一対一関係ですね。その方が直感的でよろしいです。でも、機能が多くなってくると、「対象×コマンド」の数だけボタンを用意しなくてはいけないので、無理が出てくるんですよね。

ということで、マウス/キーボードのインタフェースと、タッチのインタフェースとでは、自ずとイベントハンドリングのプログラミングスタイルが変わってくるんです、という話でした。

OS Xファーストの開発スタイル


去年の末から、うちの会社では、「OS Xファースト」のスタイルで開発するものが増えました。開発するときに、まずOS Xで動かす。その後で、iOSに移植する、というやり方です。これがねぇ、とてもいいんですよ。

このスタイルになった一番の理由は、ドキュメント・ベース・アプリケーションのものが増えたからです。書類を作成するタイプのアプリ、つまりはエディタタイプのものですね。エディタものをiOSで作ろうとすると、色々面倒なんですよ。というより、OS Xの方が圧倒的にエディタに向いているんです。理由は以下の通りです。

標準のファイルブラウザが使える

OS Xには、ファイルシステムに存在するファイルを確認および操作するファイルブラウザがあります。何の事はない、Finderのことですね。忘れがちですが、iOSにはFinderに相当するものがありません。

エディタアプリだと、書類を作成するんです。そうすると、ファイルの確認や操作が必要になるんですよ。OS XだったらFinderでひょいっとのぞけばおしまいなんですが、iOSだとソースコード書き連ねてアプリ側でやらないといけない。メンドクサイ。

あと、オープンダイアログ。OS Xには標準のオープンダイアログがありますが、iOSにはないんです。だから、まず始めにオープンダイアログを自作しないといけない。超メンドクサイ。

プルダウンメニューが使える

エディタアプリは、どうしても操作のためのコマンドが多くなります。これは複雑というよりは、単に求められるものが多いんですね。たとえば、アンドゥでしょ、リドゥでしょ、カットにコピーにペーストでしょ、削除でしょ、すべてを選択でしょ…。これらをボタンとして並べていったら、iPhoneの画面がそれだけでいっぱいになってしまいます。そうならないために色々とUIを考えるんですけど、そっちにやたら時間を取られるんですよ。

でもこれがOS Xならば!プルダウンメニューがあるじゃないか!プルダウンメニューの素晴らしいところは、プルダウンできるところです!当たり前すぎて何言ってるか分からないですが、つまりいつもは隠れていて、必要なときにクリックして引き出す事のできるUIということですね。これは、多くの項目を並べるのにとても適したものなんです。

だから開発の初期段階では、とりあえずコマンドの呼び出しはメニューだけにして、中核機能だけ先に作っちゃえということができます。キャッチーでファンタスティックでバブリーなUIは、後でじっくり考えればいいのです。

キーボードが使える

エディタアプリでは、文字を入力する事が多いです。文字の入力には、そりゃなんだかんだいってもキーボードでしょう。キーボードを使うのがいちばん効率いいです。

ユーザの使い勝手だけでなく、プログラムの立場からでもそうです。iOSでは文字入力時にソフトウェアキーボードが表示されますが、あれが出てくると画面が狭くなるんですね。となると、動的にビューの大きさ変更しないといけないし、狭い画面でも使えるUIにしないといけない。うわー、メンドクサイ。

こういった理由から、まずはOS Xで動くものを作っています。もちろんプロトタイプの使い捨てではなくて、きちんと世の中に出せるレベルまで持っていきます。始めにきちんと設計しておけば、かなりのソースコードをOS XとiOSで共有できます。モデルだけではなく、コントローラクラスも共用できます。OS XではNSViewControllerのサブクラス、iOSではUIViewControllerのサブクラスとして、同じクラスに実装していきます。#ifdefだらけになりますが。

ただこうしてOS X版を作っても、リリースするかどうかはまた別の話ですね。出したとしてもどれだけ売れるのやら、という問題がありますから。

alloc+initよりも、new?


Objective-Cでインスタンス化といえば、alloc+init。もう指が覚えていて、何も意識せずに自動的に入力しちゃいます。

でも最近、いろんなソースコード見ると、newメソッドを使っているものが目につくような気がします。Stack Overflowのサンプルとか。Appleのサンプルコードでも、けっこう使われている。個人的な感覚としては、妙に気持ち悪い。やっぱりそこは、alloc+initだろ、おい。

感情的な事はさておいて、alloc+initの利点は様々なイニシャライザが使えるところですね。たとえば、NSStringだとinitWithFormat:とか、initWithBytes:length:encoding:とか。ズラズラと引数を並べていくのが、Objective-Cの伝統です。いちばん長いのは、あれでしょ。OS Xになるけど、NSBitmapImageRepの、

– (id)initWithBitmapDataPlanes:(unsigned char **)planes pixelsWide:(NSInteger)width pixelsHigh:(NSInteger)height bitsPerSample:(NSInteger)bps samplesPerPixel:(NSInteger)spp hasAlpha:(BOOL)alpha isPlanar:(BOOL)isPlanar colorSpaceName:(NSString *)colorSpaceNamebitmapFormat:(NSBitmapFormat)bitmapFormat bytesPerRow:(NSInteger)rowBytes bitsPerPixel:(NSInteger)pixelBits

 です。なげーよ。引数いくつだよ。エディタのコード補完がなければ、やってられませんね。

こんなイニシャライザメソッドですけど、ある程度流行はあって、最近のトレンドだとinit時に引数を付けないものが多いような気がします。とりあえずinitメソッドでインスタンス化して、その後で各種プロパティを設定していく、という使い方です。これはやっぱり、property構文が導入されたからなんでしょうね。あと、初期化後も可変のプロパティの場合は、プロパティのアクセッサメソッドから設定するのに一本化した方が実装もすっきりするでしょう。ARCでretainを気にしなくてもよくなった、っていうのも影響しているかな。

そう考えると、なるほどnewメソッドを使うのは理にかなっているな、と思いました。alloc+initがnewメソッド一発に置き換わるなら、それもありかと。あと、JavaやC++から移って来た人たちにとっては、やっぱりnewの文字は捨て難いのかもしれません。

とはいっても、自分で書くコードでは、やっぱりalloc+initにしちゃうよな。

朝4時に起きること


ここ10年近く、朝は4時に起きてます。そのまま仕事場行って、5時から6時には仕事開始です。終わるのは、18時。朝型かと言われれば、朝型ですね。

意識して朝型にしたということはないけれど、一人で静かに仕事できる時間を確保しよう、としたら、自然に早くなっていきました。今では目覚まし時計かけなくとも、だいたいその辺の時間に目が覚めます。便利だけど、正月でもその時間に起きるので、損した気分です。

朝型の方が良いとか悪いとか、そんな議論には興味ないんですけど、ひとつ確実に言えるのは、体調を崩しにくくなったこと。風邪ひかなくなったんですよ。もう10年くらい風邪らしい風邪ひいてない。これは朝早く起きることよりは、夜早く寝る事が効いているのかもしれない。夜は21時には寝ちゃいますからね。

独立して自分で会社始めるようになってから、体調管理には気を使うようになりました。だって、会社勤めしてたときは自分が休んだら他の人が仕事してくれたけど、独立したら自分しか仕事する人いないですから。体が資本という言葉は間違いなくほんとですね。いまの仕事に関して言えば、頭も資本です。体と頭が充分に活躍できるように、風邪をひかない一年を送ります。

ポップオーバー的な何か


「ポップオーバー」っていうユーザインタフェースあるじゃないですか。クラスで言うならUIPopoverControllerですね。今の画面の上にポンと表示できるので、ちょっとした設定画面などを表示するときに便利です。

popover_ipad

でもこれ、iPadでしか使えないんですよね。まぁ、がんばればiPhoneで使えたりするみたいなんですけど、OSのバージョンアップしたときの手間とか考えると、もうやめたい。なので、自力でゴリゴリと作って使っています。

popover_mine

なんでiPhoneでUIPopoverControllerが使えないんだろう?もっと正確に言えば、AppleはiPhoneでのポップオーバー的UIは良くないと考えているんだろうか?狭い画面でビューが多重になると、ゴチャゴチャした印象を与えるからかな。そんなことやるくらいならモーダルにしろよ、ってことでしょうか。

iOS 7では、UIの文法がガラッと変わりました。そのときに、depthって概念が導入されました。階層的にしろってことですね。その例として挙げられているのが、ノーティフィケーションセンターです。ポップオーバーよりも、こんな感じにした方がいいんですかね。

iOS 7のdepthで特徴的なのは、ノーティフィケーションセンターみたいな半透明の背景です。でもこれ、自前のアプリだと実現するの難しいんですよね。それ用のクラスが用意されていないし。自分で実装しようとすると、ぼかしは処理時間が大きすぎて、実用的な時間で動かないし。今のところ、UINavigationBarを引き延ばして無理矢理やってみていますが。でもこれだと、よく分からないタイミングで、いきなり半透明が解除されたりするんですよね。どうもうまいとこいかんです。

popover_navigation

FFXとDQ8


お正月なんでゲームでもやりたいなと思って、「FINAL FANTASY X HD Remaster」をやっとります。VITA版の方です。FF Xをリアルタイムでやったのは、25歳くらいでしょうか。自分がすっかりオッサン世代になったことを自覚させます。

内容はほとんど忘れているので、新鮮な気持ちでプレイできて楽しいです。FF Xでは、主人公がいきなり異世界に投げ込まれますが、記憶をなくした(というか混乱している)という設定で、説明的なセリフが違和感なくビシビシと発せられるので、無理なくストーリーに入り込む事ができます。この辺が上手ですよね。

ffx

HD化されたグラフィックも、とても奇麗です。今回はVITAでプレイしているのですが、このデバイスの画面の大きさと眼からの距離は適切で、情報量の多いHD画面もあいまってかなりの没入感があります。下手なモニタにつながったPS3よりも、こっちの方が好みですね。

同時期に、iOSおよびAndroid向けに、FFとならぶJRPGである「ドラゴンクエストVIII」も登場しました。もちろん、ドラクエ8もリアルタイムでプレイしていたクチなので、こちらも興味津々だったんですが、縦長化されたスクリーンショットを見ると、うーん、とうなってしまいます。

レビューを読むと色々と考えているのは分かるんだけど、やっぱり横画面でみたいですよね。天井と床ばっかり強調されても、困っちまいますな。実際にプレイしたらまた違う感想になるのかもしれないですけど、第一印象のガッカリ感はぬぐえません。

いくらスマホが普及したといっても、コンソールのゲームはやっぱりコンソールでやりたいな、と思った正月でした。

でかいサイズのアプリをApp Storeにアップロード中…


正月の次の日ですが、朝もはよからアプリの申請作業を行っています。アップロードが時間かかる。

うちで作っているアプリはサイズがでかいものが多いです。辞書系だと、500MB超えはざらですね。サイズがでかいとき、ネットワークのアクセス速度を考えると、ユーザにダウンロードしてもらう下りの回線は、まぁ最近は充分に速いです。

問題は、上り。Appleのサーバにアップロードするのに、下手すると一時間以上かかります。放っておいてもいいんだけど、時々アップロードが終わった後に「Invalid Signature」とかエラーが出て、もう一回やり直しかよぉぉぉ、ってことがあるので、油断できないです。

アプリ本体のサイズを小さくして、App Storeから購入した後にダウンロードさせよう、という話もよく出てきます。それはそれで、またメリットとデメリットがあって、悩ましいところです。

ちなみに「大辞泉」の場合は、

・辞書データは、アプリ同梱
・画像データは、サムネイルはアプリ同梱で、高解像度はコンテンツサーバから逐次ダウンロード

というスタイルになってます。全部の画像突っ込むと、余裕で1GB超えますからね。「大辞泉」リリース直後は、サーバの管理会社の方から「アクセス量が急増して、このままだとアクセス制限します」と言われたけど、どうにか乗り切ったらしいです。

2014年の新年のごあいさつ


あけましておめでとうございます。今年もよろしくお願いします。

2013年は、HMDTの会社としては、なかなかに激動の年でした。ようやく体制も立て直しつつあるので、今年は新しいことを始めたいですね。そろそろ、新しいスタッフも募集したいし。まずはバイトからかな。

個人的には、今年はとうとう40歳になります。30の頃には40になる自分なんて想像できなかったけど、月日が経てばとうぜんそんな日が来る訳です。

いまの私の肩書きは、社長兼プログラマ、というよりは、プログラマ兼社長で、社長業よりもプログラマとしての仕事の方がメインですね。年齢とプログラミング能力の相関関係は昔から色々言われているけど(プログラマ35歳定年説とか)、個人的にはマダマダイケルゼ!というか、俺がエースプログラマだ、若い奴らはかかって来いや!という気概です。

年齢を重ねることは悪い事だけではなくて、積み上げてきた経験が色々と助けてくれます。ただ、やっぱり能力的に衰えるところはあるなー、と思っていて、それは集中力ですね。いま、一日に働く時間はだいたい12時間なんですけど、そのうち集中できているのは4時間くらいかな。それ以外は、ダラダラと、自分でも集中できないなー、と感じながらやってます。その辺の時間管理を変えていかないといけないですね。

では、今年もがんばっていきたいと思います。

『大辞泉』1.6で新規に追加された言葉をつぶやき中


daijisen_icon

最近この話ばっかりですが、『大辞泉』1.6では、2,500語が追加されて総項目数26万7,300語になりました。

で、この新たに追加された言葉の一部を、Twitter (@mkino)でつぶやくキャンペーンをやっております。

いままでにツイートしたものは、

【インターネット選挙】
【日本版NSC】
【コミュニケーション障害】
【全過程の可視化】
【バナメイ海老】
【森田アレイ】
【冬の大三角】
【電気ピンセット】
【ゴールドバッハの予想】
【スマホ断ち】

こんなのが追加されとります。時事ネタありーの、科学分野ありーの、ネット用語ありーの、もうどんな分野でもありですね。

100個くらいはツイートしようと思うので、興味ある方はフォローしてください。

『大辞泉』1.6公開!記念セールも開催中!


daijisen_icon

大辞泉』の新しいバージョン1.6が、無事審査通過しました!ということで、公開します。

バージョン1.6の公開を記念して、セールを開催します!まず、事実上のフル機能となる「利用回数制限の解除」を、通常価格2,000円のところを1,400円に!さらに、バージョン1.6で新規に追加されたアドオンである「利用回数の最大値を50に拡大」を、通常価格600円のところを300円に!

また、この「利用回数の最大値を50に拡大」を購入した方は、制限解除アドオンを割引価格で購入できます。差分の価格になります。この価格も、通常価格1,400円のところを1,100円に!

えーっと、ややこしいですが、まとめると、

「利用回数の制限解除」通常2,000円→セール価格1,400円
「利用回数の最大値を50に拡大」通常600円→セール価格300円
「利用回数の最大値を50に拡大」を購入していた場合の「利用回数の制限解除」通常1,400円→セール価格1,100円

と、なります。セール期間は、今日から年内いっぱいの12/31まで。ぜひ、この機会にお求めください。

さて、バージョン1.6での機能の変更なのですが、先ほど説明した「利用回数の最大値を50に拡大」があります。これを購入すると、連続して50回まで利用できるようになります。消費した回数は、時間経過とともに回復するのは今まで通りです。50回も利用できると、使い切るまでかなり余裕ができますね。画像なんかも、まとめてバンバン見る事ができます。

これの導入にあわせまして、デフォルトの最大値を変更させていただきました。今まではデフォルトで15だったのを、5にしました。無料の状態で使うときは、連続利用回数が制限される事になります。

この最大値の切り下げには、色々な議論がありました。ライセンサーからの強い圧力があったのも事実です。ただ決定的だったのは、利用回数の調査結果です。実際にユーザが、連続してどのくらい検索を行っているのか、調査してグラフにしたのが下の図です。

stamina_graph

1回しか利用していないユーザは55%、半数以上にのぼります。5回以内のユーザをカウントすると、92%になり、大部分のユーザは5回以内で問題ないんですね。それとは逆に、15回全部使い切るユーザも一定数いることが分かります。

ここから、多くのユーザの使い勝手はそのままにして、ヘビーに使ってくれているユーザに新たな選択肢を与えたい、ということを議論した結果、最大値のデフォルトを5にして、最大値拡大のアドオンを追加する、という落としどころを見つけました。これでさらに利用してくれるユーザが増えてくれると嬉しいです。

他にも細かい修正点として、検索のスピードを上げるために、文字入力中はスニペット表示をやめて、検索ボタンを押したタイミングで表示するようにしたとか、地図画面での表示が高速になったとか、あります。ぜひ、アップデートしてください。