読者です 読者をやめる 読者になる 読者になる

5.1さらうどん

@giginetの技術ブログ。ゲーム開発、iOS開発、その他いろいろ

UITextFieldに簡単にカスタムキーボード貼るライブラリ作った+iOS UIライブラリのCI改善の話

最近、Swiftでライブラリを作るのが趣味なgiginetです。

最近は仕事でもSwiftを使う機会が多く、金曜の夜に仕事でアプリを作っていたら、突如良い感じの実装になってきたので、週末のやっていきでライブラリが誕生した。

github.com

CustomKeyboardTextField

CustomKeyboardTextField は、カスタムキーボードが貼り付いたテキストフィールドを簡単に生成できるライブラリ。

デモアプリはAppetize.ioに上げてあり、↓で動作確認ができる。

こんな感じで作った動作デモをシュッとブログに埋め込んで使ってもらえるの最高の時代だし、実機実行はもはや時代遅れだから今すぐiPhoneを投げ捨てるべき。

アピールポイントとして、Genericsなどを使ってゴリゴリしているので、簡単に型安全なTextFieldのクラスを生成できる。 よく使うであろうPickerを貼るだけのTextFieldであれば、以下のように一瞬で実装できる。

import CustomKeyboardTextField

struct PokemonPickerKeyboardDataSource: UIPickerViewKeyboardDataSource {
    let elements = ["Bulbasaur", "Charmander", "Squirtle"]
}
typealias PokemonPickerTextField = PickerKeyboardTextField<PokemonPickerKeyboardDataSource>

typealiasで簡単に新たなTextField型を生み出せるのがミソで、上記のように最初の3匹を選ばせたいときなんかは役に立つと思う。

サンプルアプリにあるように、画像を埋め込んだちょっとリッチなピッカーにしたり、一番下の雑ゲームパッドのように完全に独自のUIViewを埋め込むこともできる。

実用的な例で言うと、例えばiOS上でユーザー登録フォームを作っていて、誕生日や性別の選択などのフォームを実装したいという時なんかに使えそう。詳しくはREADMEをどうぞ。

気に入ったら是非 ⭐️ スターをお願いします 🙏

UIライブラリを作ってみて新たな知見

最近はSwiftライブラリ作成マンとして活動しつつあるため、ライブラリの作り方などは何度かブログ記事に書いた。

giginet.hateblo.jp

giginet.hateblo.jp

しかし、UI作るのが面倒であまり好きではなくて今まで作ってこなかったので、今回はUIライブラリ用の知見を何個か紹介したい。

Travis CI+Fastlaneで自動的にAppetize.ioにデプロイする

冒頭に埋め込んだ動作デモはAppetize.ioという、ブラウザ上でiOS/Androidアプリを実行できる素晴らしいサービスを使っている。

今回は、Travis CIでサンプルアプリをビルドして、Fastlaneを使って、自動的にAppetize.ioにアップロードするようにしてみた。

実は以前、この仕組みはこのブログでも紹介していて、今回も以前送ったPRが元になっている。

fastlaneを使ってiOSアプリをブラウザから爆速確認できるようにした - 5.1さらうどん

今回改めて調べてみたら、この記事を書いた時代からいろいろと進化していて

  • Appetize.ioのAPIが進化していて、直接アプリをアップロードできるようになった
    • 以前はどこかにアップロードしておいてURLを参照する形だった
  • Fastlaneにzipアクションやbuild_and_upload_to_appetizeというそのまんまなアクションが追加された

これらを使うと、わずかこれだけでシュッと実装できてしまう。

platform :ios do
  desc "Deploy demo application to Appetize.io"
  lane :deploy_to_appetize do
    build_and_upload_to_appetize(scheme: 'DemoApp', xcodebuild: {project: 'DemoApp.xcodeproj'})
  end
end

これを使ってFastlaneを実行するだけで↑みたいなのが簡単にデプロイできる。

$ fastlane deploy_to_appetize

他に必要なこととしてTravis CIには、セキュアな値を暗号化して環境変数にできる仕組みが実装されていて、それを使ってAPIキー各種をセットしておく必要がある。

$ travis encrypt APPETIZE_API_TOKEN=yourapitoken --add
$ travis encrypt APPETIZE_PUBLICKEY=yourpublickey --add

今回はデフォルトで用意されたアクションを使わずにgitのコミットログを一緒に送るようにしていたりとか若干改良している。 興味のある方はFastfileをどうぞ。

Xcode7.xと8系で同時にテストする

この時期はWWDC後で、現行のバージョンとβ版両方を考えないといけないiOS開発者にとって憂鬱な時期。

とはいえ、以前と比べて大体のことはいろいろな手段で解決できるようになっていて、Travis CIのmatrixの仕組みを使えば複数のコンテナを立ち上げてXcode7と8で同時にテストを実行できる。

f:id:gigi-net:20160808010714p:plain

これを利用してSwift 2.2と2.3両方に対応している。

たまに標準ライブラリの型が変わっていたりして、トリッキーなコードを書く必要があったりするけど、2.2と2.3はほとんど文法的に互換性を保っているので、Xcode8.0で設定を済ませるだけで大体の場合は簡単に2.3対応が行える。

今後3が出てきてからどのように複数環境でテストしていくかという知見はまだない。 ただ、2.x系は今後早々と切り捨てられそうなので、近いうちに3以外は考えなくても良い世界が到来しそう。

UIライブラリのユニットテスト

UI系のライブラリはテストを書きづらく、テストがない場合も多いんだけど、申し訳程度にユニットテストを書いた。

本来はXCUITestなどを使って、しっかりUIテストを書くのが望ましいんだろうけど、面倒でそこまでちゃんと書いていない。 気が向いたらUI Testも増やしてみたい。

感想

ライブラリをいろいろ作ってみて、Protocol Orientedな設計が大分わかってきた気になってきたけど、実は良くわかってなくてまだまだ勉強が足りていないのを痛感する。

他に作ったライブラリも含め、興味があったらぜひご利用ください。

github.com

github.com

github.com

Thanks to WPZOOM about nice icon sets.