potatotips #50 に参加して来た
potatotipsとは
iOS/Android合わせて10数名が持ち時間5分の中でそれぞれのTipsを話す会です。
今回は第50回目(継続されててすごい!)の開催で、私はiOSブログまとめ枠として参加して来ました。今回初参加です!
ケータリングにもポテチが!
Yet another simple logger by @ngtk
「SwiftyBeaverはロギングプラットフォームとして使われようと頑張っていると感じる一方で、ロックインされたくない」という考えには同感した。
それなら作ってしまおう!ということでロガーのベーシックなところの実装方針がライトに説明されていました。
インターフェースの定義とか見ていて、行き着くところはJavaのSLF4Jなのでは!?!?とか思いながら聞いていました。
emojiはfilterbility?悪そう。
Taged by @to4iki
Conditional Conformanceを使って、型を制御しようという話。
下記のライブラリの話。
GitHub - pointfreeco/swift-tagged: 🏷 A wrapper type for safer, expressive code.
これは夢がある。コード量削減に繋がる覚えて置きたいテクニック。
APIクライアントをCodableで置き換えた話 by @kobakei
もっと、苦労した話があるかと思ったらそうでもなかった?ように見えた。
APIクライアントのインターフェースやCodableに準拠させる型の周辺くらいか。
dateDecodingStrategy
は知らなかった。
iOSは自動生成の夢を見るか by @nonchalant0303
DIの定義部分を自動生成で手間とミスを減らそうという試み。
これはできればやりたい。ランタイムで定義ミスでアプリが落ちるリスクを少なくとも軽減できる。
逸脱した書き方もこれで怒られるようになったりするのかが気になった。
Izumo by @nakajijapan
Izumo - markdown note tool - をリリースしました。 - おじさんは生きている
これを作った人。
CloudKitを使ってiOS/Macで同期できるMarckdownのエディタを開発した話。
同期処理や編集部分のコンフリクト、マークダウンパーサーの自作をしたとのこと。それぞれのトピックで30分ずつ話してほしい内容だった。
スライドはConpassにも発表者のツイートにもなかったのでとりあえず宣伝!開発お疲れ様です!
RxSwift, Codable, Moya APICooking @AkkyLab
サイバーの18新卒で研修後に参加?のようで驚いた。
WebViewがつらい @suxisuxido
ビジネス的なしがらみによって技術が制限されることで辛さやバグ、最終的にはUXが低下する未来が見えるような内容でした。
WebViewはあかん...
次は辛くない話をするそうです!
まとめ
potatotipsは名の通り、tipsを5分で話す会。
初参加で感じたこと自分の当たり前はだれかのTipsとして受け入れられるということ。
ということで、次は発表枠で応募しました。
Nintendo Switchのゲーム音とPCやスマホの音を同時に聴くにはBelkinのRockstarがおすすめ。
Nintendo Switchのゲーム音とPCやスマホの音を同時に聴くには?
Splatoon2やってますか?私はリーグ戦やプライベートマッチをよく楽しんでいます!
その時に必ずと言って使うのがDiscord。いわゆるボイスチャットです。
皆さんはボイスチャットをしながら、スプラの音をどうやって聞いてますか?
私はつい最近まで、
スマホにイヤホンをつなぎ、Discordをイヤホンで。
Switchにヘッドホンをつなぎ、イヤホンの上からヘッドホンを被せて
ゲーム音とボイチャを同時に聞いていました。
しかし、Rockstarを使えばヘッドホン1つで両方の音を同時に聴くことができることがわかりました。
ちゃんと配線するなら1万円くらいするオーディオミキサーが必要だと思っていましたが、
1500円程度で実現できたのでかなりコスパがよかったです!今回はそれを紹介します。
必要なもの
- Belkin Rockstar
- オスーオスケーブル
Belkin Rockstarはこちら
【正規代理店】belkin マルチイヤホンスプリッターイヤホン分配/分岐 ロックスター ブルー F8Z274btBLU
「1つの音を分配する」器機なのですが、
実は、 「出力をつなぐと、聞いている側で音が合成されて聞ける」んです。
下記をイメージしてもらうとわかりやすいです。
注意!! 同梱物として オス-オスのケーブルが1本含まれています。
なかなか自宅にないのがオスーオスのケーブル。実は1本含まれているので、新たに買う必要はありません!
「これを買った人はこれも買っています」にオスーオスケーブルがオススメされていて、自分は買ってしまった。。。
ただし、同梱されているケーブルは30cmほどで短いので、長いケーブルが必要な場合は別でオスーオスケーブルを買うか
延長ケーブルを1本買えばいいです。
イヤホンとヘッドホンを2つ使っていた時はたまに外れていたので、格段に便利になりました♪
CMSampleBufferの方向を取得する
ReplayKitのRPBroadcastSampleHandler
では1フレームの情報をCMSampleBufferとして受け取り、それを自由に扱うことができます。
今回はCMSampleBuffer
から方向を取得してみたいと思います。
結論からいうと下記でできます。
internal extension CMSampleBuffer { internal var orientation: CGImagePropertyOrientation { if let orientationAttachment = CMGetAttachment(self, RPVideoSampleOrientationKey as CFString, nil) as? NSNumber { if let orientation = CGImagePropertyOrientation(rawValue: orientationAttachment.uint32Value) { return orientation } } return .up } }
しかし、iOSの特定バージョン以前では RPVideoSampleOrientationKey
がリンクエラーで起動時に失敗します。
iOS 11.0 ~ NG iOS 11.1 ~ NG iOS 11.2.1 NG iOS 11.2.5 OK
という状況です。
また、
RPVideoSampleOrientationKey
の中身はRPSampleBufferVideoOrientation
なので、iOS11.0系の端末を使って下記のようにハードコードで試してみました。
しかしながら、方向の情報はnilになってしまい、取得することができませんでした。
CMGetAttachment(self, kCGImagePropertyOrientation, nil)
ダメ元で、CGImageのOrientationも試してみましたがダメ...
公式の情報を見る限りはiOS11.0~使えるはずなのですが。。。使えないじゃん(泣)という情報でした。
UITableViewCellの中身をRxで監視するときのtips
シナリオ
- テキスト入力をもつTableViewCellがある
- 画面には更新ボタンがあり、押した時に、キーボードを閉じたい
結論ソース
※諸々省略してます
// UITableViewCellにcellForRowAtIndexまでにunbindさせるための情報を定義する extension Reactive where Base: UITableViewCell { var prepairForReuse: Observable<Void> { return methodInvoked(#selector(base.prepareForReuse)) .map { _ -> Void in return Void() } } var obsolete: Observable<Void> { return Observable.merge(prepairForReuse, deallocated) } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as TextCell weak var weakCell = cell updateButton.rx.tap .takeUntil(cell.rx.obsolete) .subscribe(onNext: { [weak self] _ in weakCell?.closeKeyboard() }) .disposed(by: disposeBag) } }
sentMessageでprepairForReuseを監視
prepairForResuseとdeallocのどちらかのイベントを受け取るまで監視しておけば良いので、それらをまとめてobsoleteというイベントを生やしました。
これをしないと、tableViewをスクロールするたびにsubscribeが増えるので予期せぬ動作を引き起こす可能性がある。
2017年買ったもの
とりあえず、2017年買ったものの総評を書いていこうと思う。 あくまで個人的な感想です。
買ったもの
- SITPACK
- 婚約指輪/結婚指輪
- ゲーミングチェア
- 自作PC
- イケアのデスクセット
- Nintendo Switch
- ヘッドホンハンガー
- 1000BASE-T対応のスイッチングハブ
- 1000BASE-T対応のUSB-LANコネクタ
- iPad Pro 10.9 inch Cellularモデル 256GB
- Apple Pencil
- LinksMateのSim 5GBプラン
- iPhone X
- Apple Watch Series 3 Cellularモデル
- MacBook Pro 15inch BTO(CPU3.1GB, SSD1TB, US Keyboard)
- USB-C to USB-A
- HDMI=DVIケーブル
- JetBrains All in Pack
リストにすると、必要な物ではなく欲しいものを買いすぎているなぁ。。。という印象 来年は買う前の判断を厳しくしていこう。
SITPACK
一口総評: 「★2 活躍できていない」
2017年1月頃入手
一言で言うと、「超コンパクトな折りたたみ椅子」
Makuakeのクラウドファンディングで1年位前にファンディング したのがやっと届いた。
ファンディング時には遅くとも1年前には届いてる予定だったけど、生産体制ができてないのにファンディング枠を増やして受注してたとのことで、届かない状態が1年くらい続いてた。
本当にくるか心配だったけど1年越しで入手。
毎月のように来る謝罪メールを確認するのが日課になっていた。
1個5000円くらいしたのかな。4つセットで購入し2つは家庭用、2つは友人に
予定どおり来ていれば海外旅行に持っていくはずだったのだけど、機会を逃したため全く使えていない
1年の始まりとして、非常に香ばしいスタート
結婚指輪/婚約指輪
一口総評: 「★5 嫁が喜んでくれた。よかった」
1月末に注文し、3月中旬ごろに完成
プロボーズを1月に結構し、承諾してもらったため一緒に嫁と買いに行った。
表参道のとあるお店で嫁が気に入ったものがあったので即決。
手元に届くまで約2ヶ月.
もともとアクセサリー系はだめな人間で、つけ始めたときの違和感が異常だったけど、すぐに慣れた。
自作PC
一口総評: 「★5 PCゲームでも、開発用でも活躍」
2017年2月頃に購入
8年ぶりに自作PCをやりたくなったため、独身最後の贅沢や!とそこそこのスペックを揃えた。
スペック (リンクはAmazonに飛びます。)
- CPU: Intel i7 7700K
- CPUクーラー: CORSAIR H115i CW-9060027-WW
- メモリ: GSK F4-2400C15D-32GVR
- マザボ: ASUS STRIX Z270F GAMING
- グラボ: ASUS ROG STRIX-GTX1080-A8G-GAMING
- キャプボ: Intensity Pro 4K
- 電源: CORSAIR HX850i
- SDD: ADATA XPG SX8000 ASX8000NP-512GM-C (M.2接続SSD)
- HDD: Western Digital WD30EFRX
- ケース: CORSAIR Crystal 570X RGB CC-9011098-WW
- OS: Microsoft Windows 10 Pro
- Display 1: iiyama ProLite GB2488HSU-2
- Display 2: iiyama ProLite E2483HS-B1
- キーボード: RealForce 87UB
- マウス: Corsair Katar
CPU, メモリ, マザボ, SSD, グラボはド定番みたいなところをチョイス 2,3年はパーツを買い換えなくても大丈夫だと思う。
基本的にはPUBGやスプラトゥーンの録画・ライブ配信に使っているのですが、
Androidアプリのビルドサーバーとして使ったりUbuntu載せたりして楽しんでます。
PCケースが2月頃は品切れ中で、黒透という3000円くらいのケースを一時的に使っていた。
一時的とはいえ完全にケチったせいで、グラボが収まらなくて、しばらくPCの外にはみ出た状態で運用していたw
汎用性を持つものの購入はやはりいいですね。
本業ではゲームの生放送サービスのネイティブアプリのエンジニアをやっているので、自分の生活にシンクロした買い物だったと思う。
CPUクーラー CORSAIR H115i CW-9060027-WW
ちょっとラジエータがでかい。大きさ的には 50cm四方くらいのケースを付けてやっと搭載できるレベル
Intensity Pro 4K
1080p60fpsをキャプチャできるもので、一番XSplitやOBSと相性が良かった。
実は他のキャプボで試したところ映らず、1度も使わずして売った時は凹みました。
電源 CORSAIR HX850i
組んでるPCもミドルクラスなのでそれに合わせた感じ。将来、GPU2つかもしれないということでこの容量。そしてPlatinum。
キーボード RealForce 87UB
一口総評: 「★3 HHKBは駆逐されるのだろうか」
しぶい!HHKBに近い打鍵感 。安定感を生み出す1.4kg。
上がRealforce, 下がHHKB Professional2
矢印キーがないHHKBが一回り小さい印象。 打鍵中に安定するな〜と思っていたら、底面のすべり止めもまた大きめだった。
また、US配列だと半角/全角の切り替えが若干めんどくさかった。
自分は右下のaltをあまり使わないので、そこに半角/全角の切り替えを割り当てました。
IKEAのデスク
一口総評: 「★3 機能性よりもシンプルさを選んでよかった」
2017年2月頃に購入
PCとモニターを設置するために購入。
リビングに置くので、見た目を嫁にも相談し、白のデスクにした。
掲載している画像のテーブルトップよりも薄く丈夫なものがあったのでそちらに変更して購入。
LERBERGという名前の脚にテーブルトップを載せる形式。可愛い感じ
ワゴンとか棚は無いのがシンプルで良い。
ゲーミングチェア
一口総評: 「★3 リクライニングは良い」
デスクときたら椅子!
本当は人間工学系のイスを買いたいけど、高いということで、ゲーミングチェアを選択。
メルカリで偶然良品(AKRacing)に出会ったため、元値の5, 6割の値段で新品同様の品を手に入れることができた。
リクライニングで完全フラットになるので、小休憩しやすい。
余談ですが、AKRacingのHPの"AKRacing フォトギャラリー"はギャグだと思うので覗いてみてほしい。
きれいな女性がオフィスにゲーミングチェアで座ってたり、暖炉の前でくつろいでたりしている異様な空気感w
モニターアーム
(配線はこの後きれいにしました)
一口総評: 「★5 デスクがかなり広くなった」
2017年12月頃購入
Amazonのサイバーマンデーセールでガス圧式で移動が容易なできるモニターアームが安くなっていた。1万が6000円くらいだったかな
頻繁に位置を変えないなら、2枚設置可能で4000円台で最低要件を満たすモニターアームを発見し、購入
設置してみるとモニターの脚がデスクを占める割合が大きかったんだな〜と痛感した。
配線もアームに括りつけることができるので本当にスッキリした。実用性も気持ちよさも兼ね備えていて本当に買ってよかった。
ヘッドホンハンガー
一口総評: 「★3 定位置のための投資」
物の固定位置を決めることが収納の鍵(うまるちゃんの兄しらべ)らしいので、Amazonで800円くらいのものを購入。 確かに固定の位置に戻す癖がついた。
Nintendo Swiftchと諸々
一口総評: 「★3 安定」
購入したソフトは
Splatoon2にハマっていて、Splathon(企業対抗戦)にも参加した。
次の第7回は年が明けてすぐ!楽しみです。
1GBbps対応のネットワーク物理
スイッチングハブ、LANケーブル、Nintendo Switch用LANコネクタをすべて1GBbps対応にした。
不便は感じてなかったけど、ケーブルは余り物とか付属品でなんとかしていたので、ちゃんと1GBbps対応のものに刷新。
Apple製品たち
どんだけ肉の写真とってるんや・・・!!
- iPad Pro 10.9 inch Cellularモデル 256GB
- LinksMateのSim 5GBプラン
- Apple Pencil
- iPhone X
- Apple Watch Series 3 Cellularモデル
- MacBook Pro 15inch BTO(CPU3.1GB, SSD1TB, US Keyboard)
これだけでかなりの出費をしてる気がする…
言い訳をするならばAndroidエンジニアからiOSエンジニアへの転向がきっかけ。
iPad Pro 10.9 inch Cellularモデル 256GB
2017年8月頃に購入
一言総評: 「★3 確かにタブレットの方がカジュアルに調べ物や読書ができる」
デバッグ用の端末+プライベートや旅行でPCを持ち歩かないために購入
Nexus 9も持ってるが、やっぱりiPadProの方がサクサクだったので買い替えてよかった。
CellularモデルということでLinksMateのsimを指している。
AbemaやOPENRECを垂れ流しにしてるが、通信料がほぼディスカウントされるのでかなりいい。Wi-Fiの帯域を食わないのも○
未使用バケットが繰越せて、10GBくらいたまった月もあった。
Apple Pencil
一言総評: 「★3 さすがApple純正のシンクロ率。。。だけど高いような。」
iPadの画面を触りたくなくて購入。やはり純正品同士のシンクロ率はソニー製品くらい感じる。
ちょっとしたメモや物事の整理をiPad + Pencilですることが多くなった。
iPhone X
一言総評: 「★3 安定のiPhone. 特に驚きはない。」
ずっとXperiaとNexusを使っていたがiOSエンジニアに転向したことと、プロダクトのiPhoneX対応をしたこともあって購入。
ホームボタンが無いことにはすぐ慣れた。
7plusから使えるようになったポートレート撮影はかなり重宝していると思う。嫁が夕食の写真を毎度撮っているのだけど、Xを貸してくれと言われる。しかもSNSには投稿しない(笑)
Xで撮った写真1
Xで撮った写真2
後ろの海老天までぼやけちゃってるけど、ポートレートモード楽しい。
Apple Watch Series 3 Cellularモデル
一言総評: 「★4 あると超便利、なくても困らない」
通知を選りすぐりしたり、頻繁にアクセスする情報(天気やスケジュール)が絞られているので
情報を確認するテンポの良さを感じた。
「時間という気になる情報を一瞬で把握できる」という時計のコンセプト に当てはまるものは意外と存在するなあという感覚。
また、通知から情報の詳細や他の情報に目移りしないようにできているのがいいなと思った。Android Wearのコンセプトもこんな感じだった気がする。
「時間を確認するコンテンツに時間を浪費する」わけにはいかない。
僕は好きです。
また、会社の入館証をApple Watchに登録していて、
入館証のチェッカーがちょうど左胸の位置にあたるので「それでも俺らは抵抗するで、拳で✊」出社を決めています。
MacBook Pro 15inch 2017 late BTO(CPU3.1GB, SSD1TB, US Keyboard)
一言総評: 「★3 ただ、ただ、高い」
12月24日に上海から届く。会社で使っているPCと同じスペックなので特にワクワクもない。
現在使っているのは5年前の物(2012年の初代Retina MBPにBTOでメモリを16GBにした)なのでそろそろ潮時。
Apple製品にしては特にトラブルもなく、5年もったことに驚き。(本来はこうあって欲しいw)
さすがにAppCodeを立ち上げると重くてコーディングするのが辛かったため、買い替え。
本当は絶賛キャンペーン中である 「ヨドバシのApple製品でもポイント10%キャンペーン 」に乗りたかったけど、US配列がないので断念。
会社にも家にもHHKBを使っているでノートの配列関係ないけど。
JetBrains All Products Pack
一言総評: 「★4 AppCodeの完成度が高い。ただし、Xcodeの新機能がワンテンポ遅れる」
Xcode9からAlcatrazが使えなくてVimバインディングが気軽にできなさそう だったので、AppCodeを検討しました。
IntelliJのみを契約していたが、AppCode(swift/objective-c)、たまにWebStormを使うので、All Products Pack を選択。
IntelliJは4年くらい使っているので、
使い慣れたIDEのショートカットがAppCodeでもそのまま使えるのがGood。
まとめ
My Best 3
- モニターアーム
- 自作PC
- iPhoneX
FastlaneがSwiftで書けるようになった〜
これはSwiftアドベントカレンダーの17日目の記事です。
Swiftの方はプラットフォームに依存しないエントリーを書くべきかと思いましたが、
FastlaneのSwift対応がタイムリーだったのでこっちにしました。
元はSwiftでTCPソケット通信を書こうと思ってたので、年末にでも。それでは本題へ
今回は下記のプロジェクトを元に紹介していきます。
https://github.com/matsuokah/fastlane-swift-samplegithub.com
Fastfileの設定ファイルやその周辺がSwiftで書けるようになりました
fastlaneがもともとRubyなのは周知の事実ですが、rubyの実装をSwiftから叩く実装が2.69.0から入りました。
Swift対応の実装方針としてはブリッジ、フック、そしてlane定義に分かれています。
ブリッジ: Rubyのコマンドをコールするラッパーを自動生成
フック: ブリッジファイルをコールしたり、エントリーポイントとなるコード
lane定義: コマンド(ブリッジ部分)を叩いたり、ビルドの設定や環境変数を定義している箇所
そしてこれらが、xcodeプロジェクトで管理できるようになっています。
今回の一番のポイントは「慣れたエディタで慣れた言語をつかえる」。これだけで効率化のイメージが湧きますよね
早速使ってみる
fastlane init swift
でfastlane関連のSwiftのファイルが生成されます。
To edit your new Fastfile.swif type: open ./fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj
というメッセージが出ています。
生成されたプロジェクトの開いて、グループの構成をみると下記のようになっていて、基本的にはFastfile.swift
だけを編集すればOK
* Autogenerated API => いわゆるRubyのブリッジ部分 * Fastfile Components * Networking => 文字通り * RunnerCode => フック部分 * Appfile.swift, Fastfile.swift => 設定、ビルドフローの定義ファイル * 各コマンド(Gymfile.swifなど)
このプロジェクトをビルドするとMacでexecutableなバイナリが出来上がります。
生成されたバイナリを介してfastlaneの部分が実行されています。また、fastlaneコマンドをつかって起動した場合、バイナリ自体のビルドもよしなに走るようになっています。
Fastfile
を編集してビルドする
Fastfile
クラスはLaneFile
クラスを継承しています。LaneFile
には各実装が織り込まれているのでビルドフローを詳しく知りたい人は読んでみるといいと思います。
つけるメソッド名はdebugLane
のように接尾辞を付ける必要があります。理由はlane
を接尾辞にもつメソッドをフィルタしてlaneを見つけ出してフックしているためです
class Fastfile: LaneFile { var fastlaneVersion: String { return "2.69.3" } func debugLane() { buildApp() crashlytics(apiToken: "TOKEN", buildSecret: "SECRET") } }
最低限の実装はこれだけで済むはずです。
ここからさらに ConfigurationやExport Methodなど、enumを定義してそれらを扱うクラスを用意すれば省コード化が可能になります。
enum Configuration: String { case debug case release var exportMethod: ExportMethod { switch self { case .release: return .appStore default: return .development } } }
上記はConfigurationの列挙ですが、プロジェクトによってはstagingや準本番のような環境もあるかと思います。
それらの環境変数を洗い出したあとは変数のマネージャクラスを用意すればOK
すべて記載すると長いので、Protocolだけ記載しておきます
protocol BuildContextProtocol { // Xcode var workspace: String { get } var scheme: String { get } var configuration: String { get } // Build var buildDir: String { get } var ipaName: String { get } var ipaPath: String { get } var dsymName: String { get } var dsymPath: String { get } var exportMethod: String { get } }
最終的には下記のようなコードに収まります。
func debugLane() { desc("Submit a new Beta Build to Crashlytics") let buildContext = BuildContext() buildContext.build() crashlytics(apiToken: "TOKEN" , buildSecret: "SECRET" , ipaPath: buildContext.ipaPath , groups: Fabric.testerGroup, notifications: true ) }
各環境変数・コンフィグの切り替えを省コード化して書いてみたサンプルをおいときます。
https://github.com/matsuokah/fastlane-swift-sample
今回省コード化のために抜き出した設定ファイルです
ハマったこと
- FastlaneRunnerをgit管理下に置こうとして失敗する
- gitignoreに追加しました。また、バイナリなので12MBほどの大きさです。毎度FastlaneのSwift部も勝手にビルドが行われて、バイナリが再度生成されるので追跡しなくていいと思います。
- ルビーでは配列で扱っている部分もすべてStringになっている
- Crashlyticsの
groups
とかがそうなのですが、rubyだと["tester1", "tester2"]
のように配列を指定できますが、SwiftではインターフェースにはString採用されているので使い方に工夫が必要になりそうです。
- Crashlyticsの
- 現状、メソッドにパラメータを渡していない
- 試してはいないのですが、フック部では
_ = fastfileInstance.perform(NSSelectorFromString(laneMethod))
と書かれていることから、引数が使えないのでは?と妄想しています。
- 試してはいないのですが、フック部では
まとめ
ということで、まだまだexperimantalで機能的にまだ満たされていない部分もありますがそこはPRポイントですね!
若干のワークアラウンドが発生しますが、FastfileがSwiftで定義でできるようになったことでグルーコードが非常に書きやすくなったかと思います!
個人的にはRubyが書けるならRubyでいいなと思います。あくまでRuby主導なリポジトリですので、Rubyで直接実行できるにこしたことはないです。
CIを前提としたプロジェクトのテンプレートができてた話
これはiOSアドベントカレンダーの10日目の記事です。
私にとって今年は、iOSエンジニアに転向した年でした。 それまではAndroid。 そして、携わっているプロジェクトのSwift化(未完)だったりiPhoneX対応だったりと劇的な半年でした。
ほぼゼロから始めたので、iOS SDKのサンプルアプリをいくつか作って勉強してたのですが、
そのうち、 CIを前提としたプロジェクトのテンプレートのような物が出来上がっていたのでそれを紹介したいと思います。
TL;DR
AnsibleでCIできるまでセットアップするプロジェクトテンプレートができてましたという話です。
大まかな使い方
- initialタグをチェックアウト
- プロジェクトをつくって、リポジトリと同じパスに配置。( initial-projectタグの状態を作る)
- プロビジョニング(Ansible)を実行(実行すると、apply-provisionタグの状態になる)
※ 実際に使う場合はトークンなどの認証情報が設定されている必要があります。
CI
- fastlane
Deploy
- Crashlytics Beta
Package Manager
- CocoaPods
Provisioning
- Ansible
- Bundler
テンプレートプロジェクト
下記のテンプレートプロジェクトをもとに詳細を書いていきます
https://github.com/matsuokah/ProjectTemplate-iOSgithub.com
リポジトリをクローンしてからfastlaneを叩くまで2,3コマンドでできるようにする
Ansibleで環境構築を自動化することで、fastlaneのコマンドを叩くまでの時間を短縮することができました。 なるべく前提を減らし、ビルドに必要なアプリケーションがなくても動くように作りました。
流れを書くと
make setup_tools
コマンドでシェルスクリプトをフック- シェルスクリプトでXcodeのインストール済みかどうかを判定。なければ、Safariを開いてXcodeのインストールを促す
- Ansibleがなければインストール、あればアップデート
- AnsibleのPlaybookを実行
Ansibleでやったこと
brew
で必要なアプリのインストール- 各テンプレートのデプロイ
bundler
のインストール
テンプレート
主に作ったテンプレートは下記の通り
.gitignore
Podfile
fastlane
関連Gemfile
.gitignore
.gitignore
は特にプロジェクト作る度にまずこれを作りますが、うっかり忘れたり、排除対象の列挙が漏れると思わぬファイルを追跡してしまいます。
gitignore.ioで作るのもめんどくさい
今回はある程度使うものを予め盛り込んだテンプレートで対応しました。
脱線しますが、CLIではcurl http://gitignore.io/api/swift >> .gitignore
という書き方も可能です。
Podfile
Crashlytics Betaを使いたいので予め盛り込んだ状態にしています。
XXXXX.xcodeproj
にヒットしたターゲット名で生成しています。これであとはpod install
するだけ。
よく使うライブラリは他にも盛り込んでもいいかも。RxSwiftとか。
fastlane
関連
テンプレート化したのは下記の3つ。Fastfile
以外は自前の定義ファイルです。
Fastfile
- ビルドシーケンス
AppContext
Env
Gemfile
- Bundlerのインストール
Fastlane
のEnv
の管理について
プライベートリポジトリを使っていたので、気にせず直書きしていました。(セキュリティの意識は甘々ですが別の漏れても被害はほぼないので。) また、サンプルを作るときには、Bitbucketを使っていました。Privateリポジトリの作成が無料かつ無制限につかえます。 余談ではありますがCIにはBitriseを使いました。Bitriseは10分以内ビルドなら月に200回まで無料で使えます。 iOSかつ、プライベートなリポジトリのCIが無料でできるのはBitriseだけ(俺調べ)
テンプレートの使い方まとめ(再掲)
- タグinitialをチェックアウト
- プロジェクトをつくる(実行すると、タグ: initial-projectの状態になる)
- プロビジョニング(Ansible)を実行(実行すると、タグapply-provisionの状態になる)
まとめ
ということで、Xcodeプロジェクトを作ってからfastlaneを走らせるまでの作業を自動化してみました。
殆どのプロジェクトでは初回のみなのであまり機会がなさそうなソースですが、
手順が自動化でき、自分にとってのプロジェクトの作成マニュアルができました。
今回は盛り込んでいませんが、xcodeprojを使えばシェルの埋め込みも可能だと思います。
まだまだプロジェクトのテンプレートは育ちそうです。
それでは次は17日のSwiftのAdvent Calendarで〜。
Macでスクリーンショットの保存先の変更と古いスクショの自動削除
デスクトップがスクショの嵐・・・!
こんなデスクトップになった経験はないでしょうか。 スクリーンショットの保存先はデスクトップなので、スクショを撮ってるうちにいつの間にかデスクトップがスクショで埋め尽くされることがあります。
精神衛生上よくない!!!
デスクトップは常にきれいでありたいものです。本当作業中で一時的なファイルを置くだけにしたい。
割れ窓理論があるように、デスクトップが心の余裕の無さや秩序を保とうとしているかを表してるんじゃないかという観念に狩られ るんですよね。もはやこれは健やかな精神なのかしるためのバロメータでもあるといえようッッ!!
ということで、整理される環境を整えたいと思います。
結論
2つの工夫で解決できます
1. ターミナルで保存先の変更
$ mkdir -p ~/Pictures/ScreenShots && defaults write com.apple.screencapture location ~/Pictures/ScreenShots
2. Automator + Calendarで自動的に古いスクリーンショットをゴミ箱に移動する
ターミナルで保存先の変更はDefaultsで解決!
約2年前の記事でも言及してますがdefaults-write.comでいろんな設定値をコマンドラインから設定することが可能です。
defaults
は、設定アプリで設定不可能な項目にアプローチできるので痒かった設定を自分好みに設定することでよりMacを使いやすくすることができます。
任意のディレクトリを作成し、そこに保存する設定を書き込みましょう。
私の場合は、写真フォルダの下にスクリーンショット用のフォルダを作成して、そこを保存先として扱うようにしました。
ターミナルで下記のコマンド2つを実行するのみです
$ mkdir -p ~/Pictures/ScreenShots $ defaults write com.apple.screencapture location ~/Pictures/ScreenShots
~/Pictures/ScreenShots
をFinderのサイドバーに登録しておくと便利です。
自動削除にはAutomator!!
次は自動削除です。デスクトップに保存しなくなった分、スクショが棚卸しされなくなりそうです。
いつの間にか凄まじい数のスクショになっているかもしれません。
スクショは往々にしてインスタントなデータなので作成日から1ヶ月過ぎたら消されてもほぼ問題無いと思います。
ということで、1ヶ月以上前のスクショを自動的に削除する仕組みを作っていきます。
Automatorを使います。スクリプトを書かない選択をしてみました。
こいつです。癖さえわかれば作業・業務を自動化できるので楽しくなります。
エンジニアなら自動化のスクリプトを組むのは日常茶飯事ですがそれがGUIベースでできるイメージです。
アプリケーションベースのアクションが定義されていてその結果を次の操作に繋いでいくイメージでしょうか。
アプリケーションベースのアクションとは
例えば、Finderだったら
- フォルダを取得する
- フォルダの名前を変更する
のような単位です。
立ち上げると
こんなウィンドウが立ち上がるので左のカラムに並んでいるアクションを、右のエリアにドラッグしてワークフローを作っていきます。
今回やりたいことは「30日以上前に作成したスクリーンショットの削除」
Automatorで扱えるフローに分解すると
これをAutomatorのフローに当てはめると
Get Specified Finder Items
Get Folder Contents
Filter Finder Items
Move Finder Items to Trash
ということでできました。
これで実行するとスクショフォルダ内にある作成日が31日以上前のファイルが一括でゴミ箱に移動されます。
Calendarアプリで定期実行に組み込む
実はCalendarアプリでアプリケーションの定期実行をすることができます。
手順としては
- ワークフロー実行用のカレンダーを作成
- 上記で作成したカレンダーにスクリーンショット削除の予定をカレンダーに追加
- 全日 or 0時などで 毎日繰り返し予定に
- カスタムアラートでその時間になったらファイルを開くを選択
こんな感じです
ワークフロー実行用のカレンダーを作成
なぜ、ワークフロー実行用のカレンダーを追加したかというと、毎日定期実行の予定がカレンダーを埋め尽くすことになるからです。 カレンダーは分けておいて、ワークフロー実行用のカレンダーを普段は非表示にしておくことをおすすめします。
まとめ
- defaultsでスクショの保存先を変えてDesktopにスクショがたまらないようにしよう!
- Automatorとカレンダーでスクショの棚卸しはPCにやらせよう!