Hatena::ブログ(Diary)

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

2014-06-23

CIKernelを使ったカスタムフィルタのつくりかた

Core Image の CIFilter でいろいろなフィルタ処理(画像処理/画像加工)ができるのはみなさまよくご存知かと思いますが、iOS 8 では CIKernel というクラスが追加され、そのフィルタ(CIFilter)を自作できるようになりました。


本記事は、その作成手順について、6/20日に開催された WWDC 2014 振り返り勉強会で発表したものです。もともとアップしないつもりで Markdown でスライドをつくった のをそのまま貼り付けてるので、少々読みづらい部分があるかもしれません。


同勉強会では、この CIKernel の内容がちょっとしかなかったので、同じく iOS 8 の新機能である HealthKit、HomeKit を対応デバイスなしですぐに試す方法 についても話しました。


また(ちょっと古いですが、)Core Image、画像処理関連の記事は他にもいろいろと書いているので、よろしければご参照ください。


CIKernel とは

  • フィルタを自作できる
  • OS X では以前からあった

CIKernelのつくりかた

カーネルはOpenGLのシェーディング言語で書く

kernel vec4 swapRedAndGreenAmount ( __sample s, float amount )
                  { return mix(s.rgba, s.grba, amount); }

文字列として CIKernel の初期化メソッドに渡す

CIKernel *kernel = [CIKernel kernelWithString:kernelStr];

CIKernel を適用する

こんな感じ

- (CIImage *)outputImage
{
    return [[self myKernel] applyWithExtent:self.inputImage.extent
                                  arguments:@[self.inputImage, self.inputAmount]];
}

CIFilter サブクラスをつくる

自作 CIKernel をつかって、CIFilter サブクラスをつくる。

@interface MyFilter : CIFilter

@property (nonatomic, strong) CIImage *inputImage;
@property (nonatomic, copy) NSNumber *inputAmount;

@end

(実装は省略。WWDCスライドにあります)


フィルタとしての使い方は普通の CIFilter と同じ

NSDictionary *params = @{kCIInputImageKey: ciImage,
                         @"inputAmount": @(1.0),
                         };
CIFilter *filter = [CIFilter filterWithName:@"MyFilter"
                        withInputParameters:params];

デモ

(自分で実装したやつがあるのですがスクショは微妙なところなのでWWDCセッションスライドのを貼っておきます。)


f:id:shu223:20140623080037p:image:w600


参考資料

動画
  • Developing Core Image Filter for iOS (515)
Dev Center
  • CIKernel Class Reference (現状 OS X 版のみ

2014-06-22

【iOS8】いますぐ試せる HealthKit & HomeKit

iOS 8 の新機能の中でも個人的に気になったのが HomeKit と HealthKit。でも何ができるのか、実際どうやって使うのか、どこまでAPIが開発者に公開されてるのか、発表だけ聞いてもいまいちピンと来ません。


実際に自分で試してみるのが一番です。


そんなわけで、HealthKit、HomeKit を対応デバイスなしでいますぐ試す方法 について6/14日に開催された yidev 第15回勉強会で、表題の内容で発表してきました。


スライドはアップしないつもりだったのでKeynoteではなく Markdown でスライドをつくった のですが、世間的にWWDCの動画(今年のは一般公開されてる)ぐらいまでなら全然OKだよねっていう雰囲気っぽいのでここに内容を貼り付けておきます。


自己紹介

  • フリーランスiOSデベロッパー
  • ブログ:Over&Out その後
  • 著書:iOSアプリ開発 達人のレシピ100


HealthKit

HealthKit でできること

  • 健康、運動データの保存、アクセス
  • セキュリティ、プライバシー設定
  • 検索、統計クエリ
  • 単位変換
  • 新データの通知
  • アクセサリーの統合

とりあえずデバイス繋いで使ってみる

HealthKit デバイスの接続方法

  • APIを探しても見当たらない
  • WWDCセッション動画 "Introducing HealthKit"を見ても見当たらない

iOS8に標準で付いてくる "Health" アプリを利用する


f:id:shu223:20140623070334p:image:w300


対応デバイスを用意する

HealthKit 対応デバイス

"HealthKit対応"を謳ったものは当然まだない


→ BLEの標準プロファイルをサポートしてるので既存デバイスで普通に繋がる

  • Heart Rate Monitor
  • Glucose Sensor
  • Blood Pressure Monitor
  • Health Thermometer

対応デバイスを買いたくない

わりと高い。。


対応デバイスを代用する

iPhoneでエミュレートする
  • Core Bluetooth で実装する
  • アプリを使用する(例:LightBlue)
BLEモジュールにファームを書き込む
  • 例:BLE113 Development Kit

参考:BLE112 / 113 の開発環境を Mac に構築する - Over&Out その後


デモ


公式サンプル "Fit" のビルド方法

【iOS8】HealthKit の Apple 公式サンプルを実機で動作させようとすると出るエラーの対処方法 - Over&Out その後


参考資料

動画
  • Designing Accessories for iOS and OS X (701)
  • Introducing HealthKit (203)
Dev Center
  • HealthKitのサンプルコード
  • クラスリファレンスはまだない

HomeKit

HomeKitとは?

  • 各種アクセサリを独自のプロトコルで統一する
    • アクセサリ:鍵、照明、カメラ、ドア、サーモスタットetc...
  • ユーザ別にデバイスを制御する方法や、デバイスをGroup化して制御する機構を提供する

f:id:shu223:20140623071158p:image:w500


デバイス接続手段

  • Bluetooth Low Energy
  • IP

HomeKit Accessory Profiles

f:id:shu223:20140623070906p:image:w500

  • → Service, Characteristicって、BLEのGATTベースプロファイル?
  • NO!

HomeKit Accessory Protocol Layers

f:id:shu223:20140623070646p:image:w500


BLE の GATT、IP の JSON をラップする独自プロトコル


プロトコルやプロファイルの仕様は?

f:id:shu223:20140623070725p:image:w500


要MFi


では、試せないのか?

Home Kit Accessory Simulator

起動方法

[Xcode] > [Open Developer Tool] > [Home Kit Accessory Simulator]


新規アクセサリ作成

[+] > [New Accessory]


f:id:shu223:20140623072048p:image:w600


  • サービス追加
    • Add Light Bulb
    • Add Garage Door Opener
    • Add Thermostat
    • Add Lock
    • Add Switch
  • 有効化
    • スイッチをONに

f:id:shu223:20140623071114p:image:w600


同じ WiFi 内ならこれでアクセサリとして HMAccessoryBrowser から発見できる。


実装方法

(実はこれはプレゼンでは説明してないのですが、簡単に。)

マネージャ生成
self.homeManager = [[HMHomeManager alloc] init];
self.homeManager.delegate = self;
家を生成
[self.homeManager addHomeWithName:@"First Home"
                completionHandler:^(HMHome *home, NSError *error) {
                    
                    if (error) {
                        NSLog(@"error:%@", error);
                        return;
                    }
                }];
部屋を生成して家にaddする
[home addRoomWithName:@"First Room"
    completionHandler:^(HMRoom *room, NSError *error) {
        
        if (error) {
            NSLog(@"error:%@", error);
        }
        else {
            NSLog(@"success!");
        }
    }
];
アクセサリ(周辺デバイス)を探す
self.accessoryBrowser = [[HMAccessoryBrowser alloc] init];
self.accessoryBrowser.delegate = self;

[self.accessoryBrowser startSearchingForNewAccessories];

デリゲートメソッドまわりは省略。


Siri連携

(口頭で話しただけ)


参考資料

動画
  • Designing Accessories for iOS and OS X (701)
  • Introducing HomeKit (213)
Dev Center
  • Home Kit の各クラスリファレンス
  • サンプルはまだない

See Also


ご清聴ありがとうございました!


2014-06-21

【書評】中級者向けのUIKit解説本『UIKit徹底解説』

インプレスジャパン様より *1 献本いただきました。


UIKit徹底解説 iOSユーザーインターフェイスの開発
西方 夏子
インプレスジャパン
売り上げランキング: 8,651


著者の西方夏子さんは、『上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編』の

  • Chapter02:「画面遷移」
  • Chapter03:「UIKit Dynamics」

等々を執筆されていた方で、僕も iOS 7 から入った「カスタム画面遷移」「インタラクティブ画面遷移」はこの書籍のサンプルで勉強させていただきました。*2


ブログの記事も書籍のように詳しくわかりやすく、いつも参考にさせていただいています。



で、今回の『UIKit徹底解説』ですが、中級者向けUIKit専門書とのこと。UIKitはiOSアプリ開発の主役なので解説書こそ多いものの、中級者以上を対象としたものはあまりないので、ありがたく拝読させていただきました。


難易度について

実際に読んでみて、難易度の点では、わりと「脱初級した人」ぐらいから読んでも大丈夫かも、という印象を持ちました。


たとえば Auto Layout の章で言うと、制約の優先度についてかなり詳しく書いてある部分は中級者向けだなと思う一方、IB から Auto Layout 設定する方法についてはスクリーンキャプチャ付きで書いてあるので、「Auto Layout をこれから使う人」にも読めるかなと。全体的に IB を使う部分は最初の一歩目としても大丈夫そうです。


またChapter10〜12は、それぞれテーブルビュー、コレクションビュー、コンテナビューコントローラの使い方/つくりかたをチュートリアル形式でちょっとずつ応用を加えながら学べるようになっているので、プログラムの話を文章だけ読んでもよくわからん、という方にはこの辺りからやってみるといいのかなと。


勉強になった項目

以下、勉強になった項目を書いていきます。

ライフサイクル

ライフサイクルについて、

  • Storyboardを使ってる場合はどうなるか
  • それぞれのメソッドにおいてsuperは呼ぶべきなのかどうか
    • たとえば loadView をオーバーライドする場合は super のは呼び出さず、すべてのビューを自前で生成することが推奨されているとのこと

等々を再確認できました。


あと、知らなかったのが isMovingToParentViewController というプロパティ。viewWillAppear や viewDidAppear が呼ばれるタイミングで、なぜコンテナに追加されたのかを知ることができる、とのこと。つまり、push されてここに来たのか、pop されて来たのかがわかるということ(そうは書いてないけど、そう理解しました)。これはありがたい。

レイアウト

iOS 7 が出たときに誰もが経験したと思われる、UINavigationBar の下にビューが潜り込む問題。対症療法的なものや微妙に誤解のある解説などWebには玉石混淆の情報が入り乱れていましたが、こちらの書籍ではフルスクリーンレイアウトについて関連プロパティがひとつひとつ解説されていて、正しく理解することができます。


またサブビューの再レイアウト処理の順序も勉強になりました。

  • Auto Layout無効のときの AutosizingMask に応じた自動サイズ調整処理は viewWillLayoutSubviews より前に行われる
  • layoutSubviews は viewWillLayoutSubviews の後、viewDidLayoutSubviews の前に呼ばれる

とか。

UIFontDescriptor

フォント属性を管理するクラス、UIFontDescriptor について詳細に解説されています。

  • フォントにアフィン変換を適用できる UIFontDescriptorMatrixAttribute
  • カスケードリストを追加して日本語だけ別フォントを使う方法
  • グリフの送り幅の変更

等々、参考になりました。

NSAttributedString, Text Kit

この2つについてもかなり詳しく書かれています。テキストレイアウトまわりで何かやりたいときにリファレンスとして良さそうです。


その他

上記には挙げていませんが、Stroryboard や Auto Layout や UIAppearance や UICollectionView や画面遷移等々、UIKit 全般について基本的なことから細かい話まで書かれています。詳細な目次はこちらで確認できます。


僕は インプレスジャパン発行の iOS 解説書シリーズは全部買ってる ので「Storyboardはあの本も詳しかったな」「UIAppearanceはあの本でも一通り解説されてたな」とか思ってしまうのですが、まだそういった書籍を揃えてない方にはこの本が全部入りかつ最新情報なのでお得なんじゃないかと思います。


電子書籍版

ちなみに国内出版社の技術書としては珍しく(?)もう電子版も出ています。700円ほどお得ですし、448ページと物量もあるので、個人的にはこちら(電子書籍)がオススメです。


UIKit徹底解説 iOSユーザーインターフェイスの開発
インプレスジャパン (2014-06-18)
売り上げランキング: 9,219


関連記事


*1@hkato さんより打診いただきました。いつもありがとうございます!

*2:カスタム画面遷移についてはこちらのサンプルもご参照ください:『iOSのカスタム画面遷移64種類を試せるサンプルコードを公開しました - Over&Out その後

2014-06-13

Markdownでプレゼン用スライドをつくる方法いろいろ

明日は 「yidev第十五回勉強会」、来週はクックパッドさん主催の 「WWDC2014 振り返り勉強会」で発表をさせていただく *1 のですが、まずMarkdownで話そうと思うことを適当にメモしてるうちに、なんか発表資料このままで良くない?と思えてきました。別にレイアウトや配色のセンスに自信があるわけでもなし


で、最初 "markdown pagination" でググってみるとあまりパッとしたのがなかったのですが、"markdown presentation" にしてみると出るわ出るわ。しかもどれも結構よさげ。


というわけで出てきたものをメモがてら書き留めておきます。結論からいうとググって一番上に出てきた "Remark" が今回の要件に(ほぼ)マッチしていたので、他はまだ使ってません。


Remark

http://remarkjs.com/

  • GitHubでソース公開されてて気軽に使える
    • 無料
    • ログイン不要
    • 不満があれば自分で修正してpull request送れる
  • Markdown が html ファイル内にあるので、Markdown エディタで編集しづらい

Swipe

http://beta.swipe.to/markdown/

  • テンプレートやフォントが複数用意されてる(っぽい)
  • 要ログイン
    • スライドを公開したい場合には長所でもある

Docset

http://www.decksetapp.com/

  • Mac アプリ
  • 19.99ドル

Reveal.js

https://github.com/hakimel/reveal.js/

  • HTMLやMarkdown等、テキストベースのスライドをつくれる
  • たぶんこの中では一番メジャー。日本語での紹介記事もたくさん出てる

Slidify

http://slidify.org/

  • サイトが10ブックマークされてるので国内でちょっと話題になったことがある?

*1:発表内容は使い回しではなく、どちらも全く別々の話をする予定です

2014-06-10

WWDC2014の旅 15泊17日を振り返る

まだサンフランシスコにいるのですが、もう帰る以外の予定はないので、遅ればせながら「WWDC2014の旅」を振り返ってみます。


旅程

シリコンバレーを訪れるのは、昨年9月に すぐにまた戻るつもりで帰国 して以来、結局一度も戻らなかったので実に 9ヵ月ぶり


せっかくなので他にもいろいろやっていこうということで、下記のようにWWDCの前後に6日間ずつの余裕を持たせた旅程にしました。

  • 5/27 日本発
  • 6/2〜6/6 WWDC
  • 6/12 日本着

やったこと

(WWDCに参加する以外には)特に具体的な予定がなかったのですが、知り合い繋がりでオフィスに遊びに行ったり、偶然街でバッタリ会ったりとかで、なんだかんだと充実した旅になりました。かまってくれた皆様どうもありがとうございました!


WHILL HQ訪問

TechShopという、FabLabの超でっかい版みたいな場所があり、そこにWHILLが米国オフィス(つまりHQ)を構えています。そこにお邪魔してきました。


f:id:shu223:20140610113419j:image:w400

(WHILL榊原さんの仕事風景)


TechShopには、3Dプリンタや3Dスキャナ、A0プリンタ、レーザーカッター等の定番マシンはもちろんのこと、


鉄を工作するための諸々の大型機械や、

f:id:shu223:20140610120007j:image:w600


木工用の大型機械、溶接するための台(?)、フォークリフトまであります。

f:id:shu223:20140610120144j:image:w600


ジャンク品コーナーや、無料ネジコーナーも。

f:id:shu223:20140610113811j:image:w400


いろいろと作業や打ち合わせもあり、今回の滞在中に3回お邪魔しました。


とあるベンチャーのアメリカ支部訪問

某有名Webサービスを運営する企業のアメリカ支部にお邪魔しました。(まだあまり情報公開したくないそうなので写真や場所について書くことは控えます)


オフィスもプロダクトももの凄く素敵で、技術的にも面白く、かなり刺激を受けました。


Kinoma 訪問

Kinoma Create を開発する Kinoma のオフィスにもお邪魔しました。


f:id:shu223:20140610114005j:image:w400

(逆光で見えづらいですが素敵なオフィスです)


開発中の Kinoma Create 実機やシミュレータ、コードなども見せていただきました。


f:id:shu223:20140610114047j:image:w400


f:id:shu223:20140610114158j:image:w400

(裏のピンにセンサを自由に追加できる)


f:id:shu223:20140610114157j:image:w400

(表にもピンが 8 x 2列あり、それぞれの役割をモニタから変更できる)


f:id:shu223:20140610114155j:image:w400

(シミュレータも用意されているので、デバイスが手元になくてもコーディング&テスト可能)


Indiegogo での注文分については 9月頃配送開始とのこと。一般発売が楽しみです!


お宅訪問

ぶらぶら散歩してたら知り合いの日本人エンジニア(バスケさん)と偶然遭遇!その辺りに住んでることも知らなかったので、お互い相当ビックリしました。


そしてそのままお宅訪問。


f:id:shu223:20140610114736j:image:w400


ちょうど引っ越しされる数日前で、「引っ越しの手伝い」という名の飲み会に参加させていただきました。


もくもく開発

とくに予定がない週末はカヤック時代の後輩 おかず と、Workshop Cafe でもくもく作業してました。


場所は BART の Montgomery 駅の近く。電源、WiFiがあり、しかも長居しやすいので、開発などに没頭したい場合にはおすすめです。


WWDC2014

初めて参加したわけですが、いやー 楽しかったですね。iOSのメジャーアップデートが発表されて、そりゃ開発者としてはできることが増えて嬉しいし、そういう情報を真っ先に聞ける、Appleの開発者に直接聞けるというメリットもありますが、それよりも何よりも、このプラットフォームでご飯食べてる人たちが世界中から集まってきてワイワイやってる、その空気感がたまらなく楽しかったです。


f:id:shu223:20140610114351j:image:w400

(あこがれのあのジャケットをもらいその場で記念撮影)


f:id:shu223:20140610114421j:image:w400

(早朝3時から基調講演の行列に並ぶ。いろんな人が暇つぶしにしゃべりにくるので、これがすごく楽しい)


f:id:shu223:20140610114418j:image:w400

(基調講演。3時から並んだわりにはわりと遠いw)


f:id:shu223:20140610114419j:image:w400

スペインに行ったときに会った Marcos がなんとアップルの中の人になってて再会!!!!一緒にランチ。)



技術情報的なところでは、既にいくつかブログに書いてるので、そちらもぜひ。


泊まったところ

Mission District

WWDCが始まるまでは、行ったことのないエリアに住んでみよう、とAirbnbで見つけたミッション地区のアパートに住んでみました。



閑静な住宅街で、AppleやFacebookの人たちも大勢このあたりに住んでいるそうです。(このあたりからクパチーノ行きのApple社員専用通勤バスが出ているとのこと)


WWDC会場近辺

近辺、といっても徒歩15分ちょいかかりますが、1泊90ドルで、WiFiも快適に繋がってなかなかいいホテルでした。



WWDCの期間+前後2日ずつで合計9日間滞在。


TechHouse

日本人が運営するシェアハウス。ここを運営されている長谷川さんと食事する機会があり、WWDC閉幕後の数日間はまだ宿を決めてなかったのでお世話になることに。

場所はBARTの Balboa Park 駅から徒歩で約12分のところにあります。



掃除が行き届いていて、すごくきれいで快適でした。


f:id:shu223:20140610114154j:image:w400


で、お値段がなんと1泊30ドル!Airbnbだと同じスペックで80ドルはするんじゃないかと。中心街までBARTですぐだし、とてもおすすめです。


費用

  • 飛行機代:¥126,850
  • WWDCチケット代:¥158,800
  • 宿代1:¥42,556
  • 宿代2:$720
  • 宿代3:$90

これだけで既に40万円オーバー。計算してませんが、上記プラス滞在中の食事やら電車賃も合計数万ぐらいはかかってるんじゃないかと思うと、なかなかの出費です。


さらに自分はフリーランスなので、仕事をしてない間は収入も止まります。その機会損失分も加味すると・・・


まとめ

  • 初のWWDC、行く前は不安だったけどめちゃくちゃ楽しかった
    • 心配してた英語は全然問題にならなかった。ラボで質問して聞き取れなかったらGoogle翻訳引っ張りだしてまで説明してくれた
  • WWDC以外の日々も充実してた。旅程を長めにとってよかった
  • こっちで会った何人かの「フルスタックエンジニア」は、サーバーサイド、iOS、Android、JSとかだけじゃなく、電子回路やファームウェア等のデバイス側もカバーしてて、もっともっと精進せねばと気が引き締まった
  • お金はかかるしWWDC情報なら日本で十分得られるけどこういう生の経験や交流はプライスレス。来年もチケット当選したらぜひ行きたい

現地でお世話になった皆様ありがとうございました!


2014-06-08

NDAについて、WWDCでAppleの中の人に聞いてみました

今年のWWDCでは例年に比べ Apple自身が公開してくれている情報 が多く、実質的にNDAが緩くなったといえます。


Appleが公開しているサンプルコードについてWWDCのラボで聞いてみた 際に、「今教えてくれたこと、ブログとかに書いていいんでしょうか?」と質問すると、次のような回答をくれました。


1. iOS Dev Center にログインする

2. Member Center に行く

3. [Your Account] > [Legal Agreements] > [iOS Developer Program License Agreement] を開く

4. "WWDC" で検索する (-> 10.1 Information Deemed Apple Confidential が引っかかる)

5. そこを読んでお前の弁護士と相談しろ


なるほど、すごく明快な回答です。WWDCに限らず、結局こういう系の話はこういう答えになるんだなと。


2014-06-07

【iOS8】HealthKit の Apple 公式サンプルを実機で動作させようとすると出るエラーの対処方法

アップルが公開している HealthKit のサンプル をビルドして実機にインストールしようとすると、


The excutable was signed with invalid entitlements.


というエラーが出てアプリが起動しません(2014年6月10日現在)。


この対処方法について、WWDCのラボで聞いてきました。

  • iOS Dev Center で プロファイルを作り直す
  • Bundle IDを新しいプロファイルに合わせて変更する
  • entitlements.plist の application-identifier の項を削除する

以上の手順で実機でも動作するようになりました。


プロファイルを作り直すときに、 使用する Identifier の HealthKit を Enabled にする のが最大のポイントです。


2014-06-06

【iOS8】App Extension の実装方法 その1:Action

App Extension とは?

App Extension (Extensions) は、iOS 8 から導入される、新しいアプリ間連携のしくみです。


f:id:shu223:20140606094505p:image


iOS では、以下の 6種類の Extension point *1を利用することができます。

  • Today
  • Share
  • Action
  • Photo Editing
  • Storage Provider
  • Custom keyboard

大まかな仕組みは同じなのですが、見た目/機能は Extension point によって色々と違いがあり、実装方法も違ってくる(部分もある)ので、個別に説明していきたいと思います。


まずは一番説明しやすい "Action" から。


1. ターゲットを作成する

Xcode の [File] > [New] > [Target] から、[Application Extension] > [Action Extension] を選択します。


f:id:shu223:20140606093345j:image

(※Xcode6のスクショではありません。App Extension Programming Guide の図3-1 です。)


ここでは [Action Type] は [View Controller] を選択します。


2. Extension の実装

Extension が起動されたときの見た目や挙動を実装します。


たとえば、ImageInverter サンプルでは、`viewDidLoad` で入力画像を反転して表示するように実装されています。

// extensionContextから入力アイテムを取得
NSExtensionItem *imageItem = [self.extensionContext.inputItems firstObject];

// NSItemProviderを取得
NSItemProvider *imageItemProvider = [[imageItem attachments] firstObject];

if([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]){

    // 入力画像を取得    
    [imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) {
        
        if(image){
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                // 画像を反転させる
                UIImage* invertedImage = [self invertedImage:image];
                
                // 表示
                [imageView setImage:invertedImage];
            });
            
        }
    }];
    
}

(説明用に簡略化しています。また `invertedImage` メソッドのソースは省略。)



そして、done ボタン押下で編集済みアイテムを返します。

-(void)done:(id)sender{
    
    // 編集済みのNSExtensionItemオブジェクトを作成
    NSExtensionItem *extensionItem = [[NSExtensionItem alloc] init];
    [extensionItem setAttachments:@[[[NSItemProvider alloc] initWithItem:[self.imageView image]
                                                          typeIdentifier:(NSString*)kUTTypeImage]]];
    
    // Host appに返す
    [self.extensionContext completeRequestReturningItems:@[extensionItem] completionHandler:nil];
}

Host appの実装

Extension を呼び出す側のアプリの実装です。


ボタン押下時に UIActivityViewController を表示する、というのは従来と同じなのですが、完了ハンドラの引数で、Extention から返ってきたアイテムを受け取れるようになっています。


ImageInverter サンプルでは、下記のように画像を取り出して表示しています。

- (IBAction)share:(id)sender {
    
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:
  @[[self.imageView image]]
                                                                                         applicationActivities:nil];
    
    [activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError * error){
        
        // 返ってきたアイテムを取得
        NSExtensionItem* extensionItem = [returnedItems firstObject];
        NSItemProvider* imageItemProvider = [[extensionItem attachments] firstObject];

        // 画像を取り出して表示
        if([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]){
            
            [imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage
                                                 options:nil
                                       completionHandler:^(UIImage *item, NSError *error) {
                                           
                                           if(item && !error){
                                               
                                               dispatch_async(dispatch_get_main_queue(), ^{
                                                   [self.imageView setImage:item];
                                               });
                                           }
                                       }];
        }
    }];
    
    [self presentViewController:activityViewController animated:YES completion:nil];
}

(説明用に簡略化しています。)


実行時の注意点

新しい機能なので、 UIActivityViewController が立ち上がってどうすればいいか一瞬戸惑うのですが、初回のみ [More] から今回追加した Extension を有効にして、UIActivityViewController を立ち上げ直す必要があります。


InvertImageサンプル自体は公開されているものの、Xcode6はNDA下にあるため、実行結果のスクショはここでは掲載を控えておきます。


参考資料

本記事は、以下のAppleによる公開リソースをもとに作成しています。


*1:OS X は4種類

2014-06-05

開発者向け公開情報から見る iOS 8 の細かい新機能8つ

今まさに開催中のWWDC2014のキーノートでは、Swift、HealthKit、HomeKit、Metal、Extensions と、iOS 8 の言語レベル、新規フレームワークレベルでの大きな新機能について発表されましたが、従来フレームワークにもいろいろと有用な機能が追加されています。


f:id:shu223:20140605094333p:image:w183


例年のWWDCではそれらはNDA下にあり正式リリースまで話題にすることはできなかったのですが、今年はAppleがいろいろと情報を公開してくれている(ログイン不要で見れるようになっている)ので、それらの情報リソースから、「これは嬉しい」と思った機能をいくつか挙げていきます。


※Xcode 6 はNDA下にあるため、実行結果には言及しないようにしています。


UIVisualEffectView

クラスリファレンスを見ると、

init(effect effect: UIVisualEffect!)

というメソッドで初期化でき、UIVisualEffect 型のオブジェクトを渡せるようになっています。


UIVisualEffectを継承するクラスとしては

  • UIBlurEffect
  • UIVibrancyEffect

の2つが用意されています。


ここで注目すべきは UIBlurEffect 。


UIナントカView にブラーエフェクトを渡せる、というのはまさにあの「磨りガラス効果」ではないでしょうか。


iOS7で導入されキーノートのときから目を引いていたエフェクトだったものの、その実装方法には諸説あり決定打に欠いていたので、やっと磨りガラス論争に終止符が打たれそうです。


CIKernel

Core Image の更新。カーネルというのはフィルタをかける際に、畳み込み演算する核となるマトリックスのことで、これがAPIとして出てきたということは、事実上 iOS でもカスタムフィルタの作成が可能となったと言えると思います。


What's New in iOS でも触れられています。

You can create custom image kernels in iOS.


残念ながらまだクラスリファレンスは公開されていません(2014.5.4現在)。


関連記事

AVAudioEngine

iOS の Core Audio においてもっとも低レイヤに位置し、リアルタイムで高度なオーディオ波形処理や、複雑なルーティングによるオーディオ処理を実現することができる Audio Unit というのが従来からあったのですが、これらは AVFoundation 等に比べると少々複雑で、しかもAPIがC言語タイプなので、自分のようなゆとりiOSエンジニアには少しハードルが高い部分がありました。

iOS 8 で追加された AVAudioEngine は、その API をみると、完全に Audio Unit の Objective-C ラッパーな感じで、上記のAudio Unitのハードルの高さを解消してくれているのでは、という期待ができます。


ギターのエフェクターのようにユニットを繋げる楽しさも健在で、たとえば AVAudioUnitEffect を継承するクラスとしては、

  • AVAudioUnitDelay
  • AVAudioUnitDistortion
  • AVAudioUnitEQ
  • AVAudioUnitReverb

といったものが用意されています。



CLFloor

公開されているクラスリファレンスを見ると、

A CLFloor object specifies the floor of the building on which the user is located.

とあり、`level` (read-only) というプロパティが定義されています。


地図からフロア情報も取得できるようになるのではないでしょうか。


CLVisit

クラスリファレンスによると、ユーザーの過去の訪問履歴を扱うためのクラスのようです。

  • coordinate
  • horizontalAccuracy
  • arrivalDate
  • departureDate

といったプロパティを持っています。


そして、"CLLocationManager+CLVisitExtensions.h" という CLLocationManager のカテゴリが追加されていて、

func startMonitoringVisits()
func stopMonitoringVisits()

というメソッドが使えるようになっています。


また、CLLocationManagerDelegate に、次のデリゲートメソッドが追加されています。

@optional func locationManager(_ manager: CLLocationManager!,
                      didVisit visit: CLVisit!)

で、What's newを見ると、

The visit service provides an alternative to the significant location change service for apps that need location information about interesting places visited by the user.

とあり、バックグラウンドで位置情報をとるためにこれまで用いていた significant location のしくみ(GPSではなく基地局ベースのやつですね)に代わり、訪れた場所をモニタリングするサービスのようです。


Manual Camera Controls

関連メソッドが多いので詳細は省略しますが(API Diffsから確認できます)、カメラの

  • フォーカス
  • ホワイトバランス
  • 露出

の設定が直接制御できるようになっています。


Accelerate Framework

従来からあるフレームワークですが、大量のクラス/メソッドが追加されています。API Diffs のページ面積の約半分(!)近くを占めるほどです。


高速画像処理演算ライブラリの vImage、線形代数演算等が強化されています。


IBでのカスタムフォントプレビュー

What's New in Xcode によると、

Custom iOS fonts. Interface Builder renders embedded custom fonts during design time, giving a more accurate preview of how the finished app will look, with correct dimensions.

とあります。カスタムフォントを Interface Builder で選べてプレビューできる、ということです。


これは個人的には待望の機能で、つい先日

という記事を書いて有料のプラグインを紹介したばかりなのですが、標準でサポートしてくれるに越したことはない *1 ので、ありがたい機能追加です。


本記事の情報ソース


*1:サードパーティ製有料プラグインを使うと、たとえばチームでプロジェクトを共有するときに困る

2014-06-04

BLEデバイスと連携するiOSアプリ開発での「落とし穴」についてWWDCラボで聞いてみました

Core Bluetooth / Bluetooth Low Energy で iOS アプリと連携する新規ハードウェアを開発したことのある人にとってはあるあるな話だと思うのですが、開発途中でペリフェラル側(外部デバイス)で GATT の内容を変更すると、iPhone の Settings から Bluetooth を Off/On しないと変更が反映されない、というのがあります。


このことを知らないと、

  • キャラクタリスティックの `value` が取れない
  • -> BLE の接続状態を疑う
  • -> Central / Peripheral 間での UUID の食い違いを疑う
  • etc...

と、無駄なデバッグ作業をしてしまいかねません。


下記スライドでも最後の方のページで「ハマりどころ」として紹介されています。


しかし例えばデバイス側の GATT に Characteristic をひとつ追加したとして、リリース済みサービスの場合、エンドユーザーに Off/On してもらうっておかしくない?と思い、せっかくなので現在絶賛参加中の WWDC 2014 の "Accessories and I/O Technologies Lab" で質問してみました。


Appleの公式回答

質問してみると、「あーー Cache の件ね!」とすぐに質問の意図を理解してもらえたので、やはりあるあるケースなようです。


で、まずは Bluetooth.org の Core Specifications を見よう、と。


f:id:shu223:20140605041045p:image:w300


Core Specifications は下記ページより ダウンロードできます。


目次をみると1351ページ以上(!)もあるPDFなのですが、その「7.1 SERVICE CHANGED」という項目があるので、そこを読めと。


どうやら、サービスに変更があった場合に使うキャラクタリスティック "Service Changed" が標準で定義されているのでそれを使えばいいよ、ということらしいです。


なるほど、となったところで「そういうことだから、じゃ!」となりそうだったので、ちょっと待って、iOS側はそのキャラクタリスティックに対してどうしたらいいの、 勝手にキャッシュクリアしてくれるの?それともアプリ内で明示的に何らかの処理をする必要があるの? ということを聞いたところ、


デバイス側で上述したキャラクタリスティックをGATTに追加しておいて必要に応じてサービス変更を通知すると、


CBPeripheralDelegate の `peripheral:didModifyServices:` が呼ばれる


ので、そこで再度 `discoverServices:` すればOKとのこと。


余談:ラボ初体験記

WWDCは今回が初参加で、「セッションは動画がすぐに公開されるので行かなくてよい、WWDCはラボで質問しまくってこそ価値がある!」と聞いてたので、「ラボで何か聞かないと・・・でも不安だ・・・」(英語コミュニケーション的な意味で)とプレッシャーを感じていました。


でもBLEについて聞けそうなラボはそんなにないので今いくしかない!と部屋に入ったものの、

といったんは逃げ帰りました。


ランチ後、「今年はiOS8のセッション聞きたいし別にラボはいいかな。。」と日和りそうになったものの


というわけで質問を全文考えていくことで乗り切ることができました。


あと、事前に @u_akihiro さんが Service Changed キャラクタリスティックの存在を教えてくださっていたので、回答が理解できたというのもあります。(いつもありがとうございます!)



これでもうWWDCの残りを気楽に楽しめます。めでたしめでたし。


2014-06-03

Objective-C で書いたアプリを Swift で書き換える5ステップ

iBookでSwiftの解説本出ましたが、言語自体にはそれほど興味がないので、実践的なところとして、手始めに「Objective-Cで書いた既存アプリをSwiftで書き換える」ところからやってみました。


アプリ全体、となると壮大なテーマになってしまうので、まずは AppDelegate だけ書き換えてみます。


なお、NDA 下にある Xcode 6 については書けないので、ビルド設定等については割愛しています。


1. 拡張子を .swift にする

例えば AppDelegate.m なら、AppDeleagate.swift にします。


2. import の書き換え

ヘッダの import も移してきて、

#import <UIKit/UIKit.h>

だったのを

import UIKit

にします。


3. クラス宣言の書き換え

これもヘッダから移してきて *1

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

だったのを、

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
}

にします。


ただし

@UIApplicationMain

は AppDelegate.swift の場合のみ。


また上記のプロパティ宣言部分

var window: UIWindow?

にある `?` は、 nilを許容するかどうか を明示的に指定するものです。


4. メソッド定義の書き換え

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

だったのを、

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    // Override point for customization after application launch.
    return true
}

にします。


どこがどう書き換わっているかは、上記の例で一目瞭然で、説明不要かと思います。


5. main.mを削除

あまりいじる機会の少ない main.m では、

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

と、UIApplicationMain 関数に AppDelegate のクラスを渡していました。


Swift では上述したように AppDelegate.swift に同等のことを書いてしまってるので、main.m は不要となるので削除してしまいます。



以上の手順で(とくに中身のないAppDelegateの場合は)ビルドが通って動作するようになります。


おわりに

冒頭で「言語自体にはあまり興味がない」と書きましたが、Swiftのお試しがてらこれをやってみると、Objective-C と Swift の違いがよくわかり、「なるほど、このあたりのおかげで LLVM がグッと最適化できて高速化につながってるのか」と勉強になりました。

*1:実装ファイルに無名カテゴリで宣言しているメンバ変数やプロパティがあればそれもマージすることになるかと。

2014-06-01

WWDC 2014 いまさら予習(と予想)

WWDC に参加するため、約1週間前からサンフランシスコに来ております。


f:id:shu223:20140602085755j:image:w400

(5/28、絶賛準備中の図)


初参加なのではりきって早めに現地入りしたわけですが、この1週間で気付いたこと。



そう、そうなのです。もともと日本でも最新情報に遅れ気味なのに、こっちに来るとネットに繋がってない状態がほとんど *1 なので、夜、宿に帰ってFacebook見て「iOS 8 が発表されるの?マジで!?」という感じです。


というわけでWWDC開催直前の今日、いろいろと記事を読んでキャッチアップしていこうと思います。


以下、調べたことなどを雑多にまとめていきます。


Appleが最近買収した企業

新機能が追加されたときに、それに関連する(と思われる)買収企業/サービスの前提知識があると新しい概念がスッと入ってきやすいので、まずはここを調べてみました。


『シリコンバレーによろしく』さんが、Appleが過去に買収した企業をすべてまとめた記事を書かれています。


そのうち、iOS 7 正式リリース以降のものを書き出してみると、

  • October 3, 2013 Cue 秘書ソフト
  • November 24, 2013 PrimeSense 半導体
  • December 2, 2013 Topsy 分析ソフト
  • December 23, 2013 BroadMap 地図
  • December 23, 2013 Catch.com ソフトウェア
  • January 4, 2014 SnappyLabs 写真編集ソフト
  • February 21, 2014 Burstly ソフトウェア
  • May 2, 2014 LuxVue Technology マイクロLEDディスプレイ
  • May 9, 2014 Beats Electronics ハードウェア

こんな感じです。


うち、いくつか個別に調べてみました。

PrimeSense

一番上の記事見て思い出しましたが、そういえば話題になってたな。。


Cue

インストールしてたけど起動したことなかったアプリ。なるほど、

同社の検索サービスは、Facebook、Twitter、LinkedInなどのソーシャルメディアや、Gmail、Google Calendar、Dropbox、Evernoteなどのクラウドサービスのユーザーアカウント内の情報を横断的に検索できるというもの。パーソナルアシスタントのアプリケーションではこうした情報を分析し、スケジュールやリマインダーをパネル形式で表示していた。

という機能を提供してたのか。。


Burstly

聞いたことない企業名だと思ったら、「Testflight」の運営会社でした。



ちなみに『シリコンバレーによろしく』の Facebookの買収企業一覧Googleの買収企業一覧 という記事も勉強になります *2


メディアによる予想記事

こんな感じの内容が予想として挙がってきているそうです。

  • iOSの新バージョン「iOS 8」の発表
  • 次期Mac OS「OS X 10.10」の発表、開発コード名が明らかに
  • VoLTE(Voice over LTE)のサポート
  • iTunesがハイレゾ音源に対応し、6月に配信開始
  • iTunes Radio専用アプリのリリース
  • Beatsのドクター・ドレとジミー・アイヴォンが登壇
  • iCloud/iWork/iLifeの改良
  • スマートホーム分野への参入
  • ヘルスケア/フィットネス分野への参入
  • iWatchなどウエアラブルデバイスの発表
  • CarPlay続報
  • iPhone 6の発表
  • ハイレゾ対応デバイスの発表
  • 新型Apple TVの発表
  • 新型Thunderbolt Displayの発表
  • 12型Retinaディスプレイの新MacBook Airを発表
  • 教育市場向け低価格iMacの発表

10ページにわたる記事。ボリューム多いので未読。


エンジニアによる予想記事

iOSエンジニアとしてはやっぱりこのあたりの記事(APIレベル/開発者目線での予想)が一番読んでておもしろかったです。


ハッシュタグ #expectWWDC ツイートのまとめ


個人的予想(願望)

僕もやってみました。Appleのビジネス戦略とか、上でわざわざ調べた買収企業の技術とか、時代の流れとか一切考慮しておりません。単に開発していて不自由に思ったこと等をつらつらと書き並べた感じです。


  • UIActivityまわりの強化

最近触ってないのですが、AppSocially SDK つくってたときに、かゆいところに手の届かない API だなーと何度か思ったので。


  • Audio Unit のユニット増

Mac で使えて iOS で使えないユニット(Sub)がたくさんあるので。


あと、Custom Audio Unit も Mac で使えて iOS で使えない機能。


(参考記事)Audio Unit 再入門 - Over&Out その後


  • CIFilter のカスタムフィルタ作成/使用

Mac でできて iOS でできない。


  • Social.framework, Accounts.framework

iOS 7 で UIActivityType に Vimeo や Flickr が追加されたのに、Accounts.framework の ACAccountTypeIdentifier や Social.framework の SLServiceType には追加されてない。


  • カスタムフォントのプレビューをIBでサポート

(参考記事)IB上でカスタムフォントを選択してプレビューできるXcodeプラグイン『MoarFonts』 - Over&Out その後


  • Siri の API解放

音声認識機能の追加、という意味でもあるし、自然言語解析機能の追加、という意味でもあります。


もしこれやってくれたら個人的にすごく嬉しいところ。


(参考記事)iOS SDK用音声認識機能ライブラリVocalKitの使い方 - Over&Out その後


  • SceneKit を iOS でもサポート

Mac では使えて iOS では使えないフレームワーク。3Dをどうこうできるらしい。触ったことない無責任なイメージを書くと、Unity的なことを Xcode + Objective-C でできるのかなと(全然違ってたらすみません)。


  • パノラマ撮影のAPI解放

並行度合いを検知するのとか、画像をつないだりとかの処理。


  • Save as template機能

ファイルテンプレートはすごく効率化に寄与すると思うんですけど、記法を覚えづらくてつくるの面倒だし、ちょっと時間経つと古くなってしまうし、人によってよく使うテンプレートは違うので他人と共有しづらい。


という意味で、Xcodeで、編集中のクラスファイルをテンプレートに自動変換してくれたらすごい嬉しいなぁと。


そもそもテンプレートのフォーマットを公式には公開してないのでまずやってくれないだろうけど。。


(参考記事)no title


  • AVSpeechSynthesizerの日本語サポート強化

僕がどういうことを望んでいるか、というのは下記記事から思いが伝わるかと思います。


no title


  • 深度センサー搭載、API追加

上述した PrimeSense はそういうのが得意な企業らしいので、iPhoneに深度センサが乗って SDK から値取れたら開発者的には夢が広がるなーと。



以上、こういうのを書き始めると無限に出てくるのでこのへんで。。


おわりに

まーiOSエンジニアとしてはなんといっても iOS 8 ですね。なんとなく「ついこないだ 7 出たばっかりだからまだだろう」ぐらいに構えてたので、完全に油断してました。しっかり聞いて勉強してこないと・・・!


*1:入国初日だけ諸々不自由があって禁断のデータローミングに手を出しました。

*2:ちなみにちなみに、このブログを運営されているサトル氏に現地でお会いしましたが、とても親切で爽やかなグッドルッキングガイでした。

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 |