2015-12-20

MakeAppIcon -- アイコンとリードのジェネレーター

iOS アプリを作るとき、スクリーンのサイズと分解能ごとにアイコンを用意する必要がある。画像の扱いに長けているわけではないし、そもそも面倒な作業である。

MakeAppIcon というウェブサービスを使った。1024x1024 の画像をアップロードすると、iOS と Android のアプリ用アイコンが生成される。iPad Pro 用のアイコンがなかったけれど、1つくらい手動で作るのは苦にならない。

できあがったアイコンセットは、ウェブでダウンロードするのではなくて、メールで受け取る。

MakeAppIcon 側から見ると、

  • iOS/Android のアプリアイコンが必要で、
  • 自力でアイコンを作るのをだるがり、
  • そのための有料ツールを使わない

という特性を持つ人のメールアドレスを集められるということだ。なるほどなぁ。

2015-12-13

多重度・本番・流星 〜 テレビ連動ウェブサービスの勘所

欲しいものを手に入れたり、何かを成し遂げるための心構えや方法論というのがあって、自己啓発書やセミナーで紹介される。何年も前に参加したイベントが、ちょっと意識高めで、そこでも紹介されていた。

「流星理論というのがあってだな」
「何すか、それ?」
「流れ星を見たら、願い事を3回となえるんだ。すると願いが叶う」
「ちょw」
「笑ったね?流れ星が突然見えたとき、とっさに3回も言えるってことは、常にそのことを考えてるってことだよ」

いま考えていることは、成果になる可能性がある。であるならば、考えていることが、誰かに某かの足しなるかも知れない。このところ、テレビ番組と連動するウェブサービスの、要件定義について考えている。

以下は、これまでの経験で、おおざっぱに個人的に認識している課題と解決策の案だ。特定の放送局、制作会社、番組の話ではない。

個数が決まらない


「Facebook Messenger に、いいねスタンプあるじゃないすか」
「ありますね」
「いつからか、長押しすると巨大化するようになりましたね」

あるオブジェクトに関連する、別のオブジェクトの個数のカテゴリーとして、0個か1個、必ず1個、0個以上、1個以上などがある。特に「必ず1個」というのは設計上/実装上、強めの制約条件になるので、チューニングに活用できる。

業務系のアプリケーションでは、目的的に多重度の決定がなされる気がする。顧客管理アプリケーションにおいて、顧客の電話番号をいくつ登録できるのかは、そのアプリケーションで解決したい問題と深く連動しそうだ。

たとえば「ここは Facebook のいいね!と同じ」と言われ、問題ドメインにおけるモデルも Facebook のいいね、と同じだと考えてたとしよう。2週間後、連打でいいねのアイコンが大きくなる、いいね数がポイントとして与えられる、しかも、時間がたったらポイントが消えていく、といったクリエイティブなアイデアが浮上する。

この種の要件は発見的に決まりがちだ。やってみたら、面白かった的な演出要素である。もちろん、演出は問題を解決する手段だけれど、顧客名簿の電話番号と違い、いいねだけを切り出して要件定義をしにくいため、プロセスの構造が少し違う。関わったことはないのだけれど、ゲームも同じような構造がありそうな気がする。

コードシンプリシティでは「未来を予測せずに、未来に備える」ことを提案している。ちょっとした切れ目を入れておくのだ。API が返すデータと、データベース上のデータをガチガチに対応づけないようにする。いいねの数は、内部で get_likes() 関数を経由して取得するとか、getter/setter にしておくとか、そういう基本的なことだ。


Rails のアクティブレコードは楽ちんだけれど、この手の届く距離にデータを置いておくアプローチだけでは、変更対応がしにくくなるのだ。



稼働中の本番環境でテスト


「もう1回」
「だめですよ。もう勝負決まりましたよ」
「さっきのは練習。次が本番」

稼働中の本番サーバーで、副作用のあるリハーサルを要求されることがある。何を言っているか分からないと思うが、私には分かる。本番環境を使うことの意味が、番組制作とウェブサービス開発では異なるのだ。

テレビ局のスタジオから生放送することを考えよう。予算とスケジュールが許せば、本番とまったく同じ物理リソースで、事前にリハーサルができる。セット、カメラ、音響、照明すべてに、本番と同じリソースを使うことは物理的に可能だ。難しいのは、出演者のスケジュールの都合で遅れたり、トイレが我慢できなかったりで、時間がずれるとかの対処だろうか。

スタジオに併設されているサブ・コントロール・ルームでは、本番時もリハーサル時も各カメラからの映像(と、必要であれば録画した映像)がたくさんのモニタに映し出され、ディレクターがどの映像を使うかを指示/選択できる。サブ・コントロール・ルームの出力は、マスター・コントロール・ルームで送信所(東京の地上波ならスカイツリーとか)に出すように切り替えない限り、視聴者が知覚できる副作用は発生しない。

ここに番組宣伝なるものが、カジュアルに提案される。もちろん、いくら宣伝をしたとしても、番組コンテンツの視聴という副作用は発生しない。

ところが「番組宣伝期間中、事前登録をしたユーザーに10ポイントあげる」となると、ユーザーとインタラクションが発生したウェブサービスに、外部から知覚できる副作用が発生する。やっかいである。

リハーサルに開発サーバーを使うと「俺、事前登録したのに、10ポイント入ってないけど」という声があがるのは楽なほうだ。2夜連続放送の2日目のリハーサルで「昨日ゲットしはたはずの牛丼クーポンがなくなってるぞ。大丈夫なの?」とかなるとアレだ。

唐突に聞かされるとやっかいだけれど、事前に分かっていれば対応可能な要件ではある。ひとつの解決策は、サービスの機能として、本番モードとリハーサルモードを用意しておくというものだ。

本番/リハーサルでAPIに渡すパラメータを変更する、リハーサルモードでは過去の本番データを参照するが、未来のデータはリハーサル用の領域に書き込むなどの機能を実装すればよい。あるいはデータが小さければ、スナップショットをとってリストアする処理を、しょっちゅう行うものとして作ってもよい。

おわりに


以上、最近考えていたことを、書き出した。

今年の年末の仕事を請けたときには、放送日が確定していなかったので、参加申し込みをしなかった忘年会がある。結局、放送日と忘年会の日程はぶつからず、惜しいことをした。飲み会や、トライアスロン/マラソンレースのキャンセルに気をもむのが嫌になった、というのも前の仕事を辞めた理由のひとつだったことを思い出した。

「カネカネカネ」
「何すか、急に?」
「いや、ちょうどあのへんに、流れ星…」 


※ 縛り
・題名:「星」を含むこと。(例:「星の王子さま」「きらきら星」など)
・書き出し:書き出しをひらがなにしたとき「ほし」と表記できること。(例:「星空」「干し芋」「保守」など)
・文中に以下の3つの縛りワードを含むこと。
  縛りワード1:「この手の届く距離」
  縛りワード2:「我慢できなかった」
  縛りワード3:「牛」
・結び:「星」で終わる。ただし、句点(。)、疑問符(?)、三点リーダ(…)、その他の文章記号をつけてもOK。

2015-12-05

GPS 誤差の距離のずれを、移動平均で減らす

GPS の電波を拾いにくい市街地で測定した経緯度を、地図上にマッピングしていくと、けっこうずれている。


「けっこう」ってどのくらいだよ、っていう話ではあるけれど。ランニングの記録なので、ばっちりの位置が欲しいわけではない。けれど、このくらいずれると、距離にして 3-5%ずれる。1km あたり 7分ペースで走っている場合、距離が 3% ずれると、1km あたり 6分48秒で走っていることになる。

1km あたり12秒の誤差が、42km 積み重なると、8分半になる。地味に気になる。

念の為に書いておくと、マラソンレースにおける距離は、路肩には30cmぐらいまで迫るのを限度として、最短パスで測られるとかだ。なので、多くのランナーは最短コースを走れないので、GPS の測定誤差が完全にゼロであっても、42.195km よりも長めに走ることになる。閑話休題。

GPSの誤差は、高周波成分をなくせばいいんだろうなぁと思った。緯度と経度を、測定ポイントではなくて、移動平均を扱えばよいだろう。

やってみた結果、時間にして5秒、距離にして10m程度で移動平均をとると、距離の誤差が1%くらいになる。ちなみに iPhone 5 。これ以上、平均を算出するポイント数を多くすると、コーナーがなまりすぎる。




2015-12-02

iOS アプリ全体で navigation の見栄えを変更する UINavigationBar.appearance()

iOS の navigation という UI コンポーネントがある。設定を深入りしていく用途なんかに使う。しかも、ストーリーボードで深入りする方向に画面遷移を定義すると、戻っていく方向の遷移は「< Back」ってラベルまでつけて、自動的に実装してくれて便利。

アプリ全体で、この文字色をカスタマイズするには、AppDelegate.swift に以下のようなコードを書く。

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let color = UIColor(red: 113/255.0, green: 61/255.0, blue: 150/255.0, alpha: 1)
        UINavigationBar.appearance().tintColor = color
        UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : color]
        return true
    }
    ...
}

tintColor は左右にある「<Back」とかの色、titleTextAttributes は上部中央のラベルの見栄えを指定する。

各画面でこのへんの文字を outlet として参照し、パラメータを変更しても、画面には反映されない。おそらく一旦描画したあとは、参照しないのだろう。

このへんの文字は UILabel のサブクラスっぽいので、UILabel で入れ替えると、見栄えが反映されるらしい。ただ、自動的に追加される「< Back」はデフォルトのままになってしまう。頑張って参照しようと思えばできるのかも。


じゃあナビゲーションをサブクラスにしようかな、という誘惑を思いとどまり、丁寧にググったら、上記のAppDelegate に書いておく方法が見つかった。