Hatena::ブログ(Diary)

Over&Out その後 このページをアンテナに追加 RSSフィード Twitter

2015-07-14

watchOS 2 の Core Graphics は何ができて何ができないのか #potatotips

本日開催された、「【第19回】potatotips」にて、watchOS 2 における Core Graphics について発表をさせていただきました。



概要

watchOS 1 では Core Graphics が使えなかったので、次のような UI を実現するにあたって、


f:id:shu223:20150214162301p:image:w600


Appleのサンプル「Lister」では、360個の連番pngを使用するという相当な力技でやっていたことは記憶に新しいところです。


f:id:shu223:20150714210052p:image:w425


で、watchOS 2 でついに Core Graphics が使えるようになったわけですが、発表されて1ヶ月経過した今も、(自分の探し方が悪いのか、)10本ぐらいあるAppleのWWDC動画にもサンプルにも、GitHub や StackOverflow にも未だに具体的なコードは見当たりませんでした


単にまだ誰も書いてないというだけかもしれないし、何か重要なクラスが watchOS 上で使えないとかで結局使えないのかもしれない、実際に試してみないとわからない・・・ということで何ができて何ができないのか、検証コードを書いて確認してみました。


ポイント

詳細はスライドを見ていただくとして、ここではポイントだけ。

  • watchOS では UIGraphicsGetCurrentContext() でグラフィックス コンテキストを取得できない
  • ビットマップコンテキストを作成し、そこに描画 → ビットマップコンテキストから UIImage を生成して WKInterfaceImage や WKInterfaceGroup に表示すればOK

(2015.7.21 修正)@hoppenichu 様よりご指摘&Pull Request をいただき、上記に間違いがあることがわかりました。(打ち消し線を入れた箇所)


UIGraphicsBeginImageContext() すれば、 UIGraphicsGetCurrentContext() でグラフィックス コンテキストを取得できます


また僕の当初のサンプルでは UIGraphicsBeginImageContext() したあとさらに CGBitmapContextCreate() でビットマップコンテキストを生成していましたが、Beginの時点で既に生成されているので、このステップは必要ないということになります。


// Create a graphics context
let size = CGSizeMake(100, 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()

// Setup for the path appearance
CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().CGColor)
CGContextSetLineWidth(context, 4.0)

// Draw lines
CGContextBeginPath (context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 100, 100);
CGContextMoveToPoint(context, 0, 100);
CGContextAddLineToPoint(context, 100, 0);
CGContextStrokePath(context);

// Convert to UIImage
let cgimage = CGBitmapContextCreateImage(context);
let uiimage = UIImage(CGImage: cgimage!)

// End the graphics context
UIGraphicsEndImageContext()

image.setImage(uiimage)

こちらの commit を見ると、間違いをどう修正していただいたかわかります。(修正ここまで)


うまくいったこと
  • CGPath を用いたパス描画
  • UIBezierPath を用いたパス描画
  • SVG ファイルからのパス描画
  • グラデーション描画

(描画の話なのに、NDAにつきまだスクショ貼れないのが残念。。)


watchOS の Core Graphics でできないこと

グラフィックスコンテキストの問題が解決できたことで、結構いろいろなことができることがわかったわけですが、基本的に CALayer や UIView の API を使う必要がある処理は実現できません。スライドでは例として下記3つを挙げています。

  • スクリーンキャプチャ
    • UIView または CALayer の内容をコンテキストに描画する必要がある
  • キーパスアニメーション
    • AddAnimation: しようにも CALayer オブジェクトにアクセスできない
  • 手書き
    • タッチイベントを取るAPIがまだ開放されていない

キーパスアニメーションができないということは、冒頭に挙げたような Circular Progress 的な UI の実現も結局難しい、ということになりますね。。(アニメーションの各フレームを UIImage として生成することもできますが、非現実的な方法かと)


おわりに

最初 UIGraphicsGetCurrentContext() でグラフィックスコンテキストが取得できず、ググってもあまり情報が見当たらなかったときは「もしかして何もできないのか・・・!?」と思いましたが、上述のようにそこは解決して、パス描画やグラデーション描画などなど、結構いろんなことができました。


ただ最後に書いたように、タッチイベントが取れない、キーパスアニメーションが使えない、という大きな制約もまだあるので、「Apple製アプリではできてサードパーティにはできない」ことというのは色々とありそうです。手書きの筆跡を共有する 「Digital Touch」的なこととか、Circular Progress的なUIを動的に描画するとか。



2015-07-02

WWDC15のチケットは外れたけどサンフランシスコに行ってきたメモ

タイトルの通り、今年はWWDCのチケットは残念ながら外れてしまったのですが、初参加した昨年を振り返ってみると

  • セッションを(英語力と理解力と集中力の点で)リアルタイムで理解できない
  • → セッション中にドキュメント等で勉強しようとする
  • → セッション会場は(椅子間の距離が)狭いし、ネットも遅い
  • 1Fのネットコーナーに入り浸る

という、日本でもできる、というかむしろ日本での方が快適にできる過ごし方をしていたわけで、良かったのは何よりもその「iOSエンジニアの祭典」的空気感なわけで、じゃあチケットなくても行く価値はあるかも、ということで航空券購入に踏み切りました。旅程は 6/6 〜 6/15 の 8泊10日。


やったこと

ヨセミテ旅行

WWDCが始まる前の土日を利用して、iOSエンジニア4人でヨセミテへ行ってきました。シリコンバレーには何度か来ているものの、なかなか観光をする機会がなかったので、今回が初。


空港で集合し、レンタカーでそのままヨセミテ方面へ。宿はヨセミテ内ではなく、そこから車で1時間ぐらいの、別荘地的なところ。


f:id:shu223:20150703093037j:image:w600

f:id:shu223:20150703093034j:image:w600


Airbnbで(Tonnyさんが)予約してくれたところなのですが、雰囲気があって超よかったです。



ヨセミテも想像以上に楽しかった。


f:id:shu223:20150607100935j:image:w600

(川遊び)


f:id:shu223:20150703042256j:image:w600

(某El Capitan)


f:id:shu223:20150703034635j:image:w400

(なぜか乗せてもらえた本場のハーレー!)


日々もくもく開発@Realm オフィス

サンフランシスコの Realm オフィスのモニタで、みんなで基調講演のストリーミングを見ました。


f:id:shu223:20150703034810j:image:w400

(広くて綺麗で快適でした)


Realmオフィスへは基調講演以降もほぼ毎日お邪魔し、もくもくドキュメント見ては手を動かして新機能を試してました。


f:id:shu223:20150703034918j:image:w400

(ランチ風景)


f:id:shu223:20150703035002j:image:w400

(念願のTシャツもいただきました。愛用してます)


StackOverflow デビュー

StackOverflow でいくつかの質問に回答し、Reputation もいくらかつき、ついに自分も vote up やコメントができるようになりました。

今まで、「なんて素晴らしい回答だ!ありがとう!」と思っても vote up する権利すらない自分の無力さを何度歯痒く思ったことか。。


StackOverflow の Reputation は GitHub 同様に世界で通用する客観的&定量的評価だし、英語の練習になるし、人の役にも立つ、ということで自分の中でずっと重要TODOだったのですが、日々の仕事を言い訳にずっと後回しにしてきたことなので、非常に達成感があります。


HomeKit 対応デバイス購入

iOS 8 で発表された HomeKit、IoT の文脈から注目はされていたものの、対応製品がない、という状況がずっと続いていました。で、最近ぽつぽつと製品が出始めている、ということでサンフランシスコの Apple Store に行ってゲットしてきました。


f:id:shu223:20150703035336j:image:w400


Lutron社の「Caséta Wireless」という製品です。229ドルもしました。とりあえず HomeKit を体験したいだけなのでもっと安いのを・・・と店内の製品パッケージをくまなく探してみましたが、残念ながらこれしか置いてないようなので購入。


後日またブログかLT等で使用&実装報告したいと思います。


WHILL HQ 訪問、野球観戦など

昨年のTechHouse内オフィスから移転したWHILLの米国本社や、とある企業のオフィス等に遊びに行きました。


f:id:shu223:20150703035436j:image:w400



あと人生初の野球観戦。


f:id:shu223:20150703035511j:image:w400


ホットドッグ&ビール&野球という経験ができてよかったです。


Apple Watchハッカソン参戦

最終日、ちょうどSFでAppleWatchハッカソンが開催されてたので参戦。


なんと、賞をいただいてしまいました!!!!


f:id:shu223:20150614131616j:image:w400


つくったのは watchOS-2-Sampler。コミュニティへの貢献を評価していただけたようです。めっちゃ嬉しかったです。


ちなみに英語プレゼンはアドリブでは絶対にグダグダになる自信があったので、いったん話したいことを全部書き出して、流れだけ頭に入れつつ反復練習して、ハック中に話しかけてくれた優しそうな現地の人に聞いてもらったりもしました。


後日談として、こういうこともありました。


やっぱ海外でハッカソンに参加するのは楽しい。


費用

気になるお値段ですが、

  • 飛行機代:¥125,140
  • 宿代:¥44,860($45 × 8 × 124.6)

で、基本費用は17万円程度。40万オーバーだった昨年と比べて、大幅にコストダウンしました。WWDCチケット代がかからなかったのと、宿を全泊TechHouseにしたのが効いたな―と。(TechHouseについては昨年の記事をご参照ください)


あとは日々の食費、ヨセミテ旅行費(レンタカー+宿。手渡しだったのでいくらか忘れた。。)、野球観戦のチケット代(確か8000円ちょい)がかかってるので、総旅行費用としては20万円ちょいかと。


LT

せっかくSFの空気に触れて高まった意識も、帰国して日々の仕事の波にさらされるとあっという間に消えてなくなるので、「人前で発表しないといけないプレッシャー」ドリブンで勉強を進めるべく、WWDC関連の勉強会にはできるだけLT枠で申し込みをするようにしました。


6/16 「potatotips #18」


ブログ:watchOS 2 新機能の細かい話5つ #potatotips - Over&Out その後


6/17 「UI Crunch #5 スマートウォッチUIデザインの今」


ブログ:UI/UX に影響の大きい watchOS 2 の新機能 3つ #uicrunch - Over&Out その後


6/19 「WWDC Afterparty Roppongi」


ブログ:【iOS9】Core Image の新機能:文字認識/追加フィルタ47種 - Over&Out その後


6/24 「WWDC2015報告共有会@ネクスト」


ブログ:【iOS9】Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜 - Over&Out その後


所感

チケットなしWWDC、ものすごく行ってよかったです。ドキュメント見るなら日本でもできる、とはいえ日本にいたら絶対仕事を入れてしまってドキュメント見たりサンプルつくってみたりLTしたりしなかったと思うので。


あと、WWDCのチケットがあると、高いチケット代払ってるので朝ちゃんと起きてフルに会場にいないといけないという気がどうしてもしてしまってなかなかしんどいのですが、そういうプレッシャーもなく健やかな気持ちで日々を過ごせたのもよかったです。結局毎日ドキュメント見てコード書いてたわけですが、義務感があるのとないのとでは健やか度がだいぶ違うなと。


それと、Realmオフィス。Realm の中の人をはじめ、CocoaPods の中の人や RestKit の中の人など、真のスーパーハッカーな方々が集う場で、なんというかそこにいるだけで「もっと精進せねば・・・」と意識が高まりました。


そんなこんなで、来年もチケット外れてもまた行きたい所存です。現地でお世話になった皆様方、ありがとうございました!


2009 | 08 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 11 | 12 |
2017 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2018 | 02 |