タグ

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

  • Storyboardとの付き合い方 2018

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

    Storyboardとの付き合い方 2018
  • iOSDCで「コード生成による静的なDependency Injection」について話した & 口頭原稿を公開

    Sep 18, 2017 このところかなり忙しく、iOSDCでちゃんとしたことを話せるのか不安でしたが、なんとか無事に終わりました。あまり会場を盛り上げることができず、後半はしどろもどろで死にたくなりましたが、面白かったと言ってくれた方もそれなりにいたので少し安心しました。 DIは今回の話以外にも色々なことに挑戦していて、最初はデフォルト引数を使った手動のinitializer injectionから始めて、SwinjectやCleanseなどのライブラリを試してみたり、Cake Patternを模倣してみたりしていました。それらを通じて、自分が求めるDIのプラクティスは 依存の宣言とインスタンスの取得のためのコードが単純かつ十分に少ない コンパイル時に依存関係の解決が検証される というものだとわかりました。もしも「dependencyの宣言さえしておけば、あとはコンパイルエラーを直してい

    iOSDCで「コード生成による静的なDependency Injection」について話した & 口頭原稿を公開
    raimon49
    raimon49 2017/09/20
    プロトコルベースのDI生成 SourceKitの活用例としても面白い
  • 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を==で比較できない問題
    raimon49
    raimon49 2016/09/26
    パターンマッチで==演算子の実装
  • 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の補足
  • Xcode 7のXCTAssertEqualとOptional

    Oct 17, 2015 Xcode 6までのXCTAssertEqualは<T: Equatable>(expression1: T, expression2: T)という引数になっていました。一見するとジェネリックで良い感じに見えるんですが、実際には片方がOptionalの場合に型が一致しなくて面倒という問題がありました。 http://blog.ishkawa.org/2015/03/02/1425257147/ Xcode 7ではそれが改善されており、XCTAssertEqualの引数は<T: Equatable>(expression1: T?, expression2: T?)というものになりました。これにより、unwrapせずにTとT?が比較できるようになりました。

    Xcode 7のXCTAssertEqualとOptional
    raimon49
    raimon49 2015/11/02
    直接Optionalな値との比較が可能に めでたい
  • 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
  • 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
    raimon49
    raimon49 2015/03/20
    テストケース内で再定義、override
  • Optionalを考慮したXCTestのassertion

    Mar 2, 2015 XCTAssertを利用しているとforced unwarpしたい場面が出てくる。例えば、

    Optionalを考慮したXCTestのassertion
    raimon49
    raimon49 2015/03/03
    XCTAssert()の中で==演算子
  • 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で書いたコマンドラインツールをHomebrewでインストールできるようにする

    Feb 18, 2015 toolという名前のコマンドラインツールをつくるとします。 Makefile ビルドターゲットのINSTALL_PATHは/usr/local/binとします。 DSTROOT=/tmp/tool.dst prefix_install: xcodebuild install -scheme tool DSTROOT=$(DSTROOT) mkdir -p $(PREFIX)/bin cp -f $(DSTROOT)/usr/local/bin/tool $(PREFIX)/bin/ class Tool < Formula homepage "https://github.com/yourname/tool" version "0.0.1" sha1 "0123456789abcdef0123456789abcdef01234567" url "https://g

    Swiftで書いたコマンドラインツールをHomebrewでインストールできるようにする
    raimon49
    raimon49 2015/02/22
    xcodebuild install
  • 堅牢で使いやすい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アプリのリリース作業を自動化
    raimon49
    raimon49 2015/01/10
    CrittercismへのdSYMアップロードもRakeで。
  • 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対応の新しいライブラリ管理
    raimon49
    raimon49 2014/11/21
    static libraryではなくdynamic frameworkを管理する。CocoaPodsみたいなworkspaceを作るものではない。
  • Swiftの略記法

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

    Swiftの略記法
    raimon49
    raimon49 2014/08/03
    おお、enumとクロージャの型名省略、これは良い!
  • 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タグ
    raimon49
    raimon49 2014/04/21
    申請タイミングじゃなくて審査通ったタイミングでタグを打つ。それまではリリースブランチ。確かにこういう運用はアリ。リジェクトされたら打ち直しで良い気もするけど。
  • デバッグ中にJSONをサッと出力する

    NSDictionaryやNSArrayのdescriptionはそれとなく見やすいフォーマットで出力されますが、JSONで欲しくなる場合があります。 しかも、デバッグ中に欲しくなったりします。 XcodeのLLDBは~/.lldbinit-Xcodeに独自のコマンドを定義することができるので、 pretty printedなJSONを吐くコマンドを定義してカジュアルにJSONを得られるようにしてみました。 1 command regex pj 's/^(.+)$/po [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:%1 options:1 error:nil] encoding:4]/' ここで定義したpjコマンドを使うと以下のようなNSDictionaryから 1 2 3 NSDiction

  • .ipaをサッとつくる - blog.ishkawa.org

    iOSアプリの.ipaを配布して他の人にテストしてもらうとき、 Xocdeを起動 メニューのProduct -> Archiveを選択。 OrganizerからArchiveを選んでのDistribute。 Save for Enterprise or Ad-Hoc Deploymentを選択。 Code Sign Identityを選択 保存先を指定 保存したipaをサーバーにアップロードする。 という面倒な手順を踏んでいる人も多いと思います。 実はこれらはコマンドでも実行できるのでmakeでサッとできます。 Makefile .xcodeprojなどと同じ階層にMakefileを作成します。 ***ってなってるところは適宜読み替えてください。 .xcodeprojを使っている場合 1 2 3 4 5 6 7 default: xcodebuild -sdk iphoneos -ta

    raimon49
    raimon49 2014/02/27
    やっぱ自動化だよね。
  • JSONにNSNullが入ってきたとき

    多くのiOSアプリはサーバーとの通信が必要で、やりとりされるデータのフォーマットにはJSONが採用されることが多いと思います。 iOS 5からは標準ライブラリにNSJSONSerializationが導入され、特に理由がなければJSONのエンコード/デコードにはこれを利用します。 NSJSONSerializationが扱うオブジェクトは以下の5種類のオブジェクトです。 NSString NSNumber NSArray NSDictionary NSNull そこで心配になるのが、予期しないところにNSNullが入ってきて”unrecognized selector sent to instance.“となってしまうことです。 NSNullではなくてnilが入っていてほしいと考える人は多いようですが、そもそもNSArrayやNSDictonaryはnilを含むことはできず、 そのような状

    raimon49
    raimon49 2013/11/18
    (object == [NSNull null]) 「NSNullはそもそもsingletonなのでisEqual:やisKindOfClass:で比較する必要はない」
  • モバイル版のGitHubにフィードがなかったので、補うiOSアプリをつくってリリースした

    プッシュ通知などもついていて、なかなか便利なものになりました。 アプリをダウンロード GitHubのモバイル版(Web)はかなり良くできていて流石だなあと思っていたのですが、 肝心のフィードがなかったりして、モバイル版の役割を十分にカバーできていないと思いました。 それを補うのがGHFeedです。具体的には以下の2つの機能を提供しています。 フィードの表示 ハイライトされるイベントをプッシュ通知 前者はpull型の利用で、時間があるときにフィードを見て面白そうなリポジトリがあればスターをつけたりしておく、というような利用を想定しています。 後者はpush型で、自分が関わるリポジトリにイベントがあった時に早く気づけるようにするという利用を想定しています。 自分はこの2つの利用パターンが可能になって、はじめてモバイル版のGitHubが成り立つんじゃないかなあと思い、開発にいたりました。 振り返

  • CocoaPodsを使ってみた - blog.ishkawa.org

    以上で導入は完了です。 元々のプロジェクト(Hoge.xcodeproj)とは別にワークスペースが(Hoge.xcworkspace)作成されるので、以降の作業ではこちらを使うようにします。 Project Navigatorは以下のようになっているはずです。 どうやらライブラリ群をlibPods.aというスタティックライブラリにまとめて、リンクしているようです。 CocoaPodsの良いところ git submoduleを直接使っている場合と比較したメリットを書きます。 プロジェクトへの導入の自動化 git submoduleはライブラリのソースコードを管理するのであって、 どのようにXcodeプロジェクトに導入されるかまでは管理していません。 つまり、ライブラリを導入するには手動で以下の手順を行う必要があります。 導入に必要なファイルのみをXcodeプロジェクトに追加 必要に応じてフレ

    raimon49
    raimon49 2013/01/27
    git submoduleとの比較。プロジェクトのメタ情報を見てくれるから便利、ということのよう。