Sunday, March 9, 2014

What I thought after reading “Welcome to the Quiet Revolution”

“Welcome to the Quiet Revolution”
Money equals time. It’s that simple. Each dollar you earn translates to time you weren’t spending with your family, friends or following a side passion. So, spending the money you earn means, really, spending your time.
(労働)収入は自分や家族のために使えたはずの時間を犠牲にして得ているということなので、お金を使うということは「自分の時間消費」することに等しい。

“Quiet Revolution” とは、 つまり、働くために時間を使うにしても、それで得た収入を使うにしても、賢く使わないともったいないよね。ということらしい。

他にも要素はいろいろあるにしても、僕がフリーランスになった一番の動機は、「自分の自由に使える時間を増やしたい」ということなのでこのへんは同感ですね。

ちょうどいま、シゴトが忙しくてオレオレプロジェクトをやってる心の余裕がない状況なので、余計に考えさせられます。 そのシゴトは僕が長い間関わっているプロジェクトで、数ヶ月前から、いろいろ改善しましょうという時期に来ていて、僕が「全部捨てて書き直しましょう」みたいなことを言い出してしまったので自業自得なところもあるし、「こうしたい」的な感じで実装できているので、まあ楽しいし、落ち着けばあとで楽になるはずという希望もあるので、ある意味「自分のために」やっている部分もあるのですが。

Sunday, October 6, 2013

au 携帯のメール受信を pebble に通知する方法

みんな大好きバッドノウハウ。

iPhone のロック画面に表示される通知が Pebble に通知されるハズなのですが、うまくゆかないので、 Pebble iOS アプリの "Email Notifications" を設定したいけど、 au の携帯メール(EZWebメール)はたぶん IMAP 設定できないし、できたとしてもパスワードを Pebble アプリで入力したくないので、携帯メールの転送先として新しく GMail アカウントを作成して、その GMail アカウントを Pebble の Email Notification として設定しました。

具体的には、
  1. 新しい Google アカウントを作成
  2. EZwebメール各種設定で作成した Gmail のアドレスを転送先として設定
  3. Pebble iOS app の "Email Notification" 設定で Gmail アカウントを設定

ちなみに、現状の Pebble では ASCII 7bit 以外の UTF-8 にはフォントの glyph が無いので豆腐になってしまいますので、メールの件名や本文が日本語だと、とりあえずメールが来たということしかわかりません。 また、 Pebble への通知はリアルタイムには来ないですね。ポーリングしてるのかな?

利用した環境は
  • Pebble iOS app 1.2.1
  • Pebble Firmware 1.12.1
  • iPhone 5 (iOS 7.0.2)

Saturday, September 21, 2013

The localization bookmarklet

ネットで海外の情報を見るときに英語という言葉の壁もあるのですが、"Sep 11, 2013, 4PM US/Pacific" のような時差やサマータイムがあって日本時間で何時なのか分からないという問題と、 "1,000 lbs" のような単位系が違うのでどんだけ重いのかピンと来ないという問題がありますよね。

Google Translate とかでも "2013年9月11日、午後4時米国/太平洋", "1,000ポンド" みたいな「翻訳」はしてくれるのですが、「ローカリゼーション」はしてくれません。

そういうときに "Sep 12, 2013 08:00 JST" や "~454.00 kg" のような変換をして表示してくれるブックマークレットを作ってみました。

http://hiroshi.github.io/l10nb9t/

気に入っていただけたら、 github リポジトリ で star したり、 tweet したりして頂けると嬉しいです。あ、要望とかバグ報告は日本語でもいいので https://github.com/hiroshi/l10nb9t/issues にお願いします。


P.S.1. 個人的な意見ですが、海外のメディアの日本語訳しているサイトでそういう時差や単位の変換をしていない翻訳はイラっと来ますね。もっと言うと文化的に理解できない内容や日本では利用できないサービスに対する訳注も無いやつはダメですね。お前は機械翻訳かと思います。

P.S.2. ブログ書くの久々ですね。一年半ぶりくらい。

  • どうでもいいことは twitter
  • 技術的なことは stackoverflow
  • バッドノウハウ的なことは qiita
という感じで書く機会が無かったのですが、なにか自分でつくって告知したいけど Hacker News に Show HN するには怖いなというときはやっぱり自分のブログに落ち着く感じですかね。読者ほぼゼロだと思いますが...。他によいメディアを知らない。

Friday, January 27, 2012

iOS App PhotoHistory Released!

iPhone / iPod Touch アプリ PhotoHistory (Apple App Store 170円) をリリースしました

このアプリは僕自身が Apple 標準の写真アプリを使ってみて不便に感じたところを解決しようとしている試みです。何が問題かというと、「iPodTouch のカメラで撮った写真やデジカメなどからの大量の写真を整理せずに iOS に放り込むと、スクロールして写真を探すのは不可能」ということです。

大量の情報を扱う可能性のあるアプリの例としては、「連絡先」や「ミュージック」があります。これらのアプリは一覧の右側の「インデックス」により素早く目的のものを見つけることができます。PhotoHistory は写真の日付をインデックスにして、例えば「2008年のクリスマス」に瞬時に戻ることができます。

I released iPhone / iPod Touch App PhotoHistory (Apple App Store $1.99)

The PhotoHistory is designed to solve a problem when I used Photo.app of Apple. What's wrong with Photo.app? Photo.app is pretty simple and I was content till I had thousands of photos in my device. It is almost impossible to find a photo by scrolling and keep watching. Yes, I should organize photos in albums or events, but I wouldn't.

On the other hand, some apps possibly to manage lot of informations or data, say Music.app and Contacts.app, have "index" on the right side of their table interface. PhotoHistory simply use same design by "index" dates of photos. Now you can find "Christmas 2008" in an instant.

Thursday, January 5, 2012

Synching Address Book on Lion, GMail Contacts and an Android

Mac (Lion) のアドレスブックと Gmail の Contacts と Android の連絡先を同期させるという基本的な作業が結構難しかったので書いときます。

まずは Lion のアドレスブックと GMail Contacts を同期させるには、

アドレスブックの環境設定 -> アカウント -> この Mac 内 -> アカウント情報 -> Google と同期 -> 構成
でアカウント情報を入力して OK すると、mac の メニューバーに sync アイコンが表示され、メニューから「今すぐ同期」を実行すると Google Contacts と同期が取れます。

過去にアドレスブックと Gmail Contacts をインポート/エクスポートでコピーしてた場合など、単純に同期を開始するとダブったりするので、

  • アドレスブックか Gmail Contacts のどちらかがゴミならバックアップをとってから全部削除 (僕の場合、 Gmail Contacts がゴミだったので削除してから同期させました)
  • 両方とも活かしたいなら、同期させてから、 Gmail Contacts で2つ以上のコンタクトをチェックしてから、 More メニューで "Merge Contacts" でまとめる
  • アドレスブックにも「選択したカードを結合」というメニュー項目があるので同じようなことができるかもしれません(試してませんが)

Gmail Contacts の内容がマトモになったら、 Android の設定 -> アカウント から同期するようにチェックすればいいのですが、Motorola の端末だと "Power Control widget" というやつで sync を off にしてると自動では同期できなくなるようです。 Android 端末のカスタマイズっぷりを把握してないので Motorola 以外の端末にもあるのかもしれませんが、不明。

実行環境は

  • Mac OS X Lion 10.7.2
  • au / Motorola PHOTON / Android 2.3.4

ちなみに、アドレスブックと iOS 端末も iCloud で同期できるのですが、 アドレスブックの「アカウント情報」のヘルプには

「iCloud アカウントを追加するきに Google 連絡先との同期が入になっている場合、その同期オプションは切になります。iCloud 連絡先サービスを利用している間は、その同期オプションを切にしておくことをお勧めします。」
と書いてあって怖いので試してません。

Thursday, December 1, 2011

make testflight

Xcode の Organizer を使って IPA を生成してから、ブラウザからアップロードするのは面倒なので、ネット上には Testflight upload API を使ってアップロードを自動化するスクリプトはいくつか転がっていますが、 xcarchive のパス, Code sign identity, API token, Team token などの設定が自動化されていないのしか見つけれられなかったので Makefile を書いて見ました。

特筆すべき必要条件

  • Xcode 4 の設定項目についてのある程度の知識
  • ruby 1.9.x or `gem install json`

準備

Build Phases の最後に "Run Script" を追加。

ここで CODE_SIGN_IDENTITY を Makefile から参照するためにファイルに保存しているのですが、 "Automatic Profile Selector" を利用している場合は、 CODE_SIGN_IDENTITY の値は "iPhone Distribution" だけで署名者名が入らないので、固有の Identity を選択するようにしてください。

Xcode scheme の "Archive" build action の Post-actions に "Run script" を追加。

通常 scheme は "shared" しない設定にしてリポジトリに追加しないようにしていると思います。なので、この Post-action を設定する scheme は "XXX-testflight" みたいな名前で "duplicate" して "shared": on, "show": off にしてリポジトリに追加すると、共有できて Xcode の scheme 選択からも見えなくなるのでいいかと思います。

あとは、プロジェクトのディレクトリに Makefile を置いて、 `make testflight` を実行するだけです。 Testflight のノートを入力するフォームが開くのでノートを変更して配信先を選択してください。

初回実行時には "Team Token" と "API Token" の入力を要求されるので、ブラウザに Testflight のセッションが残っていれば、表示されるはずなのでコピペしてください。

Xcode の archive から実行したい人は、 Makefile を fork して工夫してみてください。

Thursday, July 14, 2011

iOS autoresizing UIView TIPS

2011-11-26: 根本的に理解が足りない気がしてきた。 autoresizingMask や layoutSubviews を使えば済む場合が多いはずなので整理ができたらまとめます。
2011-10-04: view controller を window に直接 addSubview するのでなく UINavigationController や UITabBarController 配下にするばあいは viewWillAppear でも orientation は反映されているようなので、あとで調べて情報を更新したい
2011-08-05: orientation が landscape の場合には - didRotateFromInterfaceOrientation: まで待つ必要があったので修正

InterfaceBuilder を使わずにコードで iOS の view 階層を作成して画面サイズや orientation にあわせて autoresize させるにはいろいろと注意が必要になるのですが、イマイチ情報が無かったのでわかったことを書いておきます。

ポイントとしては、 Apple のドキュメント "View Controller Programming Guide for iPhone OS" (rev. 2010-05-03) の "Custom View Controllers" だと、コードで view 階層を作成するには loadView でやれみたいに読めるのですが、 loadView や viewDidLoad のタイミングでは autoresize はまだ反映されず、 viewWillAppear のタイミングで反映されるようです。
さらに、 orientation が landscape (ヨコ) の場合には viewWillAppear ではダメで didRotateFromInterfaceOrientation: まで待たないとダメなようです。

ちなみに、 orientation が viewController.view に反映されているかどうかは、 view.transform に rotation の値が入ってるかどうかで分かるようです。
<UIView: 0x5b59d80; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x5b532a0>>


従って、画面のサイズ(iPhone or iPad)、 navigation bar などの表示の有無 によって autoresize される view の frame や bounds に反映されるのは viewWillAppear のタイミングなので、例えば、それらの autoresize される view の subviews として view をグリッド状に並べたりするのは viewWillAppear でやれってことになります (orientation が portrait でないときは didRotateFromInterfaceOrientation)。

ちなみに、 loadView で生成して addSubview する view をおまかせで画面に fit させる場合、
initWithFrame する必要は無く、 frame は (0 0; 0 0) で OKのようです。
- (void)laodView
{
    UIView *rootView = [[[UIView alloc] init] autorelease];
    rootView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    self.view = rootView;
}


逆に fit させる大きさ(この場合、navigation bar などを除いたサイズ) より大きい frame を設定してしまうと autoresize はうまくゆかないようです。

また、 [super loadView] で自動生成される view は [[UIView alloc] init] した view とは違い、そのタイミングでの (orientation の反映されていない) frame になっていたり、プロパティの値が違うのか、期待どおりの動きにするのが面倒な感じなので自前で [[UIView alloc] init] したほうがよさそうです。