iOSDC でベストトーク賞(3位)をいただきました
8/19-20 にかけて開催された 400人規模 600人規模のiOSカンファレンス「iOS Developers Conference Japan 2016」にて「Xcode で快適なデバッグライフを追い求める」というタイトルで発表させていただきました。
以下、CFPより
僕は怠惰な人間です。プログラミングの大半はデバッグに時間を費やすと思っているので、なるべく早く原因に辿りついたり効率のよいデバッグライフを送りたいと常々思っています。 プリントデバッグもいいのですが Xcode には便利な機能が色々とあります。それらを使うことで簡単に原因を特定できるケースがあります。 visualize されるのは分かりやすいですよね。 それらを tips で紹介できたらなと思います。
発表資料
皆さん怠惰ですよね…? -Xcodeで快適なデバッグライフを送りましょう- #iosdc #a - Togetterまとめ
動画
(近々配信される予定ですので、後ほど埋め込みます)
ベストトーク賞(3位)
投票してくださった皆様のおかげでいただくことができました、ありがとうございます!!!
発表直前まで、この話しおもしろいのか...そもそも時間内に終わるのか...と不安だらけでしたが、うまくいったようで良かったです。Diagnostics の発音が分からなくなった辺りから会場の空気が良くなったので、忘れて本当に良かったなとw
こういった賞レースとは縁遠かったので貰えるとは思っておらず、後ろでバドワイザーを飲んでLTの余韻に浸ってぼーっとしてたんで、しばらく気づかなかったです。。。
反響も多く興味も持ってもらえたようなので本当に嬉しいかぎりです。
LLDB 芸にハマりたくなる気持ち、それな、分かるという気持ちになってる
— Yusuke Sugamiya (@DNPP) August 20, 2016
Xcodeデバッガーの奴、知見に溢れていて素晴らしいセッションだった #iosdc
— ぎぎにゃん (@giginet) August 20, 2016
今スタッフ業務やりつつだから集中して聞けてないけど後で資料をじっくり見て復習したいトーク。 #iosdc #a
— akatsuki174 (@akatsuki174) August 20, 2016
— みろなる |∀・꒱.。oO (CIO) (@mironal) August 20, 2016
会場ドッカンドッカンわかせてた発表だ。 https://t.co/UadlqjPk1M
— huin (koichisakata) (@huin) August 20, 2016
有用過ぎる!!!! / “Xcode で快適なデバッグライフを追い求める // Speaker Deck” https://t.co/iggypVDGYn
— kazuph (@kazuph) August 20, 2016
.@dealforest さんのすごいところは「めんどくさい」で終わらせるんじゃなくて、それをちゃんと解決してしまうところだと思った / “Xcode で快適なデバッグライフを追い求める // Speaker D…” https://t.co/twLyR3xzNE #iosdc
— Kosuke Ogawa (@koogawa) August 22, 2016
補足
発表自体かなり駆け足気味で話してしまったので、少し補足しておきます
Xcode Plugin が動かなくなる
Xcode のバイナリから証明書を消せば一部の Plugin は使えるようになります。みんな大好き XVim は動きます。
すべての Plugin が動くわけではなく一部なので何が原因か特定できず GM が出たタイミングでもう一度調べようと思っています。
詳しくは「Xcode Editor Extension と Xcode8 で Plugin が動かなくなったことについて発表してきました」をどうぞ
どの ViewController かわからない問題
symbolic breakpoint を使えば、特定のセレクタが実行されたタイミングでブレイクできるので、わざわざここかな?と推測してログを仕込んだりしなくても済むというお話でした。
LOG_CURRENT_METHOD
すでに仕込まれていれば便利ですけど、人が仕込むものなので、忘れられている可能性もあったりしますしね。
あとログが出すぎでうざったいとかも Breakpoint だと、該当する箇所だけ無効にするのも簡単です。
実機のログやファイルを取得したい問題
ここで特に触れていなかったので LLDB にslack コマンドがあると思ってしまったかもしれません。すみませんでした。
LLDB のコマンド自体に slack
コマンドはなく拡張しました。
gist から DL して、~/.lldbinit
から import しておくと、slack
コマンドが使えるようになります。
このようにデバッグ用のコードを LLDB のコマンドに寄せると、どのプロジェクトでも使えるし #ifdef DEBUG
のことも気にしなくていいようになるので、ライブラリにするより LLDB のコマンドで実装するようにしています。
おわりに
iOSDC はあの規模の人数を滞りなく終えていたので、とても初回のイベントとは思えませんでした。 さらに懇親会のビールの充実感がすごくて、COEDOの鞠花がビールサーバーであったり BREWDOG やよなよなエールがあったりなど、お酒好きの自分からすれば最高の懇親会でした。
良いカンファレンスは良いビールから。
これだ!!!と思い、これからこのフレーズは使っていきたいなと思いました。
今回のiOSDCやっぱり運営もiOS界隈の人だった事は大事な事実。自分たちも見たいトークがあるのに運営にコミットしてくれた人が沢山いるた。参加者の僕らができるのは来年は運営にもコミットしてみんなが学びの時間になるイベントにする事だと思う。来年は絶対やるよー #iosdc
— huin (koichisakata) (@huin) August 20, 2016
本当にこのとおりで、実行委委員長の長谷川さんはじめ、スタッフの皆さん、本当にお疲れさまでした!!!! 最高な2日間を過ごせました、ありがとございます!!!
おしらせ
iOSDC では話せなかった、もっと LLDB にフォーカスを当てた内容を発表させていただく予定です。
- AKIBA.swift×Swift愛好会 では 「LLDB の世界からみた Swift」
- iOSDC Reject Conference days2」では「魅せるデバッグ技術」
定員は超えていますがおそらく当日キャンセルも出ると思うので、今申し込んでも参加できる可能性が高いかなと思います。
「Intrducing debug in WWDC2016」という内容で発表してきました
「WWDC.next」で発表させていただきました。
WWDC のデバッグセッションは今すぐにでも実践できる tips が意外に多いので普段のデバッグの手助けになると思います。 ただしボリュームが結構でかいので心が折れないように進めていくのをオススメします。 (1日で全部見て気持ち悪くなりました...)
「Xcode で快適なデバッグライフを追い求める | iOSDC Japan 201」にトークを応募したのでもしかしたら話せるかもしれません。
ではでは。
Tokyo Server-Side Swift Meetup で「swift build と Xcode での build の違い」について発表してきました
「Tokyo Server-Side Swift Meetup #4」で発表させていただきました。
このイベントがきっかけで server side swift に初めてふれてみたのですが、久しぶりに web の開発をした気がしてとても楽しかったです。 Xcode で使うことを気にしなければ簡単に試せたのでイメージはすごい変わりました。
資料の中(P.43)に書いていたのですが SPM で dylib を Build するものに関しては、どうしても Xcode 側でうまく Build することができませんでした。
framework と dylib が絡む Xcode の設定がおかしいのかなと。
とはいえ clang
に -framework
で compile しようとしているのに、なぜ -l
しようとしてるのかもよくわかりません。
仕方ないので力技で swift build
で作成した dylib
を参照するようにして解決しました。
この辺りがなぜなのか分かる人がいれば教えてもらえるとありがたいです。
noppoMan/Slimane は現時点で気軽に試せるのでオススメです。(swift build で使う分には。)
ではでは
Xcode Editor Extension と Xcode8 で Plugin が動かなくなったことについて発表してきました
「FiNC WWDC振り返り勉強会」と「potatotips #30 (iOS/Android開発Tips共有会)」で発表させていただきました。
内容としては Xcode Editor Extension についてと、既存の Xcode Plugin が Xcode8 では動かなくなるのを回避する方法があるよ。 という内容を話しました。
ngs さんと同じ内容を話していたので該当箇所は結構削ったので Xcode Editor Extension について、そちらの資料を見るのがいいかなと思います
Xcode の非証明バイナリを作る方法を gist にスクリプトでまとめておきましたので自己責任でお願いします。
非証明バイナリにするというのはどうなのかといった話もあると思いますが、それでも Plugin を使いたい人もいると思うのでそういう人にはいいんじゃないでしょうか。 個人的には DL してきて正しい証明されてるものと確認した後に抜くのでいいんじゃないかなと思ってます。
ただ非証明 Xcode でも動かない Plugin もあって、それの原因がよくわかってません。 もうすこし調べれば分かるかなと思ってます。
Xcode Source Editor Extension はいい仕組みだと思うので、しばらくの間の移行期はこれで耐え忍ぶしかないかなと個人的には思っている次第です。
このようにフィードバックを送って API を増やしていってもらえれば、1年もすればすんなり移行できてたりするかもしれませんね。 まぁ Plugin をつかわないように調教するのもひとつの手段だとは思いますが。
Anglerfish について potatotips#29 で LT してきました
potatotips #29 (iOS/Android開発Tips共有会) で LT をしてきました。 主催の方々お疲れ様でした。とても楽しめました。
id:koogawa さんの 「 2016/5/25 #potatotips #29 (iOS/Android開発Tips共有会) に参加してきたよ」が当日の様子がわかりやすいのでオススメです。
発表内容
今回は Anglerfish という Xcode Plugin を作ったのでそれについて話しました。 Anglerfish とは iPhone の simulator を使用順にソートする Xcode Plugin です。
まだ Xcode 起動時の情報を基にしてソートするしかできないのですが今後はもう少し機能を追加する予定です
simulator のソート順をリアルタイムに反映v0.1.1 実装済- ソートの on/off を切り替え
- ショートカットで deivce と simulator を切り替え
命名は niwatako 氏にお願いしました。 いつもありがとうございます。
@dealforest 狙ったものをピックアップする感覚で アンコウ Anglerfish (Anglerは"釣り")https://t.co/meLe3Vh4X2
— にわタコ (@niwatako) May 18, 2016
使ってくれたら何かフィードバックがあると嬉しいです、ではでは
xcode-install を利用した Xcode のバージョン管理をやってみた
Xcode のバージョン管理するが面倒くさい!そう思ったことはありませんか?
App Store から DL しても途中で失敗したりなかなかうまいこといきません。 仕方がないので Developer Center から直接 DL してきます。 そして古い Xcode.app をリネームして残しておき、新しいのと入れ替える。
そう、めんどくさいんです。。。
そんな時に neonichu/xcode-install と出会いました。 作者は try! Swift でも登壇されていた Boris Bügling さんです。
これは rbenv のような **env 系と似たような interface を持つ CLI で Xcode のバージョンを管理するのに特化しています。
これがとても便利だったので紹介します。
xcode-install の使い方
Installation
gem install xcode-install
Xcode を DL する際に Developer Center にログインする必要があります。
毎回ログイン情報を入力するのもめんどくさいので、XCODE_INSTALL_USER
, XCODE_INSTALL_PASSWORD
の環境変数を指定しておくと楽になります。
password はいやだって人は ID だけでも設定しておくと、一度パスワードを入力すると次回からは keychain から取得してくれるのでそれでもいいかなと思います。
ここの部分は fastlane/credentials_manager を使っているようです
Usage
$ xcversion update $ xcversion install 7.3.1
仕組みとしては簡単で Xcode_x.x.x.dmg を cache ディレクトリに保存し、それを /Application/Xcode-x.x.x.app にインストール後、xcode-select
を実行してバージョンを切り替えてくれます
以下、ざっと使うコマンドを紹介していきます
インストール可能なバージョン一覧を表示
$ xcversion list 7 7.0.1 7.1 7.1.1 7.2 7.2.1 (installed) 7.3 (installed) 7.3.1 (installed)
--all
をつけると、さらに古いバージョンも表示されます
インストール可能なバージョン一覧を更新
$ xcversion update
インストール済みのバージョン一覧を表示
$ xcversion installed 6.4 (/Applications/Xcode-6.4.app) 7.2.1 (/Applications/Xcode-7.2.1.app) 7.3 (/Applications/Xcode-7.3.app) 7.3.1 (/Applications/Xcode-7.3.1.app)
DVTPlugInCompatibilityUUID
を一覧で表示するオプションを追加した PR がマージされたので 1.3.0 の次のバージョンから使えるようになるでしょう。
Xcode Plugin を作ってる(使ってる)人には大助かりですね。
はやく使いたい方は master からインストールしてもらえれば使えます
$ xcversion installed --uuid 6.4 (/Applications/Xcode-6.4.app) 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 7.2.1 (/Applications/Xcode-7.2.1.app) F41BD31E-2683-44B8-AE7F-5F09E919790E 7.3 (/Applications/Xcode-7.3.app) ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 7.3.1 (/Applications/Xcode-7.3.1.app) ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C
利用する Xcode を変更
$ xcversion select 7.3.1
Simulator の install 状況を確認
$ xcversion simulators Xcode 7.3.1 (/Applications/Xcode-7.3.1.app) iOS 8.1 Simulator (installed) iOS 8.2 Simulator (installed) iOS 8.3 Simulator (installed) iOS 8.4 Simulator (installed) iOS 9.0 Simulator (installed) iOS 9.1 Simulator (not installed) iOS 9.2 Simulator (installed) tvOS 9.0 Simulator (installed) tvOS 9.1 Simulator (installed) watchOS 2.0 Simulator (installed) watchOS 2.1 Simulator (installed)
Simulator を install
$ xcversion simulators --install='iOS 9.1 Simulator'
Xcode_x.x.x.dmg を削除
一度 DL した Xcode_x.x.x.dmg は保存されたままになります。
ディスク容量が気になる方は cleanup
を実行して削除してください
$ xcversion cleanup
はまりどこ
Developer Center にログインすると利用規約への同意画面が表示されるような状態のアカウントを使うと Xcode の DL に失敗(タイムアウト)します。 普段使っていないアカウントを使う場合は一度ログインして確認しておきましょう。
まとめ
xcode-install
を使うことによって Xcode のアップデートが以下のような手順になります。
$ xcversion update // 一覧更新 $ xcversion list // 入れたいバージョンを確認 $ xcversion install x.x.x // インストール
これだけで最新の Xcode が使えるようになり、バージョン管理も行ってくれます。 これで Xcode のヘッダーの diff をとってニヤニヤする作業もしやすくなりますね。
UIWebView で input[type=file] が正常に動かない対応について -決定版-
基本的なことは「iOSアプリのwebviewでinput[type=file]が正常に動作しない時」見てもらえれば分かるかなと思います。
簡単に説明すると画像を選択後 Image Picker を閉じようとした際に WebView をモーダルで表示していた場合、モーダルごと閉じられてしまうということです。
どういう view 構造にするかにもよりますがこのような構造でモーダルを表示していたとします。
[modal の view 構造] UINavigationController └── UIViewController └── UIWebView
この場合 UINavigationController
に対して解決方法を適応してやればいいわけです。
extension UINavigationController { override public func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) { if presentedViewController != nil { super.dismissViewControllerAnimated(flag, completion: completion) } } }
ただしこれだと問題があります。
それは UIActivityViewController
を使って新たに ActivityItem
を追加しようとした時です。
追加しようとしたモーダルが閉じれなくなってしまうんですね。。。
というわけで、その状況にも対応しようとするとこのようになります
extension UINavigationController { override public func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) { if presentedViewController != nil || presentingViewController is UIActivityViewController { super.dismissViewControllerAnimated(flag, completion: completion) } } }
HTML の方が楽な場合(複雑な投稿画面等)とかもあるのでそういう時では使っていきたいんですが、なかなか一筋縄ではいきませんね。 WKWebView では同じ現象が起きるかどうかは知りませんが起きないことを祈ります。