その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

フリーランスのお仕事まとめ2018年9月〜12月

前回の実績まとめ以降の9月〜12月の4ヶ月間にやったお仕事のまとめ。

ハイライト

  • 「アナログデジタルボドゲ」がついにリリース
  • 機械学習×iOS」案件が増えてきた
  • 採用コンサルや新規の技術顧問契約等、新展開も色々と
  • 本の執筆×2
  • インタビューしていただきました×3
  • Voicyはじめました
  • 娘が生まれました

Core NFCを利用したボドゲ「アナログデジタルボドゲ

f:id:shu223:20181230141249j:plain

非常勤メンバーとして参加しているブルーパドル社でのお仕事。以前から水面下で開発していたアナログ+デジタルなボードゲーム、その名も「アナログデジタルボドゲ」がついにリリースされました1。アプリ実装をまるっと担当してます。

bodoge.blue-puddle.com

あれこれ制約が多く今のところ使いみちがないと言われがちなCore NFCですが、それをゲームで実用するというのは世界でも珍しいのではと。

開発中は作っては遊び、遊んでは作って、というサイクルで、完全に楽しかったです。

機械学習×iOS

機械学習×iOSCoreML登場以前から模索していたもののなかなか仕事に繋げられないでいたのですが、ここにきて実ってきました。前回書いたまごチャンネルの「子どもファインダー」機械学習で子供が写っている写真を自動選別する機能でしたが、今回はそれとは別に新案件が2つ。

TensorFlowモデルをiOSで動かすための実装

作業は完了しているのですが、機能リリースがまだなのでアプリ名やどういう機能かは控えておきます。TensorFlow(以下TF)で学習させたモデルがあって、そのモデルを用いた推論処理とOpenCVの処理を組み合わせたC++のコードがあり、それを既存のiOSプロジェクトに組み込む、というミッションでした。

TFのモデルを使うだけであれば以前別の案件でやったようにCore MLモデルに変換してiOSで用いる、という選択肢もあるのですが、今回の場合はOpenCVと組み合わせてトータルな処理を構成しているのと、そのC++コードは今後も継続的にアップデートされるであろうことから、(少々詳細になりすぎているので中略)つまり何が言いたいかというと、

  • TFはサンプルレベルながらも多少触ったりコードを読んだりしていた
  • Fyusion社でR&Dチームが書いたC++コードをiOSに組み込む仕事をよくやっていた
  • Core MLやiOSGPUまわりについて知見・経験がある
  • Courseraで機械学習の基礎だけは学んでいた

等々が絡んでいて、点と点が繋がって線になっているなぁ、と感じたのでした。

qiita.com

qiita.com

qiita.com

d.hatena.ne.jp

機械学習を利用した機能のSDK

上とは別の会社で、機械学習で実現しようとしていることも全然違います。ここでのお仕事は、既にiOSで動いているCoreMLモデルがあり、その機能をSDK化するというものでした。モデル追加しやすいように内部で抽象化したり、利用側が使いやすいようなAPI設計にしたり、テスト書いたり。公開が楽しみです。

継続的なお手伝い

ドローン利用アプリ

ドローンを利用した屋根点検サービスを提供しているスタートアップ「CLUE」を継続してお手伝いしています。同社はドローンを飛ばせる「ラボ」を都内に持っているのですが、子供が生まれてから外出が難しくなったので、リモートでも可能な(つまりドローン実機が不要な)部分でお手伝いしています。

まごチャンネル

テレビにHDMIケーブルを繋ぐだけの写真・動画サービス「まごチャンネル」を提供しているチカク社を継続してお手伝いしています。細かいUIUXや機能改善等。

技術顧問(継続)

こちらも前回から引き続き。事業計画に沿って、キーとなる技術のフィージビリティ調査(検証のための実装も含む)を行ったりしています。そろそろ新展開がありそうです。

Metal関連

Metalでのフィルタ実装

顔のパーツとかメガネとか背景とかはそのままに、肌だけ平滑化するMetalフィルタを実装。海外案件。

かなり前に同じようなフィルタのシェーダを書いたことがあり(GPUImageにプルリク送ってマージされた)、そのときの知見が役立ちました。

新展開

採用コンサル

こちらも継続的にお手伝いしている会社で、技術面では「Bluetoothモジュールの機能調査」をやっていてNDA的に書けないことしかないのですが、同社のエンジニア採用コンサルもさせていただきました。同社のWantedly採用ページについてエンジニア目線からどのへんがポイントとなるか、あるいはポイントとならないか(クリックしない/読むのをやめる)、といったところを指摘し、僕ならこう書く、というのを書いて解説したりもしました。

記事には書いたことないですが、基本的には手を動かして(コードを書く)お手伝いを軸としつつ、継続する中でこういった採用面でお手伝いすることはちょくちょくあります。(エンジニア募集方法について一緒に検討したり、面接したり、候補者についてコメントしたり、人を紹介したり)

技術顧問(新規)

12月後半から開始しました。(僕の個人的なイメージですが)「技術顧問」は設計とか技術選定とかチーム開発手法とかの比較的大きい枠組みでの技術的アドバイスが求められることが多いと思っていて、僕はそういうところの知見やスキルが特に秀でているわけではないので基本的に技術顧問的ポジションには向いていないと言っているのですが、ここはスタートアップというより、アーティストチームのようなところで、僕自身ずっとファンでもあったし、求められている内容も期待に応えられそうだと感じたので、二つ返事でお受けしました。

ポッドキャスト(Voicy)開始

『技術の小難しい話はおいておいて、「生き様」に焦点をあてていろんなエンジニアにお話を伺う』というコンセプトでPodcastをはじめました。とはいえPodcastアプリで探しても出てこなくて、Voicyというアプリ/Webサイトで聴けます。

voicy.jp

ソフトウェアエンジニアという職業は今や売り手市場で、パソコンとネットがあればどこでも仕事ができ、国や言語を超えて通用し、ブログやオープンソースで発信することでプレゼンスも向上しやすく、「生き方の選択肢が多い」職業のひとつです。エンジニアにもそうでないみなさまにも、人生の可能性を感じてワクワクしていただけるような内容にしたいと思っています。

執筆

「実践ARKit」執筆&技術書典5

【つくりながら学ぶ実践入門書】というコンセプトで、ARKitの入門書「実践ARKit」を個人で出版しました。

note.mu

Boothにて販売しています。

shu223.booth.pm

10月の「技術書典5」で販売してきました。

shu223.hatenablog.com

iOS 12 Programming」執筆

PEAKS刊行の「iOS 12 Programming」で、「ARKit」の章と「デプス」の章の執筆を担当しました。

iOS 12 Programming

iOS 12 Programming

  • 著者: 加藤 尋樹,佐藤 紘一,石川 洋資,堤 修一,吉田 悠一,池田 翔,佐藤剛士,大榎一司,所 友太,
  • 製本版,電子版
  • PEAKSで購入する

詳細はこちら:

shu223.hatenablog.com

インタビュー&講演

Qiita:Zineでの対談(フリーナンス広告記事)

フリーランス向け保険その名も「フリーナンス」について、座談会形式でお話を伺いました。広告記事ですが提灯記事にはしたくないです、ってことで『僕にはちょっと当てはまらないかな?』とかかなり正直に話してるので興味のある方はぜひ。

zine.qiita.com

エンジニアHubインタビュー

OSSを軸にしたあのインタビューシリーズに出させていただきました!iOS Samplerシリーズを始めたきっかけや、どういうことを考えてコードを公開しているか、といった話をしています。

employment.en-japan.com

よく「ブログを書いたほうがいいとは思いつつも、書く時間がない」と聞きますが、それは僕からすれば「仕事をしたけど請求書を書く時間がない」と言っているのと同じように感じます。「今月は時間がないから、100万円分の請求書を出しませんでした」っていう人は絶対にいないでしょう(笑)。それと同じ感覚で、面白い仕事を経験したり、新しい技術を身に付けたらそのことを世に発信するのは、僕にとっては明確に実益を伴うことなんです。僕はブログを書くために仕事を断ってでも時間を確保することもあります。

キズナシッターインタビュー

ベビーシッターでいつもお世話になっている「キズナシッター」さんにインタビューしていただきました。うちの👼も同席しました。(隣りにいるのはよく来てくださっているシッターの岩見さん)

sitter.kidsna.com

フェンリル社で講演

アプリ開発等で有名なフェンリル社にお招きいただき、「エンジニアという仕事を楽しみ続けるためのキャリア戦略」というテーマで講演させていただきました。フェンリルさんに許可をいただいたので、その講演内でつかった約60ページのスライド資料をnoteにまとめました。

note.mu

エンジニアを楽しみ「続ける」というところがポイントで、世の中の変化も激しいし自分も飽きたり慣れたり状況や心境が変わったりする中でどうやって楽しみ「続ける」よう工夫しているのか、というのを実体験を多く交えつつ話しています。

昔は楽しかったんだけど最近はどうも惰性でやってるかも」とか、「若くて優秀な人にはもうかなわないなぁ」という感じの方々には共感していただける部分があるかもしれないのでぜひ見てみてください。

おわりに - 育児と両立するための試行錯誤

9/1に娘が生まれ、働き方がそれまでとはガラッと変わりました。育児のために外出すらままならなくなりいったんほぼすべてのフリーランス案件を止め、収入が激減。軽く絶望感すらありました。

これは上のキズナシッターのインタビューからの引用なのですが、

僕はエンジニアで、自分の仕事を楽しんでいて、僕の技術を必要としてくれている会社がたくさんあるのに、赤ちゃんを抱っこしていると働けない、という状況がすごく苦しかったんです。そんな状況を、僕よりも赤ちゃんを上手にあやせるベビーシッターさん達に助けてもらうようになって、本当に救われた気がしました。

というわけで、今は週5でシッターさんに来ていただいてます。僕も奥さんも忙しいときは週末にも来てもらうことがあって、11月は(ちゃんと計算してないですが)たぶん40万円以上(!)2かかっています。

とんでもない金額ですね。×12すると恐ろしいですが、認可どころか認可外保育園でも入れないし、片働きなので僕が赤ちゃんを抱っこしてる限り我が家の収入はゼロになるのだから仕方ないです。

しかし全然悲観的な話ではなくて、「お金で解決できるところはそうしよう」と開き直ってシッターさんに毎日来てもらうようにしてからの10月・11月と、僕のフリーランスとしての売り上げは逆に過去最高になっています。

なぜかというとシンプルな話で、僕が何をしている間も常にベビーシッターさんの時給(約2000円)がかかっているので「もったいない精神」が働いて、移動や飲み会を極限まで減らすようになり、代わりにその間も仕事するようになったからです。(ちなみに受けている仕事はどれもおもしろいので全く苦ではありません)

いや、もともと自分の時給が◯◯円だから、「今こうして飲み会に行っている間も△△円かかっている」という認識はあったつもりなんですよ。でもそういう「機会損失」は実際に自分の財布や口座からお金が出ていくわけじゃないので、行動に影響を与える程ではなかった。そこがシッターさんに時給を払うことで可視化/具現化されて、やっと自分の行動を変えるに至ったと。これはエポックメイキングな気付きでした。

そんなわけで、いろんな新しい体験をしたり気付きを得たりしつつ、楽しくやっております。


  1. 11月末に開催された「ゲームマーケット2018」で限定100個だけ販売したのですが、さくっと初日のお昼ぐらいには売り切れてしまいました。クラウドファンディング準備中です。

  2. 2000円×10時間×20日 = 40万円

「iOS 12 Programming」のARKitとデプスの章を執筆しました

12月17日、共著で執筆したiOSの技術書「iOS 12 Programming」の一般販売が開始されました!

iOS 12 Programming

iOS 12 Programming

  • 著者: 加藤 尋樹,佐藤 紘一,石川 洋資,堤 修一,吉田 悠一,池田 翔,佐藤剛士,大榎一司,所 友太,
  • 製本版,電子版
  • PEAKSで購入する

私は「ARKit」と「デプス」1の章の執筆を担当しました。担当章の詳細については後述します。

中身が良いのはもちろんなのですが、とにかく表紙のデザインがすごく良くて、自分が過去に執筆で関わった書籍では一番のお気に入りです。マットな質感と色合いが好きで、ついつい手にとってしまいます。モノとしての技術書が好き、という方はぜひ製本版をおすすめします!

f:id:shu223:20181221153048j:plain

今のところAmazonでは売ってなくて、PEAKS社のサイトより購入できます。

以下、担当した章の紹介です。

第4章: ARKit

ARKit 2.0の新機能だけではなく、ARKit 1.5で追加された機能、さらにARKit 1.0の中でも前著「iOS 11 Programming」執筆以降に追加発表されたフェイストラッキング 2 等の機能も網羅しています。

- 4.1 はじめに
- 4.2 垂直平面の検出
  - 4.2.1 検出する平面のタイプを指定する
  - 4.2.2 検出した平面のアラインメントを判別する
- 4.3 平面ジオメトリの取得
  - 4.3.1 ARPlaneGeometry
  - 4.3.2 ARSCNPlaneGeometry
  - 4.3.3 ARPlaneAnchorのgeometryプロパティ
  - 4.3.4 実装
- 4.4 画像検出
  - 4.4.1 ARWorldTrackingConfiguration の detectionImages プロパティ
  - 4.4.2 ARReferenceImage
  - 4.4.3 ARImageAnchor
  - 4.4.4 実装
  - 画像検出のパフォーマンス
- 4.5 画像トラッキング
  - 4.5.1 ARImageTrackingConfiguration
  - 4.5.2 実装
  - 4.5.3 画像トラッキングと画像検出の違い
  - 4.5.4 ワールドトラッキングコンフィギュレーションで画像トラッキング
- 4.6 フェイストラッキング
  - 4.6.1 ARFaceTrackingConfiguration
  - 4.6.2 ARFaceAnchor
  - 4.6.3 ARFaceGeometry
  - 4.6.4 ARSCNFaceGeometry
  - 4.6.5 実装
- 4.7 3D物体検出
  - 4.7.1 ARReferenceObject
  - 4.7.2 detectionObjects
  - 4.7.3 ARObjectAnchor
  - 4.7.4 実装
  - 4.7.5 3D 物体スキャンの公式サンプルと独自実装について
- 4.8 AR体験の永続化と共有
  - 4.8.1 ARWorldMap
  - 4.8.2 ワールドマップの取得
  - 4.8.3 ワールドマップからの復元/initialWorldMap
  - 4.8.4 ワールドマップのアーカイブ/アンアーカイブ
  - 4.8.5 ワールドマップ取得タイミング
- 4.9 ビデオフォーマット
  - 4.9.1 ARConfiguration.VideoFormat
  - 4.9.2 videoFormat
  - 4.9.3 supportedVideoFormats
- 4.10 USDZの利用
  - 4.10.1 USDZファイルからMDLAssetを初期化する
  - 4.10.2 MDLAssetからSCNSceneを初期化する

なお、基礎から順序立ててARKitについて学びたい方は「iOS 11 Programming」の第2章を参照してください(後述)。

第5章: デプス

デプス(深度)が取得可能になったのはiOS 11から、つまり比較的最近のことです。 従来のカメラやGPSが、デジタルの世界と我々が生きる現実世界を繋ぐ重要な役割を担い、 アプリ開発者に多くの創造性を与えてくれたのと同様に、 モバイル端末で「奥行き」がわかるようになったというのはアプリ開発の次元がひとつ増えたようなものです。

そんなデプスですが、登場して間もないということもあり、日本語での情報はまだほとんどありません。 そこで本章ではデプスについて、iOS 12で追加されたAPIの解説だけでなく、 基礎から応用まで順序立てて30ページにわたって解説しています。

- 5.1 はじめに
- 5.2 デプスとは?
- 5.3 Disparity(視差)とDepth(深度)
- 5.4 AVDepthData
- 5.5 iOSにおけるデプス取得方法
- 5.6 デプス取得方法1:撮影済み写真から取得
  - 5.6.1 CGImageSourceオブジェクトを作成する
  - デプスデータをもつ PHAsset だけを取得する
  - 5.6.2 CGImageSource から Auxiliary データを取得する
  - 5.6.3 Auxiliary データから AVDepthData を初期化する
  - デプスマップをCIImageとして取得する
- 5.7 デプス取得方法2:カメラからリアルタイムに取得
  - 5.7.1 デプスが取れるタイプの AVCaptureDevice を使用する
  - 5.7.2 デプスが取れるフォーマットを指定する
  - 5.7.3 セッションの出力に AVCaptureDepthDataOutput を追加する
  - 5.7.4 AVCaptureDepthDataOutputDelegate を実装し、AVDepthData を取得する
  - 5.7.5 AVCaptureDataOutputSynchronizer で出力を同期させる
- 5.8 デプス取得方法3:ARKitから取得
- 5.9 デプス応用1:背景合成
  - 5.9.1 背景合成とは
  - 5.9.2 CIBlendWithMask
  - 5.9.3 デプスデータの加工
- 5.10 デプス応用2:2D写真を3D空間に描画する
- 5.11 PortraitEffectsMatte
  - 5.11.1 AVPortraitEffectsMatte
  - 5.11.2 PortraitEffectsMatteの取得方法
  - 5.11.3 PortraitEffectsMatteの取得条件/制約

iOSにおけるデプスについてこれだけ網羅的に、しかもフレームワークを横断して解説している書籍は英語圏を含めても存在しないのではと思っています。たぶんiOS 13が出ても14が出てもデプスについて詳しく書かれた日本語解説書は出てこないので、「デプスやるならiOS 12 Programming」と末永くご愛読いただけるといいなぁと思っております。

f:id:shu223:20180913012548g:plain

(PortraitEffectsMatteで背景切り抜き)

f:id:shu223:20180915110312g:plain

(2D写真を3D空間に描画)

全体のPR

本書の目次全体は次のようになっております。

  • 第1章 Siri Shortcuts ( @cockscomb 加藤 尋樹)
  • 第2章 Notifications ( @justin999_ 佐藤 紘一)
  • 第3章 Password AutoFillとAuthentication Services( @_ishkawa 石川 洋資)
  • 第4章 ARKit( @shu223 堤 修一)
  • 第5章 デプス( @shu223 堤 修一)
  • 第6章 Core ML 2, Create ML( @sonson_twit 吉田 悠一)
  • 第7章 Swift 4.0からSwift 4.2へのアップデート( @ikesyo 池田 翔)
  • 第8章 Xcode 10の新機能( @hatakenokakashi 佐藤剛士
  • 第9章 Mojaveの新機能( @tamadeveloper 大榎一司)
  • 第10章 tvOS 12の新機能( @tokorom 所 友太)

いかがでしょうか。ここで僕が声を大にして言いたいことはiOS 11のときも言ってますが)

本書はiOS 13, 14, 15...が登場しても価値を持ち続ける

ということです。今後もiOSやSwiftの入門本は多く出てくると思いますが、本書が扱っているような項目について同様の詳細度で解説する書籍はそうそう現れないでしょう。というわけで、ひとつでも興味のある項目があれば、ぜひご検討ください。

iOS 11 Programming」も併せてどうぞ

なお、ついでに言わせていただきますと、同じ理由でiOS 11本も今でも「買い」です。

iOS 11 Programming

iOS 11 Programming

  • 著者:堤 修一,吉田 悠一,池田 翔,坂田 晃一,加藤 尋樹,川邉 雄介,岸川克己,所 友太,永野 哲久,加藤 寛人,
  • 発行日:2017年11月16日
  • 対応フォーマット:製本版,PDF
  • PEAKSで購入する

もう一度改めて目次を見てください。

- 第2章 ARKit
- 第3章 Core ML
- 第4章 Swift 4の新機能とアップデート
- 第5章 Xcode 9 の新機能
- 第6章 Drag and Drop
- 第7章 FilesとDocument Based Application
- 第8章 レイアウト関連の新機能及び変更点
- 第9章 Core NFC
- 第10章 PDF Kit
- 第11章 SiriKit
- 第12章 HomeKit入門とiOS 11のアップデート
- 第13章 Metal
- 第14章 Audio関連アップデート

私が担当したARKitの章、こちらはiOS 12本で書いた内容と一切の重複はありませんiOS 11本のARKitの章では、3行で実現できるARKitのはじめの一歩から、水平面の検出・仮想オブジェクトの設置・インタラクションといった重要な基礎機能の解説、そして現実世界の長さを測るメジャーアプリや空中に絵や文字を描くお絵かきアプリといった応用アプリケーションの実装方法を解説しています。iOS 12が登場した今でも古びない内容ですので、ARKitの実装を基礎から学びたい方はぜひご検討ください。

また同じく私が担当したMetalの章、こちらもiOS 11の新機能だけではなく、基礎からじっくり順序立てて解説しています。OpenGLDirectXGPUに近いレイヤでのグラフィックスプログラミングに親しんで「いない」人達にはMetalはかなりとっつきにくいと思うのですが、そういう方達にとってのわかりやすさにおいては英語の情報ソース含めても随一なのではないかなと勝手に自負しております。

他にもたとえばHomeKitの章。長らく謎に包まれていたHomeKit、対応デバイスもなかなか登場しなかった当然それについて書かれた書籍もありませんでした。そしてポツポツとデバイスが出揃ってきた今、満を持しての所さんによる56ページに及ぶ入門~実践の解説!他の章に用がなくてもHomeKitに興味がある人はこれだけで本書を購入する価値があると思います。

他にもこの本以外では詳細な解説はなかなか出ないんじゃないか、と思われる項目がたくさんあります。しかも、著書やカンファレンスでの講演に定評のある著者陣による執筆です。たまーに見かける、APIリファレンスを翻訳しただけのような、あるいはさわりをちょろっと解説しただけみたいな章はひとつもありません。それぞれが興味深く読めて、ちゃんと頭に入ってきて、実際の現場で役立つように各著者によって噛み砕かれ、再構成されています。

というわけで今でもその価値は色あせてないと思うので、興味のあるトピックがあればぜひiOS 11 Programmingもご検討ください。

まとめ

ついに一般販売が開始された書籍「iOS 12 Programming」について執筆者の立場から紹介させていただきました。ちょっと気になってきた、というみなさま。PEAKSのサイトに無料サンプルもあるので、ぜひぜひチェックしてみてください。

iOS 12 Programming

iOS 12 Programming

  • 著者: 加藤 尋樹,佐藤 紘一,石川 洋資,堤 修一,吉田 悠一,池田 翔,佐藤剛士,大榎一司,所 友太,
  • 製本版,電子版
  • PEAKSで購入する

何卒よろしくお願いいたします。


  1. 実はクラウドファンディングで購入者を募った時点ではMetalのiOS 12の新機能について書く予定だったのですが、執筆段階でデプスの章に変更させていただきました。Metalの章を楽しみにしていたクラウドファンディング支援者の方々には申し訳なかったのですが、デプスもまたiOSアプリ開発の新しい可能性を切り拓くものなので、いまこのタイミングで体系だった解説を書くことの意義は大きいと考え、この決断に至りました。この変更については支援者にはメールでベータリリース時お知らせしています。

  2. フェイストラッキングはARKit 1.0に属する機能ですが、ARKitが初めて発表されたWWDC 2017の時点ではまだ隠されており、2017年秋にiPhone X発表と同時にAPIが公開されました。

技術書の著者になるためにやったこと

この記事はカヤックOBが綴るアドベントカレンダーex-KAYAC Advent Calendar 2018」の4日目の記事となります。

2010年: いつか技術書を書いてみたい

プログラマになる前、「本の書く」というのは自分とは関係ない「どこか遠い世界の話」のように思っていました。しかしプログラマになってカヤックに入ってみると、なんとまぁ、書籍執筆経験のある人の多いこと。 本を書くことが「現実的な憧れ」に変わりました。

しかし、自分は30過ぎてプログラマデビューしたばかりの、技術力も経験もない、うだつの上がらないプログラマ。 有名でもないし、本の執筆が舞い込むようなインパクトのある実績も特にありません。 いつかは自分も、とは思うものの、それは「いつか」でしかありませんでした。

2011年: 会社の広報に「本を書きたいです」とメール

ある日ふとこう考えるようになりました。自分に技術書の著者になるほどのネームバリューがないからこそ、技術界隈でも名の知れている会社の看板の力を借りるべきなんじゃないの、と。

そうとなったら善は急げ、ということで、今の自分にも書けそうな企画として(当時まだあまり出揃っていなかった)iOS関連のライブラリカタログ本的な企画を考え、会社の広報にメールしました。本を書きたいので、出版社に繋げてもらえませんか、と。

(当時メールを出す前に書いた下書きの抜粋)

今期、技術書を書いてどこかの出版社に寄稿したいと考えています。
で、今自分が考えているようなことが可能性があるのかどうか、
カヤックでの出版に数々携わっている◯◯さんにまずは相談してみようということでメールしてみました。


【考えている内容】

オープンソースのiOS用フレームワーク/ライブラリ/カテゴリ/サンプルコードを紹介する
(注:カテゴリというのはObjective-Cの機能で、既存のクラスを拡張することができるものです)


【紙面のイメージ】(添付画像)

・見開き2ページで1つずつライブラリを紹介していくイメージです
・UI/アニメーション/通信/メディア(音声とか画像とか動画とか)/データベース とかで分類
・紹介内容は、どんなライブラリか、そのライブラリを使用することによってどんなメリットがあるか、中身のソースコードについての解説等
・ライセンスや対応iOSバージョン、必要なフレームワークについても記述


 【この本の価値】

・Objective-Cはライブラリやクラスの流用がしやすいわりにまとまったライブラリ情報は少なく、車輪の再開発が目立つ。
・gitHubやappleのdev center、個人サイトなど所在がバラバラなので、なかなか検索だけでオンタイムに欲しいライブラリやサンプルコードを見つけることはできない。
・githubやappleのdev centerは、サンプルを実行したスクリーンショットがないのでビルドしてみるまで実際にどういうコードなのかわからない。特にUIライブラリとかならスクショ見るまで有用性が判断できない。本ならパラパラとめくってよさげなのをさがすことができる。・そのプロジェクト自体に価値はなくても、中のひとつのクラスが有用だったりもする。そういうのは探そうと思って探せるものではない
・少なくとも日本語ではまだこういう本はない(知る限りでは英語でもない)


【ターゲット】

・中級者以上のiOSアプリケーション開発者

ビジュアルがあったほうが伝わるだろう、と考え、本の紙面アイデアも添付しました。もちろん自分で紙面デザインをするような高度なスキルは持ち合わせていないので、こちらの書籍をベースに「プレビュー.app」で線や文字を切り貼りして作成しました。

f:id:shu223:20181203212158p:plain

(当時作成した紙面アイデア画像)

2012年: Web連載開始

広報を宛先に、そしてiOSも書くエースエンジニア陣をCcに入れていたので、すぐに色々と意見をもらえました。いきなり紙の書籍の執筆は時間もかかるし書き上げる難易度も高いので、Web連載から始めるといいのでは、とのことで、これはまさにごもっとも。

そしてその広報の繋がりで、技術評論社(gihyo.jp)の方に会うことになりました。

先の書籍のアイデアを連載用に練り直し、全6回(各回毎に違うテーマを設定し、お役立ちライブラリを紹介する)の連載企画案をつくって会食の場に持っていきました。

無事「いいですね、やりましょう!」とご快諾いただき、連載決定。1回1回、通常業務を終えた後に何日も徹夜してめちゃくちゃがんばって調べまくっては書いてました。会社の看板ありきの連載なので原稿料は自分には入らないし、残業代が出るわけでもないのですが、「Web連載」という新しい実績を獲得できると思うとそれが十分な報酬でした。

2013年: 出版社から技術書を出版

連載とは別に、ブログでのアウトプットも続けていました。当時、ちょうどQiitaが出てきた頃で、自分が今までに書いた技術記事を100本まとめた記事を書いたらはてブのホットエントリー入りする程バズりました。

それを見た出版社の方より本を書きませんかと連絡をいただき、全力で書きたいですと答え、考えていた企画案を提示しました。このへんは先の連載での経験が大いに活きたところだと思います。

無事その案が出版社の企画会議で承認され、2013年5月吉日、晴れて自分も技術書の著者になることができたのでした。

d.hatena.ne.jp

まとめ

カヤック陣で綴るアドベントカレンダーのネタとして何かためになる(かもしれない)思い出話でも、ということで、本の著者になりたいという憧れを、まだ自分の技術力や実績が物足りない頃からアクションを起こし、数年越しでかなえることができた、という経験談を書きました。

まぁ書いてみて思いましたが自分で企画書を書いて広報にメールしたことと、最後に出版社の方から声をかけていただいたこととは明確な因果関係はありません。出版社の方からの連絡は完全に「運」です。ただ、自分から手をあげてWeb連載を経験するとか、技術ブログを地道に書き続けるとか、そういった行動の積み重ねの延長線上にあることも確かかと思います。

紙面案の画像を見て、「こんなのでいいのかw」と思われた方も多いかも知れません。そう、一見自分には手の届かなそうなことでも、案外「こんなことでいいのか」程度の行動の積み重ねで実現できたりするものです。そういうことがこの経験談から伝わって、誰かの勇気になると嬉しいです。

フリーランスのお仕事まとめ2018年5月〜8月

前回の実績まとめ記事以降(5月〜8月いっぱいまで)の4ヶ月間にやったお仕事のまとめ。

Fyusion

5月GW以降の約3週間はサンフランシスコでFyusionの仕事1。新しい画像処理機能の開発と、既存の画像処理パイプラインをMetalで最適化する仕事をやってました。

WWDC/AltConf参加

6月頭、WWDCはチケット外れてしまったので会場には入れなかったのですが、10日間ほどサンノゼ近辺に宿を取り、AltConfに出たり、カフェでセッション動画を見て勉強したり、ということをやっていました2

ドローン利用アプリ

ドローンを利用した屋根点検サービスを提供しているスタートアップ「CLUE」のアプリ開発をお手伝いしました(しています)。

CLUE社はドローンを飛ばせるように都内に専用の場所を借りていて、飛行ライセンスを持った人がテストしています。ドローンは興味がありつつもボーッとしているうちに規制されてしまい乗り遅れてしまっていたので、こうしてしっかりビジネスをやっているところに声をかけていただけたのは幸運でした。

f:id:shu223:20180619113450j:plain

(都内某所で飛行テスト)

とはいえスケジュールが立て込んでいたのであまり多くはお手伝いできていないのが実情。issue対応やちょっとした機能開発しかできていません。もっとがっつりドローンと向かい合いたいところです。

中国でのファームウェア実装のヘルプ

7月のある日、昔一緒にお仕事させていただいたプロダクトデザイナーの方より「ある制作会社に発注したアプリができてこなくて、そろそろ生産に入るデバイスのファームのテストが全くできていない、助けてほしい」という旨の電話が来て、急遽当該デバイスとアプリ間で行うBLE通信の全要件を確認できるテストアプリをつくり、その週には深センまで飛んで中国側のファームウェアエンジニアとテーブルを囲んでがっつりテスト&デバッグ作業をやる、というお仕事でした。テストアプリ開発2日、深セン2日の合計4日間。

f:id:shu223:20180727123338j:plain

(工場とオフィスのある建物)

f:id:shu223:20180727090340j:plain

(泊まったホテルより)

f:id:shu223:20181022031422j:plain

(作業の様子)

動作確認するための通信相手(iOSアプリ)が提供されない状況で実装されたファームですから、最初の確認では繋がることすらできない(接続のための仕様のすりあわせがうまくいっていない)状況でした。そこから、合計4人日でひと通りの機能が動作するところまで持っていったので、なかなか良い貢献ができたと思っています。

Swift Island参加

オランダの「テッセル島」で開催されたカンファレンスに参加。詳細は以前ブログに書きました。

shu223.hatenablog.com

カンファレンス自体は3日間なのですが、初めて行くオランダなのでトータル2週間滞在しました。

BLEプロト

海外から来たお仕事。BLEを利用したコミュニケーション機能の開発。要件ヒアリングから、実装、納品用にiPhone2台で動作させる動画を撮るところまでさくっと5時間でやって、5時間分だけ請求、すぐにPaypalで支払われた超特急案件でした。

上述のオランダ滞在中にやった案件で、僕からすれば海外旅行中のスキマ時間で対応可能/ひさびさのBLE案件で自分の古いコードベースをアップデートする良い機会/手離れが良いetc...というメリットがあり、先方もたったの5時間(当初あちらのメンバーが「調査」だけで何日かかけていた)の料金で済み、win-win案件だったと思います。

Metal、デプス、ARKitを使ったエフェクト実装

こちらも海外から来たお仕事。「こういうエフェクトをつくりたい」という打診があり、もともとのコードベースがARKit(フェイストラッキング使用)+Metalレンダリングだったので、エフェクトもMetalで実装しました。やっていくうちにデプス(深度)も利用することになり、ここで初めてデプスを扱った経験がiOSDCでの発表やiOS-Depth-Samplerの実装のきっかけになりました。これもオランダ滞在中にリモートで請けて完了させたお仕事。

Core MLを使った写真の自動分類機能

「まごチャンネル」という子供写真の共有サービスで、アプリ起動時にバックグラウンドで解析処理が走り、自分で選択しなくても子供が写っている写真だけを自動で抽出してくれる(→すぐにアップロードできる)、という機能を実装しました。

f:id:shu223:20181022034251j:plain:w240

モデル自体は社内の機械学習エンジニアの方がつくったもので、それをCore MLで使えるように変換するところから、iOSアプリに解析機能とUIを実装するところまでを担当しました3

まごチャンネル(チカク社)はその後もアプリ改善等で継続してお手伝いしています。

Core NFCを使ったゲームアプリ

これも前回記事からの継続。非常勤メンバーとして関わっているブルーパドル社でのお仕事で、Core NFCを使ったゲームアプリをつくっています。こちらはアプリ実装をゼロからまるっと担当。

いろいろ発散させて遊んでみるというフェーズから、今は仕様を収束させ、11月末の公開に向けて動いているところです。すでに一度はApp Storeの審査にも通っています。乞うご期待。

ちなみにこの期間、ブルーパドルではコードコーヒーというのもクラウドファンディングで出しました(僕は飲みながら感想言うだけのお仕事)。

Bluetoothモジュールの機能調査

とあるBluetoothモジュールの評価ボードを使って、(iOSアプリと連携して)何ができるのか、どう実装するのか、といったところ調査し、プロトタイプをつくる、というお仕事。ボード購入や問い合わせ待ちで間が空いたりしつつ、今も継続しています。

アプリ側はまだしも、ハードウェア側は「勘」が効かないので、問題解決にいちいち手こずります。このへん、慣れ親しんだiOSばかりやってる自分には良い刺激になっています。

技術顧問

こちらも前回から引き続き。事業計画に沿って、キーとなる技術のフィージビリティ調査(検証のための実装も含む)を行ったりしています。

その他

MIT訪問

ボストン/ケンブリッジに5日間の旅程で行き、MITのMedia Labを見学させていただきました。ラボも良かったし、MITのキャンパスも、ケンブリッジという街の雰囲気も良かった。いまはまだリアルには考えられないですが、何か研究テーマを決めてこういう環境で2年か3年探求するってのは楽しいだろうなぁ、と。

書籍の執筆

iOS 12 Programming」の章を2つ書きました。これについてはアーリーアクセス、あるいはベータ版が公開されたらまた別途記事を書きます。

iOSDC登壇

8月最終週はお客さん仕事を止め、ほぼフルタイムでこれに取り組んでいました。現存するデプス関連APIをすべて棚卸しして、それぞれ動作確認サンプルつくって、という素材集めでまず時間がかかり、集めた素材をどう調理しようかという発表の構成フェーズもまた時間がかかりまして、結局iOSDCの自分の発表前夜までこねくり回してました。工数かかってるのでぜひ見てやってください。

www.youtube.com

おかげさまでベストトーク賞3位を受賞しまして、さらにこのとき作ったサンプルを再構成して新作OSS(後述)も出せたし、本にも書けた4ので、調査や推敲にかけた時間は報われたかなと。

OSS活動

デプス(深度)をiOSで扱う方法を網羅したサンプルコード集「iOS-Depth-Sampler」をGitHubで公開しました。

github.com

デプス(深度)をiOSで扱う方法を網羅したサンプルコード集「iOS-Depth-Sampler」を公開しました - その後のその後

Trendingのデイリー最高2位ぐらい、ウィークリーでも10位以内にランクインしてました。iOS 7〜10のSamplerシリーズは軒並み3000スター以上を獲得していたことを考えるとだいぶひっそりとしたものですが、「iOSにおけるデプス」という切り口でこれだけ横断的にまとまった技術情報は英語でも存在しなかった5ので、世界に貢献するいい仕事ができたなと自己満足しています。

f:id:shu223:20180915110312g:plain

引っ越し

家族構成が変化することを見越して、8月頭に、4年半住んだ6アパートから引っ越しました。フリーランス、しかも前年度の確定申告実績がない7という社会的信用力の低さから、審査は多少難航しました。

妻の希望を優先して目黒区から新宿区になり、ほとんどのお客さんのオフィスから遠ざかってしまった(以前はほぼ自転車移動で済んでいた)のですが、場所や環境が変わればいろいろと新展開が始まるもので、マイナス面よりプラス面の方が遥かに多いです。引っ越しは面倒だけど定期的にやるものだなと。

おわりに

5月〜8月末までのお仕事をまとめました。

というのも、9月1日(iOSDCの登壇日の朝!)に娘が生まれ、働き方がガラッと変わったからです。いや、変わった、というよりいったん仕事ができなくなりました。諸事情で日中の育児は僕が担当することになっているのですが、赤ちゃんが寝てくれている時間しか仕事ができない(いつ起きて泣き出すかは赤ちゃん次第)ので、稼働可能な時間が読めない → お客さん仕事は入れられない、という。

9月は「iOS 12 Programming」の執筆の続きと、技術書典5向けの執筆があったのでそれでも良かったのですが、僕はお客さんのところにいって顔を合わせてコミュニケーションしながら仕事をするスタイルを本当に楽しんでいたので、そういった働き方ができないのはかなり苦しいですし、そもそもこのままだと収入が止まってしまいます(片働きです)。今のところ平日はベビーシッターさんを呼んだりしていますが、そうすると1日2万円、20人日で40万円(実際は8時間ではカバーできないのでもっと)かかる計算になってしまうし、保育園は認可外ですらすぐには入れない、という悩ましい状況です。

本記事でまとめた「それ以前」のお仕事を振り返ると、あらためて自分はよいお仕事・会社・機会に恵まれているなと思います。いまはまだ完全には仕事に復帰できていない状況ですが、どうにかポジティブに育児も仕事も幸せにこなせるよう画策していく所存です。


  1. これはフリーランスとしての仕事ではなく、アメリカの会社員としての仕事(ビザはH-1B)。別途アメリカで確定申告することになります。

  2. ちなみにこれによる収入はゼロですが、フリーランスiOSエンジニアとしての活動の一環ではあるのでここに書きました。

  3. 本機能については前回記事にも書きましたが、その後もろもろ本実装を行った上で無事リリースされたので、改めて書きました。

  4. これは後日発表します。しっかり練った構成が既にあったのでスイスイ書けた。

  5. WWDCのセッションはよくまとまっているが、それでも3つのセッションに分かれている(2018年現在)し、サンプルコードが提供されていないものがほとんど。

  6. 正確にはそのうち1年半は僕は主にアメリカに拠点を置き1ヶ月ごとに往復する生活をしていたが、妻はずっとこのアパートに住んでいた。

  7. 2017年度は全収益をアメリカで確定申告したので。

技術書でご飯は食べられるのか? #技術書典

昨日開催された技術書典5にて、新刊「実践ARKit」と既刊「Metal入門」という2冊の技術書を販売してきました。これまで商業出版も含め何度か技術書を書いてきて、「技術書に儲けを期待してはいけない」1と思い込んできましたが、昨日一日の売り上げは約46万円(詳細は後述)。もしかしたら技術書を書くこと自体でそれなりに稼げる時代が来つつあるのかもしれない・・・と考えを改めました。

f:id:shu223:20181010015119j:plain

(技術書典5。自分のブースからの光景)

自分の書籍の中身やイベントがめちゃくちゃ楽しかったという話は本記事ではいったん置いておいて、そんな「お金」の面について具体的な数字、気付きなどを書いておきたいと思います。

1日の売り上げ詳細

実践ARKitMetal入門、どちらも製本版+電子版のセットで2000円で販売しました。どっちが何冊売れたかはちゃんと数えてないのですが、だいたい3:1ぐらいでARKitのほうが多かった感じです。

で、現地で約36万円売れて、Web(BOOTH)でも同日に10万円程度を売り上げました2

印刷代は合計で11.5万円ぐらいで、BOOTHは手数料が3.6%、ダウンロードコード発行代が約1万円(コンカ)。粗利だけで33万円という感じです。

この金額の意味するところ

とはいえ技術書典での1日と同じ水準で売れ続けるわけはなく、これからは電子版を中心にポツポツ売れるだけなので、実際のところ「ご飯を食べるタネ」としてはまだまだ心もとないかもしれません。

しかし、この金額は僕にとっては非常に大きな意味を持ちます。

というのも、いままでにちゃんと「本屋に並ぶ技術書」も書かせていただきましたが(いわゆる商業出版)、印税率は8%で、共著だとそこから折半なので、たとえば4000円の本を買ってもらって1冊あたり160円。初版2000部のぶんはもらえるので32万円。これが何ヶ月かフルタイムで執筆してのトータルの収益3だったのです。

また別の話ですが、僕はGitHubでいろいろとOSSを公開していて、合計で約23,000スターを獲得しています。もちろんスター数が絶対的な価値を持つわけではありませんが、しかしソースコードを公開してエンジニアコミュニティに多少なりとも貢献をしているとはいえると思います。

そんなGitHubpaypal.meのお布施リンクを置いてみてはいますが、いまのところトータル収益はゼロ円です。

それとはまた別に、Qiitaでは21,000コントリビューション以上ありますが、もちろんここからの収益はありません。

それとカンファレンスでの登壇は、(略)

つまり何がいいたいかというと、いままで技術情報の発信というのは基本的に無報酬、お金とは違うところに意味を見出しつつ、稼ぎはそれ自体ではなく別のところで得るしかなかった、ということです。

それが、今回の技術書典5では、技術情報発信(ここでは書籍)自体でそれなりの稼ぎがあったので、これはエポックメイキングだなと。

というわけで個人的にすごく楽しくなってきたので、今後の動き方を考えるためにも、今回の技術書典5を振り返って(売り上げの観点から)「やってよかった」と思うことを書いておきたいと思います。

やってよかったこと

前日からBOOTHで販売開始

今回の実践ARKitは、技術書典の前日にはBOOTHで電子書籍版の販売を開始し、告知しました。

あと、当日会場での「開封の儀」をツイートしたりと、タイムラインからでも会場の温度感が伝わるようにしました。

東京の池袋で1日だけ開催された技術書典。非常に盛り上がったとはいえ、東京以外にお住まいの方々にとってはこのためだけに来るというのはハードルが高いと思います。

  • 遠方の多くの人は技術書典に来れない
  • しかし注目はしている=熱気は届いている

というわけで、タイムライン見てて、なんかツイートとか流れてきて「いいな〜買いたいな〜」と思ったそのときにネットで買えるなら買ってしまうのではないでしょうか。「電子版は後日用意します」は思っている以上に大きな機会損失かもしれません。

印刷代の割増を恐れずギリギリまで書く

どんな時間管理術や仕事術を弄したところで、結局一番捗るのは締切間際、というのが現実かと思います。締切間際のあの集中力と決断力はプライスレスです。

ギリギリまで粘ると印刷代の割増料金がかかるといっても1日で5%程度、元の印刷代を仮に40,000円とすると、たかだか2,000円です。たったの2,000円で締切間際の集中力ブーストがもう1日分買えるなら買うしかない、と判断しまして、入稿を10%割り増し(2日延長)の10/4(技術書典は10/8開催)に行いました。この2日の作業で本のクオリティは50%はアップしたと思います。

安売りしない

前回の「Metal入門」は、技術書典初参加で、まったく空気感もわからず、「自分のとこだけ売れなかったら寂しいなー」と日和って1,200円という価格設定にしました。しかしこのMetal入門いまでも日本語では唯一のMetalのまとまった情報源で、非常にニッチな本なので、いくら安かろうがいらない人はいらないし、欲しい人は高くても買うという類のものです。なんせ代わりがないので。数は出ないけど高くても売れる、ニッチというのは弱みでもあり強みでもあるのです。

今回の新刊のテーマであるARKitはもうちょいメジャーで、同フレームワークを扱った書籍は商業・同人共にいくつか出てますが、しかしネイティブでのARKit開発(Unityではなく)を扱っていて、著者にしっかりとしたiOSのバックグラウンドがあり、体系立てて構成も練られている、となるとやはり商業出版含め代わりはないかなと思っています。

そんなわけで、「製本版+電子版とのセットで2000円」と、技術書典としては少し高めの水準の価格設定にしました4。結果的にはちゃんと売れて、合計としても前回の2倍という売り上げになったので、これでよかったのかなと思います。

売れ残りを恐れず刷る

「完売の誘惑」というのはあって、やっぱり早々に売り切って「完売しました!」とツイートして、他のブースまわったりしたい、というのはあります。

また普通の小売業にとって在庫を抱えるというのはリスクを伴うことだと思います。単純にうちの場合、余った本の箱を家に送ろうものなら奥さんに間違いなく迷惑がられます。

しかし今回、技術書典会場に【BOOTH倉庫に無料発送できる窓口】という窓口が設置され、

もはや売れ残りを恐れる理由はなくなりました。在庫が多すぎると保管料が1000円かかるとのことですが、送る物品のサイズ・重量・管理コストを考えれば、気にするべくもないめちゃくちゃリーズナブルな価格だと思います。

というわけで僕は当初の予定より1.5倍ほど多めに刷りました。もはや売れ残りすら楽しみになって、早くBOOTHの在庫に反映されないかなーと心待ちにしています。

おわりに

「やってよかったこと」を書いてみましたが、当たり前すぎますかね。。

とにかく、「技術の発信」でも収入が得られる時代が到来しつつあることが嬉しいです。お客さんの課題に対して技術力をふるう「案件」も好きですが、その仕込みフェーズ自体でも稼げるとなると、より自由に生きるための選択肢が増えたような、そんなワクワク感があります。

技術書典6で書きたいネタも山程あります。引き続き勉強と発信を続けていきたい所存です。


  1. 本屋に自分の本が並ぶというのは親にも親戚にも誇らしかったし、エンジニアとしての箔はついたと思うし、仕事に繋がった面もあるし、海外でも物理的な本は自慢になったし、もろもろメリット・デメリット比較して書きたいと思ったから書いたわけで、実際書いてよかったと今も思います。

  2. 新刊は前日からBOOTHという販売サイトにて電子版の販売を開始しました。

  3. 書いた本はどちらも2, 3回増刷されましたが、なんやかんやの規約があってなかなか増刷分は入ってこなかったりします

  4. BOOTHでの通常販売はもうちょい高めになっています。

ARKitの解説書を個人出版しました #技術書典 #技術書典5

ARKitの解説書「実践ARKit」を本日よりBOOTHにて販売開始しました!ARKit 2.0 (iOS 12)・Xcode 10・Swift 4.2対応、全92ページ。サンプルコードはGitHubよりダウンロード可能です。

shu223.booth.pm

なお、明日開催される技術書典5では製本版+電子版セットで2000円で販売する予定です。だいぶお得です。サークル名は「堤and北」、配置は「う65」です。

techbookfest.org

書籍の紹介

本書は、作りながら学ぶネイティブARKitアプリケーション開発の実践入門書です。

はじめの一歩として3行で書ける最小実装のARから始めて、平面を検出する方法、その平面に仮想オブジェクトを設置する方法、そしてその仮想オブジェクトとインタラクションできるようにする方法・・・と、読み進めるにつれて「作りながら」引き出しが増えていき、最終的にはARKitを用いたメジャーや、空間に絵や文字を描くといった、ARKitならではのアプリケーションの実装ができるよう構成しています。

全92ページ。ARKit 2.0 (iOS 12), Xcode 10, Swift 4.2対応。サンプルコードはGitHubよりダウンロード可能です。

f:id:shu223:20181007153454p:plain

目次

第1章 入門編その1 - 最小実装で体験してみる

  • 1.1 手順1:プロジェクトの準備
  • 1.2 手順2:ViewControllerの実装
  • 1.3 基本クラスの解説

第2章 入門編その2 - 水平面を検出する

  • 2.1 水平面を検出するためのコンフィギュレーション
  • 2.2 平面検出に関するイベントをフックする - ARSessionDelegate
  • 2.3 平面検出に関するイベントをフックする - ARSCNViewDelegate
  • 2.4 検出した平面を可視化する

第3章 入門編その3 - 検出した水平面に仮想オブジェクトを置く

  • 3.1 3Dモデルを読み込む
  • 3.2 仮想オブジェクトとして検出した平面に置く

第4章 ARKit 開発に必須の機能

  • 4.1 トラッキング状態を監視する
  • 4.2 デバッグオプションを利用する
  • 4.3 トラッキング状態をリセットする / 検出済みアンカーを削除する

第5章 平面検出の基礎

  • 5.1 垂直平面の検出
  • 5.2 検出した平面のアラインメントを判別する
  • 5.3 平面ジオメトリの取得
  • ARPlaneGeometry と ARSCNPlaneGeometry

第6章 AR 空間におけるインタラクションを実現する

  • 6.1 ヒットテスト(当たり判定)を行う
  • 6.2 デバイスの移動に対するインタラクション

第7章 AR 体験の永続化と共有

  • 7.1 ARWorldMap
  • 7.2 ワールドマップを取得する
  • 7.3 ワールドマップを永続化・共有する
  • 7.4 ワールドマップからセッションを復元する
  • 7.5 ワールドマップ取得タイミング

第8章 フェイストラッキング

  • 8.1 フェイストラッキングを開始する - ARFaceTrackingConfiguration
  • 8.2 検出した顔のアンカーを取得する - ARFaceAnchor
  • 8.3 顔の動きを可視化する
  • ブレンドシェイプでアニ文字風3Dアバター

第9章 特徴点を利用する

  • 9.1 特徴点を可視化する
  • 9.2 フレームに含まれる特徴点群データ
  • 9.3 ワールドマップに含まれる特徴点群データ

第10章 デプスを利用する

  • 10.1 ARFrameからデプスデータを取得する
  • 10.2 デプスを取得可能なコンフィギュレーション

第11章 ビデオフォーマット

  • 11.1 ARConfiguration.VideoFormat
  • 11.2 ビデオフォーマットを指定する
  • 11.3 使用可能なビデオフォーマット
  • 現行デバイスで使用可能なビデオフォーマット一覧
  • ビデオフォーマットはどう使い分けるのか?

第12章 アプリケーション実装例1: 現実空間の長さを測る

  • 12.1 ARKitにおける座標と現実のスケール
  • 12.2 現実空間における二点間の距離

第13章 アプリケーション実装例2: 空中に絵や文字を描く

  • 13.1 スクリーンの中心座標をワールド座標に変換する
  • 13.2 頂点座標の配列から、線としてのカスタムジオメトリを構成する
  • 13.3 その他の実装のポイント

第14章 アプリケーション実装例3: Core ML + Vision + ARKit

  • 14.1 CoreML・Vision・ARKit連携のポイント

第 15 章 Metal + ARKit

  • 15.1 その1-マテリアルをMetalで描画する
  • 15.2 その2-Metalによるカスタムレンダリング

対象読者

「実践入門書」を謳っている通り、実践を主眼に据えつつあくまでARKit入門者向けです。すでに現場でゴリゴリに触ってる人には物足りないかもしれません。また本書はネイティブiOSアプリ開発の話で、Unityを使ったARKitアプリの開発については書いてないです。

あと、全面的にリライトしたりARKit 2.0対応したりしてますが、「iOS 11 Progamming」で執筆を担当したARKitの章を土台としてますので、そちらを既にご購入の方には重複する部分が多くなってしまうかと思います。目次をよくご確認いただき、ご検討ください。

表紙の話

もともとあった表紙の構想は、ARKitにとって象徴的なシンボルである(と僕は思っている)「あの」飛行機の3Dモデル"ship.scn"を「ちょっと浮いた感じで真ん中あたりにプリントする」(+タイトル)というシンプルなものでした。

f:id:shu223:20181007153656p:plain

(ship.scn。XcodeのARKitテンプレートに同梱されている)

が、そういう特殊加工をするには部数が足りない(しかもかなり高い)ことがわかり断念。

で、次になんとなく思いついたのが、ship.scnを手書きスケッチ風にしてオライ◯ー的表紙として仕上げることでした。

何度かバージョンアップして、今に至ります。

f:id:shu223:20181007162610p:plain

(左から、Beta 1、Beta 2、RC1)

f:id:shu223:20181007154222j:plain

(入稿版)

「Metal入門」製本版も復活します

技術書典4では完売御礼だった「Metal入門」も第2刷として製本版を販売します。マイナーアップデートでSwift 4.2, iOS 12, Xcode 10対応しております。こちらも技術書典のみ製本版+電子版セットで2000円です。興味あればぜひともこの機会に。

f:id:shu223:20180422101932j:plain

(製本版はマットな表紙とほどほどな厚みが手に馴染む、最高な仕上がりとなっております)

電子版はBOOTHでも販売しております。

shu223.booth.pm

こちらの記事に評判をまとめています。

関連記事

shu223.hatenablog.com

shu223.hatenablog.com

デプス(深度)をiOSで扱う方法を網羅したサンプルコード集「iOS-Depth-Sampler」を公開しました

iOSにおけるデプス(深度)関連APIの実装方法を示すサンプル集「iOS-Depth-Sampler」をオープンソースで公開しました。

github.com

ソースコードGitHub に置いてあるので、ご自由にご活用ください。Swift 4.2です。

今のところ6つのサンプル(後述)が入っています。本記事のタイトル「網羅した」は少し大げさですが、撮影済みの写真からデプスを取得する方法から、リアルタイムに取得する方法、ARKitで取得する方法、フロント/リアカメラ、Disparity / Depth / Portrait Matteといったタイプと相互変換、デプスを利用した背景合成や3D空間へのマッピングといったサンプルも備えています。

f:id:shu223:20180918074109j:plain

(2次元の写真をデプスを利用して3D空間へマッピング

今後iOSにデプス関連の機能が追加されるたびに、サンプルも追加していく予定です。

利用可能なデバイス

デュアルカメラもしくはTrueDepthカメラを持つデバイスを使用してください。 7 Plus, 8 Plus, X, XS, XRをお持ちの方はぜひビルドして遊んでみてください。リア(Dual Camera)とフロント(TrueDepth Camera)でそれぞれサポートしている機能が全然違うので、X or XSが理想です。

利用方法

git cloneしてXcode 10でビルドしてiOS 12端末 1 にインストール

以上です。Metalを使用しているのでシミュレータでは動作しない点、ご注意ください。

サンプル一覧

Real-time Depth

リアルタイムにカメラから深度情報を取得し、可視化するサンプルです。

f:id:shu223:20180913012136g:plain

Real-time Dpeth Mask

リアルタイムにカメラから取得した深度情報をマスクとして使用し、背景合成を行うサンプルです。

f:id:shu223:20180913012157g:plain

Depth from Camera Roll

カメラロールにある撮影済みの写真から深度情報を取り出し、可視化するサンプルです。標準のカメラアプリのポートレートモードで撮影した写真を利用できます。

f:id:shu223:20180913012537j:plain

Portrait Matte

Portrait Matte (Portrait Effect Matte)を使用し、背景を除去するサンプルです。ポートレートモードで「人間を撮影」した写真を利用できます。要iOS 12。

f:id:shu223:20180913012548g:plain

カメラはフロント・リアどちらもOKです。

shu223.hatenablog.com

ARKit Depth

ARKitで深度情報を取得し、可視化するサンプルです。

f:id:shu223:20180913012600g:plain

現状、ARKitではARFaceTrackingConfiguration使用時のみ(つまりフェイストラッキングARのときだけ)この方法で(※後で貼るスライド内で説明しています)深度情報を取得できます。

2D image in 3D space

写真(2D)を深度をz値として3D空間にマッピングするサンプルです。

f:id:shu223:20180915110312g:plain

AR occlusion

[WIP] An occlusion sample on ARKit using depth.

そもそもデプスって?

「デプスって何?」「何が嬉しいの?」「どういう仕組みで計測してるの?」といったところは拙スライドもご参照ください。

speakerdeck.com

デモやアニメーションを交えているので、動画の方がおすすめです。

www.youtube.com

付録: iOSで深度データにアクセスする方法のまとめ(書きかけ)

Qiitaにでも書こうとまとめてたのですが、途中になってるので、ここに一旦おいておきます。

PHAssetから深度マップ画像を生成

requestContentEditingInput(with: nil) { (contentEditingInput, info) in
    guard let url = contentEditingInput?.fullSizeImageURL else { fatalError() }
    let depthImage = CIImage(contentsOf: url, options: [CIImageOption.auxiliaryDisparity : true])!
    ...
}

深度データを持つPHAssetだけを取得する

let resultCollections = PHAssetCollection.fetchAssetCollections(
    with: .smartAlbum,
    subtype: .smartAlbumDepthEffect,
    options: nil)
var assets: [PHAsset] = []
resultCollections.enumerateObjects({ collection, index, stop in
    let result = PHAsset.fetchAssets(in: collection, options: nil)
    result.enumerateObjects({ asset, index, stop in
        assets.append(asset)
    })
})

PHAssetが持つ深度データからAVDepthData生成

アセットのURLを指定して、CGImageSourceを作成する。

guard let source = CGImageSourceCreateWithURL(url as CFURL, nil) else { fatalError() }

CGImageSourceCopyAuxiliaryDataInfoAtIndexを使用する

let info = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDisparity) as? [String : AnyObject]
let info = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDepth) as? [String : AnyObject]

ここで得られる辞書型データは次のような情報を持っている。

  • the depth data (CFDataRef) - (kCGImageAuxiliaryDataInfoData),
  • the depth data description (CFDictionary) - (kCGImageAuxiliaryDataInfoDataDescription)
  • metadata (CGImageMetadataRef) - (kCGImageAuxiliaryDataInfoMetadata)

この辞書型データをそのままAVDepthDataのイニシャライザに渡せる。

let depthData = try! AVDepthData(fromDictionaryRepresentation: info)

CGImageSourceCopyPropertiesから深度に関する情報を取得する

以下のように辿って深度に関する情報を得ることもできる。

guard let sourceProperties = CGImageSourceCopyProperties(source, nil) as? [String: AnyObject] else { fatalError() }
guard let fileContentsProperties = sourceProperties[String(kCGImagePropertyFileContentsDictionary)] as? [String : AnyObject] else { fatalError() }
guard let images = fileContentsProperties[String(kCGImagePropertyImages)] as? [AnyObject] else { return nil }
for imageProperties in images {
    guard let auxiliaryDataProperties = imageProperties[String(kCGImagePropertyAuxiliaryData)] as? [[String : AnyObject]] else { continue }
    ...
}

こういう情報が取れる。

["Width": 576, "AuxiliaryDataType": kCGImageAuxiliaryDataTypeDisparity, "Height": 768]

とはいえ深度マップのデータそのものは入っていない。

AVCaptureSynchronizedDataCollectionからデータを取り出す

AVCaptureDataOutputSynchronizerDelegateのdidOutputメソッドの第2引数からAVCaptureSynchronizedDataCollectionオブジェクトが得られる。

func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer, didOutput synchronizedDataCollection: AVCaptureSynchronizedDataCollection) {

    if let syncedDepthData = synchronizedDataCollection.synchronizedData(for: depthDataOutput) as? AVCaptureSynchronizedDepthData, !syncedDepthData.depthDataWasDropped {
        let depthData = syncedDepthData.depthData
        ...
    }
    
    if let syncedVideoData = synchronizedDataCollection.synchronizedData(for: videoDataOutput) as? AVCaptureSynchronizedSampleBufferData, !syncedVideoData.sampleBufferWasDropped {
        let videoSampleBuffer = syncedVideoData.sampleBuffer
        ...
    }
}

iOS 12のPortrait Matte

let info = CGImageSourceCopyAuxiliaryDataInfoAtIndex(self, 0, kCGImageAuxiliaryDataTypePortraitEffectsMatte) as? [String : AnyObject]
let matte = try! AVPortraitEffectsMatte(fromDictionaryRepresentation: info)

  1. ほとんどのデプスAPIiOS 11から使えるのですが、インパクトのある「Portrait Matte」がiOS 12〜なので、本サンプルはiOS 12以上にしてしまいました。