タグ

ブックマーク / blog.ishkawa.org (29)

  • Storyboardとの付き合い方 2018

    Aug 12, 2018 少し前に、自分のStoryboardの使い方をツイートしたら割と反応があったので、改めてまとめてみようと思います。これまで何年かiOSアプリの開発をしてきて、Storyboardとの付き合い方は何度も変わりました。なので、今回紹介するものはあくまで2018年現在のもので、来年には変わっているかもしれません。 説明のイメージを掴みやすくするため、画面の例を用意しました。左が編集時のStoryboardで、右が実行時のiOSシミュレーターです。具体的なトピックが出た時に、この例を説明に使うことがあります。 記事の最後にこれが動作するサンプルコードも用意しましたので、興味があればどうぞ。 Storyboardを使う目的 以下の2つを重視して、Storyboardを選択しています。 動作確認に掛かる時間を短縮する 成果物の構造を把握しやすくする ただし、Storyboar

    Storyboardとの付き合い方 2018
  • associated valueを持つenumを==で比較できない問題

    Sep 25, 2016 associated valueを持つenumをシュッと比較できなくて困る時があります。一瞬だけSwiftの仕様が悪いような気がしますが、associated valueがEquatableでない可能性もあるので仕方がないことです。 enum SomeEnum { case a case b(Int) } SomeEnum.a == SomeEnum.a // コンパイルエラー SomeEnum.a == SomeEnum.b(1) // コンパイルエラー SomeEnum.b(1) == SomeEnum.b(1) // コンパイルエラー SomeEnum.b(1) == SomeEnum.b(2) // コンパイルエラー enum SomeEnum: Equatable { case a case b(Int) static func ==(lhs: Some

    associated valueを持つenumを==で比較できない問題
  • iOSDCでRxSwiftを紹介してきた + ReactiveCocoaの補足

    Aug 23, 2016 オタクなのでRxSwiftの話になるとつい早口にアレコレ喋りまくってしまうのですが、今回はそういった気持ちをそっと胸にしまって、RxSwiftを導入するとアプリ開発にどういう変化が起こるのか、なるべく多くの方に伝わるように心がけて話しました。 スライド: http://blog.ishkawa.org/talks/2016-08-20-iosdc/ ビデオ: https://abemafresh.tv/tech-conference/32381 (1:00:00~) 3行で書くと以下の通りです。 RxSwiftはイベントストリームをObservableで抽象化するライブラリ 大抵のイベント処理はObservableからObserverへの接続で実装できる イベントストリームの依存関係はオペレーターから読み取れる その他、以下の3つについても話そうと思っていましたが

    iOSDCでRxSwiftを紹介してきた + ReactiveCocoaの補足
  • APIKit: レスポンスに応じた独自のエラーを投げる

    { "message": "Validation Failed", "errors": [ { "resource": "Issue", "field": "title", "code": "missing_field" } ] } 今回は、このようなエラーをリクエストの呼び出し側に伝える方法を説明します。なお、この説明はDefining Request Protocol for Web Serviceのエラーの扱いをもう少し詳しく説明したものとなります。 サービス用のリクエストプロトコル APIKitでは、特定のサービス(Web API)向けのリクエストの特徴をまとめるために、サービス用のリクエストプロトコルを定義します。今回はGitHub APIを例としているので、baseURLのデフォルト値がhttps://api.github.comとなっているGitHubRequestを定義しま

    APIKit: レスポンスに応じた独自のエラーを投げる
  • TestSchedulerとSessionAdapterTypeを使った仮想時間上のテスト

    May 7, 2016 TestScheduler RxSwiftにはVirtualTimeSchedulerというSchedulerがあって、仮想的な時間でイベントストリームを扱えます。仮想的な時間というとなんだか難しそうですが、要は時間を自分で操作できるSchedulerということです。 RxSwiftのテストライブラリのRxTestsには、TestSchedulerというSchedulerも用意されています。これはVirtualTimeSchedulerにテスト向けの機能をつけたもので、イベントを記録できたりします。記録したイベントはXCTAssertEqual(_:_:)で検証できるので、どの時刻にどの値が来くるかテストできるというわけです。 func test() { let scheduler = TestScheduler(initialClock: 0) let obser

    TestSchedulerとSessionAdapterTypeを使った仮想時間上のテスト
  • Swift 2でのAPIKit + Himotoki

    Jul 29, 2015 Swift 2の利点を最大限に活かすため、APIKitのデザインは大幅に刷新されました。型制約つきprotocol extensionsとHimotokiと組み合わせるとresponseFromObject(_:URLResponse:)にデフォルト実装を与えられるので、個々のリクエストの定義を楽にできます。以下はその例です。 // https://developer.github.com/v3/search/#search-repositories struct SearchRepositoriesRequest: GitHubRequestType { enum Sort: String { case Stars = "stars" case Forks = "forks" case Updated = "updated" } let query: Strin

    Swift 2でのAPIKit + Himotoki
  • Value binding patternを活用して可変な構造を持つレスポンスを型安全に扱う方法

    Nov 5, 2015 GitHubのEvents APIでは、イベントの種類に応じて一部のJSONの構造が変わります。構造が可変となっているのはpayloadと呼ばれる箇所で、種類に固有の情報はpayload以下に格納されます。例えば、CommitCommentEventのpayloadはcomment, senderといった情報を持ち、CreateEventやDeleteEventはref, ref_typeといった情報を持ちます。 https://developer.github.com/v3/activity/events/types/ SwiftでEvents APIのレスポンスを表そうと考えた場合、以下の2つが思い浮びました。 Eventという1つの型を定義してpayloadは[String: AnyObject]にする。 EventTypeというプロトコルを定義して種類ごとに

    Value binding patternを活用して可変な構造を持つレスポンスを型安全に扱う方法
  • APIKitでSwiftらしいAPIクライアントを実装する

    Feb 22, 2015 堅牢で使いやすいAPIクライアントをSwiftで実装したいをライブラリにまとめてAPIKitとしてリリースしました。 なお、”Swiftらしい”というのは主観です。 https://github.com/ishkawa/APIKit 利用側のコード リクエストに渡すパラメーターは型によって明らかになっている。 レスポンスはモデルオブジェクトとして受け取れる。 成功時にレスポンスを非オプショナルな値で受け取れる。 失敗時にエラーを非オプショナルな値で受け取れる。 // リクエストに渡すパラメーターを型で制限 let request = GitHub.Endpoint.SearchRepositories(query: "APIKit", sort: .Stars) GitHub.sendRequest(request) { response in // option

    APIKitでSwiftらしいAPIクライアントを実装する
  • Swiftのmanual mocking

    Mar 20, 2015 Objective-Cではテストケース毎にオブジェクトの一部だけ挙動を変えたい場合に、OCMockなどのライブラリを使うのが普通でした。 それらのライブラリはNSInvocationやMethod Swizzlingなどを使ったいわゆる魔術的なコードで実現されていることが多く、 “テストコードを書いているのによくわからんコードが動いてる!”ってなってモヤモヤしたりします。 一方、Swiftではmanual mockingという手法が取られたりするみたいです。 例えば、 class Object { var foo: String { return "foo" } var bar: String { return "bar" } } class ObjectTests: XCTestCase { func testFoo() { class ObjectMock:

    Swiftのmanual mocking
  • 堅牢で使いやすいAPIクライアントをSwiftで実装したい

    Feb 17, 2015 昨年末にはてなの@cockscombさんと@yashiganiさんがつくっていたSwiftでenumとジェネリクスを活用したかっこいいAPIクライアントを書くが 面白かったので、これを参考にしつつSwiftらしい堅牢で使いやすいAPIクライアントを考えてみました。 目標としたのは以下の3つの条件を満たすことです。 レスポンスはモデルオブジェクトとして受け取る (便利) 個々のリクエスト/レスポンスの定義は1箇所で済ます (変更しやすくしたい) リクエストオブジェクトはAPIクライアントから分離させたい 例にはGitHub System Status APIを使用しています。 サンプルコードはGitHubに上がっています。 APIクライアントのインターフェース APIの呼び出し用に用意されたメソッドはcallのみで、callに渡すリクエストによってレスポンスの型が変

    堅牢で使いやすいAPIクライアントをSwiftで実装したい
  • Circle CIでiOSアプリのリリース作業を自動化

    Jan 7, 2015 ※ 現在(2015/01/07)Circle CIのiOSビルドはベータとなっているため、利用するにはサポートへの連絡が必要です。 できること GitHubへのコミット毎に以下のタスクを実行します。 ユニットテストの実行 ipaの作成 ipaのバリデーション CrittercismにdSYMをアップロード Circle CIにテストレポートを出力 iTunes Connectにipaをアップロード これらの作業を自動化すると、masterブランチにgit pushするだけでテストが通ったアプリがiTunes Connectに登録され、 TestFlight(新)からダウンロードできるようになり、そのままApp Storeに申請することまで出来るようになります。 Circle CIのメリット 無料(1 container) 見た目がきれい private reposi

    Circle CIでiOSアプリのリリース作業を自動化
    clavier
    clavier 2015/01/08
    Circle CIでiOSアプリのリリース作業を自動化
  • Goのコードカバレッジをサブパッケージまでまとめて出力

    というのが出来ると思ったら、現段階ではまだできないようです。 go.tools/cmd/cover: should support -coverprofile for multiple packages *.goが含まれるディレクトリで実行して回って、出力をくっつけるスクリプトを書いて凌ぐことにしました。 profile="coverage.out" if [ -f $profile ] then rm $profile fi for dir in $(find . -type d ! -path "*/.git*" ! -path "*/_*") do if ls $dir/*.go > /dev/null 2>&1 then subprofile=$dir/coverage.tmp go test -coverprofile=$subprofile $dir if [ -f $subp

    Goのコードカバレッジをサブパッケージまでまとめて出力
  • Carthage: Swift対応の新しいライブラリ管理

    Nov 20, 2014 iOS, OSXで利用できるライブラリ管理ツールといえばCocoaPodsが有名ですが、 それとはまた違った方針のCarthageというライブラリ管理ツールがリリースされました。 GitHubのデベロッパーを中心としたチームで開発が進められているようです。 https://github.com/Carthage/Carthage インストール方法 Releasesからpkgをダウンロードして、インストーラーを実行します。 使い方 Cartfileを書く carthage updateを実行する Carthage.buildに作成された.frameworkをXcodeに追加する Cartfileではgithub, gitの2種類のキーワードが利用でき、以下のように書きます。 サポート対象 Carthageはdynamic frameworkのみをサポートするため、C

    Carthage: Swift対応の新しいライブラリ管理
  • agvtool+Jenkinsでビルド番号付きipaを作成

    Oct 19, 2014 iTunes Connectがアップデートされてから、1つのアプリのバージョンに対して複数のipaをアップロードできるようになりました。 しかし、ビルド番号が重複しているとエラーが発生してしまうので、ビルド番号をインクリメントしていく必要があります。 手動でビルド番号をインクリメントしてリポジトリにコミットしていくと、分散管理では矛盾が生じてしまうので、 ビルド番号にはJenkinsのビルド番号を指定し、リポジトリにはコミットしないことにしてみました。 セットアップ Jenkinsでxcodebuildを実行する前に以下のコマンドを実行するだけです。 自分はJenkinsにアドホック配布用のipaとAppStore用のipaの両方を作成させていて、 AdHoc配布用のipaをTestFlightにアップロードし、AppStore用のipaはビルド成果物として保存し

    agvtool+Jenkinsでビルド番号付きipaを作成
  • 家庭で余ったMacをJenkinsのスレーブにする

    Oct 18, 2014 iOS開発のCI環境を提供するサービスには以下の2つがあります。 Travis CI Greenhouse CI また、自分でCIサーバーを立てる場合には以下の2つの選択肢があります。 Xcode Bots Jenkins 自分はお金を掛けずになんでも自動化できるJenkinsを選ぶことにしました。 Jenkinsにアクセスするために自宅のMacに繋ぎに行くのは嫌だったので、VPSでJenkinsを動かし、Macをそのスレーブにすることにしました。 Macで動くスレーブエージェントは自分からマスターに繋ぎに行ってくれるので、ユーザーとしてはVPSに繋げれば十分ということになります。 ノードの登録 “Jenkinsの管理” > “ノードの管理” > “新規ノード作成”からノードの作成を選択します。 リモートFSルートを設定し、起動方法を”JNLP経由でスレーブを起動

    家庭で余ったMacをJenkinsのスレーブにする
  • Swiftの略記法

    Aug 1, 2014 お気に入りのSwiftの略記法を紹介します。 (※ beta 4で動作確認) enumの型名の省略 enumの値をfuncの引数として渡す場合や、type annotationがついた変数/定数に代入する場合など、 あらかじめenumの型が決まっている場合には、型名を省略できます。 例えば、NSJSONReadingOptions.AllowFragmentsは以下のように.AllowFragmentsと書くことができます。 NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &error)

    Swiftの略記法
  • auto_closureを利用して条件成立を待つXCTestExpectationをつくる

    Jul 23, 2014 AppleSwift Blogを読んで@auto_closureが面白そうだと思い活用方法を考えてみました。 @auto_closureはclosureを取る引数につけると、呼び出し側はclosureの{}を省略できるようになるというものです。 Swift Blogによると、AppleSwiftでのassert()などの実装にこれを利用しているそうです。 今回はこれを利用して、条件が成立するまで待つXCTestExpectationを実装してみました。 以下のように使うことができます。 func testBlockOperation() { let queue = NSOperationQueue() let operation = NSBlockOperation(block: { NSThread.sleepForTimeInterval(1.0) })

    auto_closureを利用して条件成立を待つXCTestExpectationをつくる
  • すべてのテストケースの前後にあれこれする

    Apr 30, 2014 iOSのアプリケーションテストを書いていると、各テストケースの前後に永続ストアやスタブサーバーなどをリセットしたくなることがあると思います。 リセットが必要なテストスイートのsetUp/tearDownに書いても良いのですが、書くのが面倒だったり書き忘れてしまうこともあるので、 すべてのテストケースについてリセットが走るようにしておいた方が心を穏やかにすることができると思います。 実現方法 すぐに思いついたのは以下のような方法です。 setUp/tearDownにリセット処理を加えたサブクラスを継承させる XCTestCaseのsetUp/tearDownをswizzleする サブクラスを継承させる方法には、KIFTestCaseなど他のライブラリのクラスには適用ができないという問題があります。 method swizzlingを利用する方法は、他のmethod

    すべてのテストケースの前後にあれこれする
  • iOS開発とGitタグ

    いままでAppleにアプリを申請するタイミングでタグを打っていて、 その後にリジェクトされると以下のようなタグが残ることがありました。 非常にダサいですね。 1.0.0 1.0.0-2 1.0.0-3 最近は少し学習して、QAに入る段階でrelease/1.0.0といったブランチを切るようにしました。 審査に出した段階ではまだタグは打たず、もしもリジェクトされた場合は引き続きrelease/1.0.0を更新します。 審査を通過した場合はそこでタグを打って、release/1.0.0をmasterにマージします。 以下の図のようなイメージです。 このように運用することで、余計なタグが打たれることはありませんし、審査中のバージョンを見失うこともありません。 もしかしたら普通のiOSデベロッパーは当たり前のように実践していることなのかもしれませんが、 自分は最近までダサいタグを打ったり、タグを打

    iOS開発とGitタグ
  • #confwd でOSSでのObjective-Cの書き方について話してきた

    Conference With Developers 2 | Peatix 自分はiOSデベロッパーとして大した経験や実績があるわけではないのですが、 公開しているライブラリの数はかなり多い方のなので、そこで得られた知識を話そうと思いました。 トーク中は聴いている人のリアクションを気にする余裕もなかったのですが、 あとからTwitterのタイムラインを読んでみると、良い反応をしてくれている方もいたようで嬉しかったです。 今回の発表ではどのトピックも詳細に立ち入ることが難しかったので、いつか文章でしっかりとまとめられるといいなと思いました。 トークの準備 大勢の前で45分も話し続けるのは初めてだったので、どうやって準備したらいいものか悩みました。 スライドをつくりながらトークの内容を練るのは難しそうだったので、はじめはmarkdownで適当な文章を書いて、 そこからの大事な単語や文を拾ってき