Sencha Touch 2.1の変更点まとめ
本記事は、Sencha Advent Calendar 2012 の3日目の記事です。Sencha Advent Calendar ですが、今のところ参加者がとても少ないです。。どんなネタでも大歓迎ですので、ご参加お待ちしています!
先月、11月6日に Sencha Touch 2.1 がリリースされました。ざっくりと以下のような点が追加・改善されたようです。
- パフォーマンスの改善
- ネストしたレイアウトでのパフォーマンス改善
- paintedイベントへの変更
- TaskQueueメカニズムの追加
- Chart の機能改善
- Drawパッケージの改善
- 拡張可能なスプライト
- 修飾子と属性の定義
- フライウェイト・インスタンス化・スプライト
- Retinaディスプレイサポート
- Chartパッケージに新しいチャートを追加
- 集合チャート
- 金融チャート
- Drawパッケージの改善
- コンポーネントの強化
- 無限スクロール付きリスト
- 新しいSencha Cmd
- 強化されたネイティブサポート
詳しくは以下をみてください。
ところが、2.1で新しくなったのはこれだけではありません。というか、全然もっとある!!ということで Release Notesから、個人的に興味あるものをピックアップして紹介したいと思います。
チャート系
- Implemented SVG support for Draw
- SVG is now forced on Android 4.1 devices due to Canvas issues
- Added webkitBackingStorePixelRatio support
- CanvasのRetina対応
チャート系のアップデートに伴い、draw系パッケージも各種強化されました。詳細は割愛。詳しくはRelease Notesみて下さい。Android 4.1 ではCanvasの問題から強制的にSVGになるようです。
dataパッケージ系
- [TOUCH-2792] Implemented filters, sorters and paging into WebStorage proxy
- [TOUCH-2844] Optimized clear method on WebStorage Proxy
WebStorageでもフィルタ、ストア、クリアができるようになった!
- [TOUCH-2800] Implemented new WebSQL proxy
- [TOUCH-3551] Added filtering and sorting capabilities to the SQL proxy
ようやくWebSQLプロキシが実装されました!!フィルタとソートも追加。
Sencha Command 関連
- in-app purchases API for iOS
- Contacts APIs for iOS and Android
- Push notifications for iOS
- openURL support
アプリ内課金、連絡先API、プッシュ通知などにも対応!
パフォーマンス
- SizeMonitor refactored for improved performance
- Improved Android 4 Scroll Indicator performance
- Update Button SASS so it looks better on device
- Change ListItems to not use vertical docking for headers. This improves performance since there is less DOM and less box layouts
スクロールや回転、リストのパフォーマンスアップ。ボタンデザインの修正。
- [TOUCH-3497] Added support for iPhone 5 resolution startup screen
解像度が変わりましたからねー。
その他
- [TOUCH-2888] Changed the default zIndex in message box to a larger number to stop accidental zIndex issues when creating other floating panels/components
- 1.xの頃からあるバグで昔私も報告したなー。ようやく直ったようで。
- [TOUCH-3042] Allow hideOnMaskTap to be changed dynamically
- これは地味に欲しい機能。
- [TOUCH-3031] Allow JS files to be specified as remote
- JSの部分遅延ロードができるのかな?
- Ext.browser, Ext.feature, Ext.os が追加
- 機能判別やブラウザ、OS判定が便利になった!
- POST calls will now honor the disableCache option
- 例の iOS6 のPOSTキャッシュのバグ回避?
- Added proper support for IE10 animateStartTime
- IE10サポートも進んでいるようです。
総括
Release notesからざっくりと拾い出してみました。実はまだドキュメントに載っていない新機能が色々とありました。ソースを見ると入っているのですが、ドキュメント化が間に合ってないみたい。2.1 になって、細かい使い勝手などが結構改善されています。2.0 → 2.1 への乗り換えはそんなにコスト掛からないと思うので、是非検討されるとよいんじゃないでしょうか?
あと、たまにRelase notesを見ると思わぬ情報があったりしておもしろいですねー。ちゃんとドキュメント読みましょう、ということですね。
さて、Sencha Advent Calendar 明日は、また @kawanoshinobu さんです!その次が未定なので、ぜひ誰かJOINしてください!(切実
Objective-Cの循環参照について
2年ほど前に書いた記事 #import の使いどころ:循環参照しないために。 が未だにそれなりにアクセスがあるのですが、これは間違いがあります。正確にいうと、間違いでは無いのですが、冗長であまり意味のない記述でした。
#import は C言語の #includeを拡張して、一度だけしかヘッダファイルを読み込まないようになっています。そのため基本的には循環参照は起こらないようになっています。
では、何が問題になるか。
先の記事のコードは、以下のようなものでした。
ClassA.h
#import "ClassB.h" @interface ClassA { ClassB variableB; } @end
ClassB.h
#import "ClassA.h" @interface ClassB { ClassA variableA; } @end
これをコンパイルすると、以下のような処理が行われます。
- ClassA.h を読み込む
- ClassA.h の先頭の#import 宣言により、ClassB.h を読み込む
- ClassB.h を読み込む
- ClassB.h の先頭の#import 宣言により、ClassA.h を読み込もうとするが、既に読み込み済みのためスキップする。
- @interface で ClassB を宣言
- 型 ClassA の 変数 variableA を宣言
- エラー!! 型 ClassA が見つからない!!
ClassB.h を読み込んだときに、まだClassAの宣言が見つからないため、このエラーが発生します。そこで、@class ディレクティブで、ClassA はクラスだということを教えてあげる必要があります。@class 宣言を追加した正しいコードは以下の通り。
ClassA.h
#import "ClassB.h" @class ClassB; @interface ClassA { ClassB variableB; } @end
ClassB.h
#import "ClassA.h" @class ClassA; @interface ClassB { ClassA variableA; } @end
実装ファイルとヘッダファイルにimportを分ける必要は特にありません。全部ヘッダファイルに書いてOKです。
もう1点。
そのクラスのメンバーにアクセスしない場合は、import宣言は特に不要です。メソッドの戻り値のように、実装ファイルの中でそのオブジェクトのメンバーにアクセスする必要が無い場合などは、@class でクラス宣言だけしてやればOKです。インスタンス変数やメソッド引数のような場合は、実装中で使用するはずですので、importは必要でしょう。
@class は、その型がクラスであることを示しているだけです。逆に言うと使用するクラスを全部 @class で宣言しておいても特に問題はありません。(めんどくさいので普通はやらない) 循環しそうだな−、というのは @class で宣言しておくと幸せになれるかもしれません。
ということで、まとめ。
- 循環参照しそうな場合は、ヘッダに @class を宣言しとくと良い
- 実装ファイルで別途 importする必要は無い。
こちらも是非参考に:
Objective-Cのクラスの前方宣言がないと困ること
Chrome/Safari でスマホサイズの表示テストをする方法
スマホ用のWebページ(アプリ)なんかを作っていると、Chrome や Safari でその画面サイズで表示を確認したいことが多いですよね。インスペクタ便利だし。実機とかエミュレータとかめんどくさい。
一般的なスマホの画面サイズ 320 x 480 にブラウザのウインドウサイズを変更すれば、メディアクエリとかで自動的に表示を切り替えてくれるはず。が、私のMacだとなぜか Chrome/Safariの横幅が 400px までしか縮められない!微妙に足りない!!(Windowsならもうちょっと縮むとか??)
サイズを変更する Chrome Extension とか試してみましたが、だめでした。やはり 400px 以下になりません。しかし、JavaScriptで別窓を開けば自由にリサイズできることが分かりました。
そこで、今見てる画面を、スマホサイズで別窓で開くブックマークレットを使うことにしました。
コードは以下の通り。
javascript:window.open(location.href, 'phone', 'width=320,height=480');
このアドレスを適当な名前(PhoneViewとか)でブックマークに登録しておくと、一発でスマホサイズで確認できて便利!(ブラウザのポップアップブロックにひっかかる場合があるので注意)
ほんとは UA とかも変えたかったけど、JSでは変更できないため断念。Extension作ればUAの変更できるらしいが、とりあえずそれはまた別の機会に。
Safari6 の Web インスペクタで行番号がずれる問題
前回の記事「iPhone5 と iOS6 での HTML5開発についてあれこれ」で書いたように、Safari6 の Web インスペクタで iOSのリモートでバッグが出来るようになりました!
が、また日本語(マルチバイト文字)を含むコードを表示すると行番号がずれている。。この問題は以前からあって、一応解決策もしたはずだった。参考: Safari の Webインスペクタで行番号がずれる問題を解決
しかし、Safariのバージョンが上がる度にこの辺りの設定箇所がコロコロ変わってしまうのです。Safari 5.0 までは /System/Library/Frameworks 以下にあった WebKit.framework が、Safari 5.1 では /System/Library/StagedFrameworks へ移動し、WebCore.framework となりました。(StagedFrameworks の説明はここが詳しい: 新・OS X ハッキング! 39 実は大きく変わった「Safari 5.1.4」)
それが、いつのまにやらまた /System/Library/PrivateFrameworks に移動されたようです。
で、とりあえず現在(Safari 6.0.1で確認)のパスはここ
/System/Library/PrivateFrameworks/WebInspector.framework/Versions/Current/Resources
ここにある、Main.css を編集します。ミニファイ化されているので、適当なエディタで展開するといいと思います。
.text-editor {
display: -webkit-box;
position: relative;
overflow: hidden;
/ 以下を追加 /
font-family: "好みのフォント", monospace;
font-size: 11px;
line-height: 13px;
}
編集内容は以前とほぼ同様。line-height が 13px とピクセル指定にしています。 .text-editor>.gutter>.line-number で指定されている物と合わせる必要があります。
ファイルを書き換えて管理者権限で保存し、Safari を再起動すると反映されます。
これで私の環境では直りましたが、まだ直らないようなら、こちらを参考にすると良いかもしれません。 Webインスペクタの行番号がズレてたら直しましょう
これで、リモートでバッグもばっちり!! と、いきたいところですが、Safari6 のWebインスペクタて使いにくいですよね。。 次回は使い方なんかを。
iPhone5 と iOS6 での HTML5開発についてあれこれ
本日、iOS6がリリースされましたね。明日は iPhone5 の発売日。Mobile Safari も大幅にアップデートされて、Web開発者にとって非常に気になります。
iPhone 5 and iOS 6 for HTML5 developers, a big step forward: web inspector, new APIs and more で素晴らしいまとめがありましたので、簡単に紹介したいと思います。
iPhone5
新しい画面サイズ
新しい 4インチ画面になり、解像度は WDVGA (Wide Double VGA) 640×1136px になりました。横幅はこれまでと変わりませんが、高さが 176px 増えました。
新しいシミュレーター
Xcode4が新しくなり、iOS6のシミュレータが出ました。Mac AppStore からダウンロードできます。
何をすべきか
画面サイズに依存したWebサイト(アプリ)は注意が必要です。縦幅が足りなくなります。Google Mapsの例のように、下が切れます。
レスポンシブWebデザインを使っていても不十分です。通常RWDは横幅に対して使われますが縦には使われていません。
デバイスの検出
サーバーサイドでiPhone5を検出する方法はありません。userAgent は iOS6 としか判定できません。iOS6 の載った iPhone4/4s と区別不能です。
しかし、JavaScript か メディアクエリーを使えば判定できます。スクリーンの高さが 568px の時は 4インチディスプレイになります。
isPhone4inches = (window.screen.height==568);
また、CSSメディアクエリーとレスポンシブWebデザインのテクニックでiPhone5を判定できます。
@media (device-height: 568px) and (-webkit-min-device-pixel-ratio: 2) { /* iPhone 5 or iPod Touch 5th generation */ }
ホームスクリーンWebアプリ
ホームにWebアプリを追加すると、上下にレターボックスが表示され、今までの画面サイズと同じように表示されます。しかし、4インチに対応したWebサイト(アプリ)でもこうなってしまう問題があります。
iOS6 での HTML5
ファイル管理
Web Audoi API
Smart App Banner
CSS3 Filter
CSS3 Cross-Fade
フルスクリーン Safari
Animation Timing API
CSS Image Set
Passbook クーポンとパスの配布
Storage API と WebAppの更新
- Application Cache の制限が 25Mb に増えました。(これまでは約5M)
- ホームスクリーンWebAppは独自のストレージサンドボックスを持つようになりました。
(追加する度に新しいストレージを持つようになったため、複数アプリの切り替えにはよいニュースです。Webサイトとホームの間でデータのやりとりをするには問題があります。) - ホームスクリーンWebAppのタイトルが定義できるようになりました。これまではサイトのページタイトルが使われていたのが、別名を定義できるようになりました。
WebView の更新
リモート デバッギング
- HTML、CSS の確認とライブ変更
- ストレージへのアクセス: クッキー、Local Storage、Session Storage、SQL Database。
- webapp のプロファイル: ネットワークリクエスト、レイアウト&レンダリング、JavaScript、イベントのパフォーマンスレポート。パフォーマンスツールの大きな進歩です。
- DOMの検索
- 全ての警告とエラーを一カ所で確認
- worker thread の管理
- JavaScript ブレークポイントの管理、キャッチしない例外のブレーク
- コンソールへのアクセスとJavaScriptの実行
- JavaScriptコードのデバッグ
- 対象の要素をタッチしてインスペクトする
その他の小さなアップデート
- JavaScriptのパフォーマンスが 20%向上
- Google Maps が iOS6 から使えなくなる。http://maps.google.com へのアクセスは ネイティブアプリではなく、GoogleMapsのWebサイトへリダイレクトされる。そこで、ネイティブマップアプリを開く新しいURLスキーマができた。maps:?=<query> queryはまさに検索文字列か、緯度経度をいれる。ルートナビゲーションを開始するパラメータは次のようになる。maps:?saddr=<source>&daddr=<destination>
- XHR2: XMLHttpRequestProgressEvent をサポート
- input の autocomplete を公式サポート
- DOM4 の Mutation Observers を実装。WebKitMutationObserver で DOMの変更をキャッチできる。
- -webkit-transform: preserve-3d でのハードウェアアクセラレーションの廃止。パフォーマンステクニックとしてこれを使うことは止めるべきだ。
- window.selection による Selection API
- <keygen> 要素
- Canvas アップデート: createImageData の引数は1つになり、二つの関数が増えた。高解像度対応の、webkitGetImageDataHD と webkitPutImageDataHD。
- SVGプロセッサとイベントの更新
- 新しい CSS viewport が結びつけられた。 vh (viewport height), vw (viewport width) と、vmin(vw と vh の最小値)
- CSS3 Exclusions と CSS Regions が β1で利用可能だったが、最終バージョンで削除された。
- iCloud タブ。Mac、iPhone、iPadでタブを同期することが出来る。そのため同じURLが全てのデバイスへ配布される。モバイルWebのアーキテクチャに気をつける必要がある。
以上、 iPhone 5 and iOS 6 for HTML5 developers, a big step forward: web inspector, new APIs and more の紹介でした!あとちょっと、「まだ待っているもの」、「最後に」と続きますが、そこは割愛。気になる方は是非原文を読んで下さい。かなり意訳&はしょったところもありますので、ご指摘&コメント歓迎です。
個人的に今回の目玉はやはり リモートWebインスペクターに限りますね!特にプロファイラとブレークポイントが泣けるほど嬉しい!これを切望したWeb開発者も大勢いると思います。
HTML5 x Touch UI の UXを考える(補足)
昨日、ありえるえりあミニ勉強会#3 ~Sencha Touch で、「HTML5 x Touch UI の UXを考える」 を発表しました。 発表資料は こちら HTML5 × Touch UI の UX を考える
川野さんの「Sencha Touch - カスタムコンポーネントを作るためにおさえておきたい 10 のステップ」、森本さんの「About Sencha Architect」も非常に面白く、勉強になりました!Sencha 使ってない方でも勉強になるかと思いますので、ぜひ次回でも覗いてみて下さい!
そして、懇親会も楽しかった!まさかみんな Sublime Text 2 ユーザーになっているとはw 他にも Inkpod(Desktop版) を使ったことあるという方もいてびっくり!色々と刺激を受けることが出来ました。
帰って Ust で自分の発表見直してみたら、やたらと咳払いが多いですね。。。あと、ちょこちょこ移動したせいで音声が聞こえないところもチラホラ。せっかくマイク用意してもらったのに。。等々 お聞き苦しいところも多々有り申し訳ないです(−−; 今後改善したいと思います。
さて、このEntryでは、資料では書ききれなかった点、こぼれ話なんかを補足したいと思います。
Touch Position (p.5)
Nikkei BP さんの記事 iPhone/iPadに込められた「見えないデザイン」を参考にさせて頂きました。この話は、あくまで特許から実装されている機能を予測する、というもので、実際にはどうなのか検証された方もいました。日経BP『iPhone/iPadには”見えないデザイン”が込められてる』記事がホントかどうか検証してみた(エミュレータ編)
少なくともエミュレータでは6角形ではないようです。ただ、当たり判定についてはやはり動的に変わっているように見えます。iPhoneでソフトウェアキーボードを英語で表示して、「S」キー(少し左寄り)を連打すると、「Sa」と入力されます。Xperiaなどではキーピッチが見た目自体可変でしたけど、iPhoneは内部的に可変の可能性が十分にあると思います。
また、iOSでは押した場所(実際にタッチされた箇所)よりも確実に、少し上が認識されます。指で普通に使う分にはむしろ自然に狙った位置がポイントされます。タッチペンをつかってもあまり違和感を感じません。しかし、タッチペンを垂直に立てるなどすると、上向きにずれているのがよく分かります。逆さにしても同様。ボタンがタッチにしにくくなるのがわかります。
これは斜めに画面にタッチすることを想定し、指(またはペン)の軸の延長線上をタッチポイントとしたほうが自然と感じるのだと思われます。HW的なタッチエリアの楕円形状や扁平率から、傾きを検知し、ずらす量を調整、までしていればすごいんだけど、そこまではやっていないようです。
なお、Android(2.3,3.0,4.0で検証)ではこの上方向への補正は感じられません。恐らくAppleの特許が影響しているのではないかと思います。
Touch Feedback (p.6)
視覚フィードバックの他に、バイブレーションを使う方法もあります。Androidなんかでは結構使われています。iOS で使われていないのは特許のせいかポリシーかは分かりません。
Webで使うには、Vibration API というのが現在仕様策定中です。以下のように使えるようです。
navigator.vibrate(1000);
ただ、2012/07/27現在、これが使えるのは Firefox Aurora Preview(Android 4.0以上)のみだとのことです。
Touch Event Specification (p.8)
jQuery の中の人のBlog jQuery Blog: GETTING TOUCHY ABOUT PATENTS で、タッチイベントの歴史、現在の状況、将来、について非常に良くまとめられています。MSPointerが技術的には将来有望だとみている点など、興味深い話です。
Touch Event Interface (p.10)
W3Cの仕様で最後の Editor's Draft で大変興味深い仕様がありました。
Touch Events version 2 W3C Editor's Draft 14 November 2011
TouchEvent に radiusX, radiusY, rotationAngle というプロパティがあります。これは、タッチした範囲の楕円半径と、その傾き角度。つまり、タッチエリアのrawデータがとれるということです。
これが使えれば、上述の指の傾きを検知してずらす量を調整などもアプリ側でできるかもしれない。是非とも仕様に入れて欲しい!
TouchEvent のはまり所
touchEvent ではまりそうな所を2点。
touchEvent は現在タッチされているポイントを、touches、changedTouches, targetTouches というプロパティとして持っています。touches はすべてのタッチ、changedTouches は変更があった点、targetTouches はその要素上のタッチの配列として取得できます。
注意するのは、toucheend イベントの時、touches は空になっている、という事です。既に指が離れたため、現在タッチしている点は無いよ、ということなのだと思います。そのため、離れたタッチを取得するには changedTouches を使用します。
二つ目は、 2本以上で同時にタッチした時、touchstart イベントが1回の場合と2回発生する場合がある。ということ。
完全に同時にタッチしたときはtouchstart イベントは1回だけ発生し、changedTouchesに二つのタッチが入ります。わずかでもタイミングがずれると、touchstart イベントは2回発生し、それぞれ changedTouches に 1つずつ入ります。
なので、マルチタッチ操作を実装する場合、どちらでも動くように対応する必要があります。
GestureEvent (p.11)
ジェスチャーイベントの発生順序は少し癖があるため、注意が必要です。
GestureEvent Class Reference に詳しくありますが、タッチイベントとジェスチャーイベントの発生順序は以下のようになっています。
- touchstart: 1本目の指がタッチ。
- gesturestart: 2本目の指が触れると gesturestart が発生。
- touchstart: 2本目の指のタッチイベント
- gesturechange: 指を離さず、動かしたときに発生
- touchmove: 動いた指のタッチイベント
- gestureend: 2本目の指が離れたら(指が残り1本になったら)発生
- touchend: 2本目の指が離れたタッチイベント
- touchend: 最後の指が離れたタッチイベント
GestureEvent は touches プロパティをもっていません。そのため、タッチポイントを取りたいときは、TouchEvent で取得したものを保持しておく必要があります。
しかし、上記の順序 2. で、まだ2本目の指の touchstart イベントが来る前に、先にジェスチャーイベントが発生します。このとき、まだ touches は 1 つしかないのため、2つのTouchを取得できません。
User action event restrictions (p.21)
私が勝手に命名しました(^^;
キーボードが出ない理由にはついては不明ですが、動画の再生については Apple から説明があります。
- Safari HTML5 Audio and Video Guide: Audio and Video HTML
- 参考: iPhone Safariだとaudio/videoタグのautoplay, autobuffer属性が効かない
携帯が従量課金とかの可能性があるから、autoplayとautobufferは無効にしてるよ。ユーザが意図して再生を開始するまで、データはロードされないよ。
ということだそうです。
ちなみに、Sencha Touch (1.1の場合) でこれらを操作するために、ちょっとした裏技があります。Sencha Touch では通常ブラウザが出すクリックイベントは抑止して出ないようになっていますが、以下のコードをアプリ起動前に設定することで、デフォルトのクリックイベントを抑止しません。
Ext.gesture.Manager.defaultPreventedMouseEvents = [];
これを設定すると、ブラウザが出すクリックイベントと、Sencah Touch がエミュレートしたものと2個発生します。Sencha Touch がエミュレートしたクリックイベントは isSimulated フラグが true になるので、それでどちらか判断できます。
ブラウザが出す clickイベントの方で、これらの制限機能を使うことができるようになります。
Scroller (p.22)
iScroll は素晴らしいのですが、全画面でのスクロールのみになってしまいます。App Storeのサムネイルみたいに、部分的にスクロール対応したい時もあります。そういう時は以下のjQueryプラグインが便利です。
flickGal・・・iPhoneでフリックギャラリーを簡単に実装できるjQueryプラグインです
ただ、惜しいかな縦/横スクロールのロックがありません。そこで、githubで公開されているものをフォークして、スクロール方向ロックオプションを付けたものをアップしました。
https://github.com/dsuket/flickGal
lockDirection を true にすると、 scrollMargin 分動くまでスクロールを待機し、動き出した後はその方向でロックします。
HTML5 × Touch UI の UX を考える
今日、 ありえるえりあミニ勉強会#3 ~Sencha Touch で 「HTML5 x Touch UI の UXを考える」というタイトルで発表してきます。
その資料がとりあえず出来たので、一足お先に こちらで公開します。