オープンソースな2tchの部品

そろそろAppleにコミットしようとしている2tch v6.0ですが,内部で利用しているいくつかのコントロールをオープンソースで展開しています. オープンソースで展開することを意識してコードを書くと,ソースコードの見通しがよくなるんですよね・・・・. 一人で使うことを前提でコードを書くと,どうしてもコードがぐちゃぐちゃに・・・・.

すべてgithubで公開しています.

UZTextView

選択可能なテキストビュークラスです. レス,スレッドタイトル,色々なところで利用しています. 文字選択やリンクを埋め込みたいテキストに利用できます. このクラスは,CocoaPodsで公開しています.

UZMultipleLayeredPopoverController – 軽量ポップオーバービューコントローラ

多段に表示することを目的としたUIPopOverControllerクラスの代替クラスです. UIPopOverControllerクラスは,多段表示したら審査で文句を言われたり,使い勝手が悪すぎるので,その辺を解決するために実装しました. 以下のようなコードでお手軽に実装できます.

id viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"NavigationController"];
[self presentMultipleLayeredPopoverWithViewController:viewController
                     contentSize:CGSizeMake(320, 480)
                       fromRect:button.frame
                        inView:self.view
                      direction:UZMultipleLayeredPopoverAnyDirection];

UZInputCandidateAccessory – オリジナル入力ショートカット

キーボードで文字を入力するときに,独自の入力ショートカット一覧をキーボードのアクセサリビューに表示するためのビューです. 割と簡単に使えるようにしました. 拡張するなら,画像とかにも対応するようにすれば,もっと色々おもしろいかもしれません.

カテゴリー: Blog

iOSシミュレータからanimation GIFを作るツール群

githubとアニメーションGIF

githubだと,READMEにYouTubeへの埋め込みリンクが張れない・・・・.iPhoneやiPadの動作画面をHTMLに埋め込みたい人に送る今回のエントリです.

githubでは,Markdown形式などで記述すると生身のテキストではなく,ブラウザにレンダリングされるREADMEファイルがあります. githubで公開されるソースはUIがメインじゃないものが多いのか,ご存知のようにYouTubeなどの動画埋め込みをサポートしておらず,READMEファイル等に動画を簡単に組み込めないのが現状です. workaroundとして,コーダーが採用しているのが,animation GIFの埋め込みです. しかし・・・このanimation GIFをさくっと簡単に作る方法が・・・・・ない・・・. そこで,その回避策を見つけたので,記事に書いてみることにします. 問題はお金で解決しましょう!!!

SimCap – iOSの動作画面を動画でキャプチャする

まずキャプチャですが,iOSシミュレータを使うのか,実機を使うのかで使うアプリケーションが決まります. iOSシミュレータの場合,少し前まではgithubで公開されていたSIMBL経由で実行するアプリケーションがあったのですが,Relfactorというアプリケーションがリリースされて後,メンテナンスが終了してしまいました. 私は,iOSシミュレータ用にSimCapというアプリケーションを買って使っています.これはわりと使い勝手よいのでお勧めです. タップしたときの指の位置なども動画に含めることができ,SoundFlowerという音声出力をキャプチャするためのソフトウェアにも対応しており,音声も同時録音できるようです. 使うときの注意点は,LandscepeとPortraitを手で合わせないと,正しく録画されないところで,私はここは少しハマリました.

SimCap

Reflector

言わずと知れたAirPlay経由でMac/Windowsに実機の画面を転送し,さらにパソコン上で動画を録画できる無敵のツールです.

http://www.airsquirrels.com/images/rf-logo-home.png

実機の挙動をキャプチャするなら,Reflector一択です. 開発したアプリケーションの実際の動作をプレゼンテーションの最中に見せたいときに真価を発揮するReflectorですが,SimCapと同じく,キャプチャがメインの目的であっても買っておいて損の無いアプリケーションです.

GIF Brewery – 動画をanimation GIFに変換する.

幸運にもApp Storeで購入した一本目のアプリケーションが当たりでした. GIF Breweryというアプリケーションです. このアプリケーションの素晴らしいところは,基本的にすべて,操作がシンプルかつ基本的にやりたいことがすべて簡単に実行できる点です(若干UIに難があるのですが).

GIFBrewery

列挙すると,

  • 動画はドラッグアンドドロップで開ける
  • In点,Out点をスライダで指定する
  • 切り出しができる
  • 切り出し後のリサイズができる
  • 動画のフレームレートを使ってフレーム数とフレームの待機時間を自動調節
  • 何種類かの方法で減色し,サイズを圧縮できる

というところがポイントです. 私は,これ以上アニメーションGIFに求めるところはないので,満足満足です.

シミュレータ→動画→GIF

それで書き出してみたのが,以下のGIFです. サイズも148KBで割りと軽いです. 2tchの用に画面の色数が少ないものは,単純な減色で圧縮しやすいので,比較としてはあまり参考にならないかも知れませんが.

以上,githubのREADMEにちょっとした動画を上げたい人にお勧めのツール群でした.

AppStore

** SimCap 1.5.2(¥1,000)**App
カテゴリ: 開発ツール, ビデオ
販売元: Just About Managing – Just About Managing(サイズ: 2.8 MB)

** GIF Brewery 2.3.2(¥500)**App
カテゴリ: ビデオ, ユーティリティ
販売元: Hello, Resolven – Patrick Rogers(サイズ: 1.3 MB)

カテゴリー: Blog

2tch version6.0

やっとリリース手前まで来ました.

iOS7以降のみ対応です. ユーザさんには見えない部分では,リファクタリングをメインに徹底的に再実装し,ソースコードが30%くらい減りました.

UXとして大きく変わるところは,

  • iOS7のアピアランスデザインに準拠
  • 文字選択ができるようになった
  • サムネイルの挙動
  • 実況用に読み上げ機能を実装してみた
  • iPad版のポップアップの挙動変更
  • 設定ビューの階層を大幅変更
  • Push Notificationの安定性を向上

です.

テキスト選択は不要だと思っていたんですが,割りと便利なので採用しました. 特にGoogleで検索するのが便利です.

主立ったバグも見えなくなってきたので,そろそろAppleに送信しようかと思っています.

カテゴリー: Blog

オレオレポップオーバー〜UZMultipleLayeredPopoverController

UIPopoverController,グダグダですよね. 階層的に表示すると審査で文句言われるし,ビューコントローラからUIPopoverControllerのインスタンスにアクセスできないし,UIPopoverControllerを破棄してもインスタンスは開放されないし,容易に多重表示されちゃうし・・・・. とりあえず,グダグダです.

そこで,仕方がないのでiOS7のUIっぽいオリジナルのポップオーバーを作りました.

@interface UIViewController (UZMultipleLayeredPopoverController)
 - (void)dismissCurrentPopoverController;
 - (void)dismissMultipleLayeredPopoverController;
 - (void)presentMultipleLayeredPopoverWithViewController:(UIViewController<em>)viewController
                       contentSize:(CGSize)contentSize
                         fromRect:(CGRect)fromRect
                          inView:(UIView</em>)inView
                        direction:(UZMultipleLayeredPopoverDirection)direction;
@end

これら3つのメソッドだけで利用することができます. ポップオーバー上に表示するビューは,ビューコントローラをセットして作ります. このため,従来のUINavigcationControllerのように使うことができます. たとえば,以下のようなコードで,Storyboardから生成したビューコントローラをポップオーバー上に配置できます.

id viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"NavigationController"];
[self presentMultipleLayeredPopoverWithViewController:viewController
                      contentSize:CGSizeMake(320, 480)
                        fromRect:button.frame
                         inView:self.view
                       direction:UZMultipleLayeredPopoverAnyDirection];

ソースは,BSDライセンスでgithubで公開しています. 使ってみてください.

github

カテゴリー: Blog

githubとSourceTree周りで色々困った話

Pushできない!!

先日,Photoshopでアイコンを作成し,まとめてリソースをgithubにPushしようとすると・・・・.
できない!!!!

エラーメッセージを眺めると,

error: RPC failed; result=22, HTTP code = 413
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly

このエラーメッセージでググると,阿鼻叫喚→Google

@niwさんが私のTweetに反応するも,似たような(ちょっと違う)エラーで@niwさんが悩んでいることが判明し,解決せず.
@niwさんが悩んでいる問題も結構深刻で,リポジトリが大きくなると発生する.- github

ググってみんなの症状を読み進めていくと,大きいデータをPushしようとすると発生していることが共通項目としてあるということがわかってきた.
そこで,一旦,コミットを戻して,Photoshopのファイルをひとつずつコミットして,Pushすると・・・・成功!!

数MBを超えるデータを更新して,Pushをするときは気をつけた方がいいですぞ!!!!

MavericksでSourceTreeがおかしい

Mavericksにアップデートしてから,SourceTreeを使っていると,毎度認証が必要なとき(たとえばprivateリポジトリにアクセスしたときなど)に変なアラートが出るようになった.

@norio_nomuraによると,Mavericks v10.9.1: Repeated prompts to unlock “Local Items” keychainが,原因っぽい.
早速試してみると,全然治らない.
仕方がないので,SourceTreeを一旦削除して,再インストールしてみたら治った.
なんだったんだ.

カテゴリー: Blog

iOS7についてそろそろまとめる

初出

6(updates) = 1(update/year) X 6(year)

1年に1回と驚異的なスピードでメジャーアップデートされつづけるiOSは,フラットデザイン?なUIに一新され,ついにバージョン7になりました.
iOS2.0用のiOS SDKが公開されたのが2008年の初旬ですが,私はJailbreak環境での開発を2007年の9月頃から始めていましたので,ついに私のiOS開発歴も6年となりました.
1年に1回のアップデートは,ver5.0くらいで終わると私は予想していたのですが,その後も続くAppleのiOSアップデートの速さに驚くばかりです.

iOS7へのアップデートの重要なポイントは,WWDC以降,色々なサイトで取り上げられていますが,開発者向けの情報に関してはどうでしょうか.
6年目のiOSに関してはベテラン(まぁ開始からですから・・・),信者としては駆け出しの私がちょっと書いてみたいと思います.

フラット万歳

開発者が受けるiOS7の表面上の恩恵は,なんといってもフラットデザインだと私は思っています.
好き嫌いの話をすると,私は,iOS6のUINavigationBarのボタン等はわかりやすくて好きでしたが,フラットデザインの楽さには勝てないというのが私の本音です1
アイコン作成,グラデーションや影を再現する手間は並ではありません.
また,iOS7の設定アプリの挙動をつぶさに見るとわかりますが,セルを選択中に左の画像の色やテキストが反転しません.
こういった細かい動作を再現するためには画像リソースをたくさん用意したり,そのためだけにメソッドを実装しないといけないことが多いため,挙動面でもtoo muchだったUIの表現が簡素化されたことは,開発者にとって作業量を減らしてくれるありがたいデザインになったといえます.
UIKitを使わないで0からコードでUIを表現する人は別ですが,UIKItでUIを組み上げる人は,その中身に集中できることになったと私は考えます.
この辺のことはラジオで@fladdictさんもおしゃっていたように2, よりコンテンツやUX(つまり中身ですね)に集中しろというAppleからのメッセージなのかもしれません.

真面目にAPIについて

iOS7では,また新しいAPIが追加されました.どちらかというと,これらは機能を強化する目的のものが多いと私は考えます.
私がiOS7で注目しているトップ3+1の機能は,以下のものです.

  1. TextKit
  2. NSURLSession
  3. Custom transition
  4. One more thing, Core Bluetooth!

TextKit

iOS7では,CoreTextを使わずにより高度なテキスト処理が行えるようになりました.
キーとなるクラスは,NSTextStorage, NSLayoutManager, NSTextContainerの3つです.
UITextViewクラスからもこれらのクラスのインスタンスにアクセスでき、UITextView上でNSAttributedStringを組み合わせて複雑なレイアウトを組むことができます.
例えば,CoreTextを使って自前でレンダリングした場合も、NSLayoutManagerを使ってユーザがタップしたテキストを検出したりするコードを簡単に書けたり,NSAAttributedStringを使ってHTMLのaタグのようなテキストも実現できます.
これらの実装はOSXでは,少し前から提供されており、やっとiOSがそれに追いついてきたとも言えます.

しかし、OSXのすべての機能が利用できるわけでもなく、クリカッブルテキストも機能は限定的です.
具体的には,クリカッブルテキストのイベントは自由に受け取ることはできず、リンクが貼られたテキストの色を自由に設定することもできません.
未だ完璧ではないTextKitですが、従来システムでは面倒なCoreTextで実装しなければならなかった機能を簡単に実現できる点から、iOS7の重要なアドバンテージの一つであると私は考えています.
TextKit周りは,拙作UZTextViewのエントリを書くときにもう少し詳しく書きたいと思っています.

NSURLSession

ダウンロードタスクを別プロセスのデーモンに任せてしまい,バックグラウンドでもダウンロードできるようにする優れもの.
説明は他のサイトにお任せしますw

Custom transition

iOS7では,プログラマがUIViewControllerの画面遷移のアニメーションをUIViewControllerと切り離して定義できるようになりました(今更感が否めませんが・・・).
私もこれを実現するためにUIStoryBoardSegueをオーバーライドしてとか,涙ぐましいことをやりましたが,iOS7からその必要はありません.
UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioningプロトコルをしゃべるクラスを実装し,UIViewControllerのsetTransitioningDelegateに遷移を定義するUIViewControllerTransitioningDelegateプロトコルを実装したクラスのオブジェクトを渡すだけで大筋の足場が完成します.
おおざっぱに言うと,UIViewControllerAnimatedTransitioningプロトコルは,画面遷移のアニメーションを実装するもので,UIViewControllerTransitioningDelegateプロトコルは,画面遷移時に使うアニメーションを定義するものです(UIViewControllerTransitioningDelegateで,UIViewControllerAnimatedTransitioningを返すみたいな感じ).
この機能も,UIViewControllerとアニメーションのコードを切り離したいというプログラマの念願をかなえてくれるiOS7の目玉機能だと私は思います(更感が否めませんが・・・しつこい).

+1, iBeaconとBTLEへの思い

最後に!One more thing, やっと,本来の力を見せ始めたCoreBluetooth!
私は,2年くらい前のどっかのイベントでもこれからくるのはBluetooth LEだ!!って言まして,全然BTLEの人気が来ないので,泣きそうだったんですが,ようやく立ち上がり始めてきてうれしい限りです.
iBeaconは,BTLEの電波にロケーション情報を載せてブロードキャストし,CoreLocationフレームワークでそれらを簡単に受け取ることができる仕組みです.
こういう考え方の典型例として,@masuidriveのブログのアイデアや,拙作AnonyFollowがあります.
これは共にコンセプトが同じもので,Bluetooth LEで誰とでもすれ違いフォローができる電波Pokenを作ろうというコンセプトです.
個人事業者にとっては,CoreBluetoothのおもしろみは,iOSとOSX同士のライトな連携にあると私は思っています.
結局,デバイスを個人や小資本で大量生産するのは不可能なので,最終的に趣味プログラマーはそっちへ収束すると私は考えますが・・・そんな閉塞感をiBeaconが打破してくれて,かっこいい,かつユニークなデバイスや環境が満を持して登場!!!・・・・というのが今の私のBTLEへの思いです.

まとめ

以上,ざらっと,iOS7について半年経ってからまとめてみました.
他にも,CIをサポートするBot,doxygenスタイルでコメントを書くと自動的にヘルプにしてくれる機能などがXcodeに追加されていたりします.
これからは,ブログであまり人が取り上げそうにないことを中心に書いていきたいと思っています.
次回は,TestFlightへの自動アップロードを中心にBotのパスについて解説したいと思います.


  1. 行き過ぎたskeuomorphismは,本来のデザインの意味や目的を失わせると私は考えます.MacOSX10.8やiOS6のメモ帳アプリのデザインは,私にとって意味不明でした.これらコンピュータ上で動くメモ帳は,いわゆるメモ帳とはまったく機能も役割も異なるものです.これらのアプリケーションは,本来のメモ帳が持つ自由に記入できる能力はまったくない,単純な正規化されたテキストいれるだけの箱です.そういったアプリケーションに物理的な本来のメモ帳のデザインを取り入れることは,ユーザに誤解を与えるだけだと私は考えています. 

  2. 参考リンク – Twitter 

カテゴリー: Blog

書評 – 上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編

献本御礼.
自分が知っているところ等を重点的に読みました.
買いか,否かというと,Xcodeの使い方,普通にInterface Bulderが使える人は買い.
タイトルの「上を目指す」は大体合ってるような気がする.
「上」のレベルにも因ると思われるが,本筋ではないのでどうでもいいか.
本書の位置づけは,iOS7の新機能の実装方法の概要です.
クラスリファレンスだけじゃさすがに実装できないので(リファレンスすらないのもありますけど),概要はとても重要です.

TextKit周り

TextKit周りは,まだ解説記事があまり出てないので,この本では特に重要.
UITextViewオブジェクトで,NSTextStorage, NSLayoutManager, NSTextContainerクラスを使って,複雑な組み版をやる例を解説しています.
テキストレイアウト周辺の実装は詳しくやると底なし沼みたいになるので,とても本の一章では解説できないが,基本的な使い方をまとめているので,この本は初めの取っ付きにはよいと思う.

Transition周り

iOS7で追加されたオリジナルの画面遷移実装についての章もおすすめ.
実装の面倒くさい,途中でキャンセルできるカスタムトランジションの実装方法についても詳しく書かれていることが特に良いところ.
最後にiPad版のカスタムトランジションのgdgdさ,まで解説して,AppleをDisってくれたら何も言うことはなかったのに(ry

おまけ〜普通に役立ったところ〜NSDataとNSURLComponents

NSDataでBase64エンコード,やっとできるようになったんですね・・・.
知りませんでした・・・・.
最初から実装しておいてよ・・・・.

NSURLComponentsクラスは,scheme,host,path,action・・・の要素からURLを生成できるクラスです.
クラスリファレンスがまだない.
いい加減にしろ,Apple.

これ以外の章はサラっとしか読んでないのであまり感想書きません(書けません).

以上,宣伝と感想でした.

上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編

カテゴリー: Blog

パーセントエスケープで勘違い

Cocoaのテストコードを整理していて,SJISの文字列をパーセントエスケープでうまく処理ができていないことを発見.
ちょっと調べてみた.

Rubyで書くとこんな感じ.

>> require 'cgi'
=> true
>> CGI.escape("名前".tosjis)
=> "%96%BC%91O"

Objective-Cでは,巷では色々議論されているけど,あれはあくまでエスケープしない文字の話であって,今回とは関係ない.
普通にエスケープするとこうなる.はず.

NSString *string = @"名前";
CFString *escaped = CFURLCreateStringByAddingPercentEscapes(NULL, string, NULL, CFSTR (";,/?:@&=+$#"), kCFStringEncodingDOSJapanese);
NSLog(@"%@", escaped);
=> %96%BC%91%4F

さて,結果が違いますね・・・・.他のデータで試しても同じ.
BathyscapheなどのCocoaを使ったオープンソースのコードを使って試してみても,得られる結果は同じようです.

さて,これは一体なんなんだと.
調べてみると,Shift JISのようなデータに非予約文字が入っている場合は,そのまま非予約文字で出力してもかまわないという仕様があるそうです.

“マルチバイト文字はバイト単位で変換する。Shift_JISの2バイト目など、バイトが非予約文字に対応するなら、その文字をそのまま使用しても良い。 – wikipedia

“その文字をそのまま使用しても良い。”なのか,”その文字をそのまま使用しなければならない。”なのかが問題.
もし,どちらでもいいというのであれば,Rubyなんかでも正しくアンエスケープされるはず・・・と思ってやってみると・・・・・あ,ちゃんとできた.

>> CGI.unescape("%96%BC%91%4F").toutf8
=> "\345\220\215\345\211\215"
>> CGI.unescape("%96%BC%91O").toutf8
=> "\345\220\215\345\211\215"

というわけで,どちらでもいいっぽい.
Wikipediaなんか読まずに仕様嫁よと言われそうなので・・・・え・・・後で読みますけど・・・いや読むのだるい・・・正しくは仕様?かRFCの勧告を参照のこと・・・.

Rubyで作ったデータをテストとかに使ったりするので,この不一致はうっとおしい・・・・.
とりあえず,Cocoaで予約文字をエスケープしないコードを作ってみたけど,これのテストするのもまたやっかい・・・・・.悩ましい.
結論,私が無知でした.勉強になりました.

2tch v5.0.1

3回のリジェクトを経て,やっと公開に至りました.
色々,指摘があると思いますが,不本意な結果になってしまいました.

あしからず,ご了承くださいませ・・・・・・・・・・.