サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
iPhone 16
blog.ishkawa.org
Jun 3, 2019 タベリーという、料理と買い物の負担を肩代わりするモバイルアプリをつくっています。最近、オンライン注文機能をリリースして、いよいよ買い物の領域にも本腰を入れ始めました。また、会社の資金調達も同時に発表しており、このタイミングで仲間になってくれるソフトウェアエンジニアも募集しています。 https://10x.co.jp/news/2019-05-14.html 会社が取り組んでいる課題や市場、文化については下記のスライドにまとまっています。 どんな人を求めているか 一言で言えば、チームの可能性を広げられる人を求めています。いまは7名の小規模チームでなんとか市場にエントリーできる場所に漕ぎ着けました。しかし、あるべき体験に到達するためには、解決しなければならない問題がたくさんあります。チームに新しいメンバーを迎えることで、これまでのチームでは出来なかったことを出来るよう
Feb 8, 2018 最近は、モバイルアプリとサーバーの通信にgRPCを使っています。gRPCは、サーバー同士の通信では徐々に使われ始めている印象がありますが、モバイルアプリでの使用例はまだ少ないと思うので、動機とか、感想とか、ウチはこうしてるというものを共有します。 リクエストとレスポンスの定義を1箇所にまとめる 今のプロジェクトでは、同じデータをサーバー, iOS, Android, Webで扱う予定がありました。普通のREST APIでは同じデータを4つの言語に翻訳する必要がありましたが、これをprotoへの翻訳の1回だけで済ませたいというのが、gRPCを使う最初の動機でした。 gRPCでは、リクエストとレスポンスの全ての情報をprotoファイル上で表現し、それを元に各言語のコードを自動生成します。APIドキュメントを人間が各言語に翻訳する場合と比べると、コードを書く手間が省けます
Dec 10, 2018 少し前に、GoogleからWireというDIツールがリリースされた。このツールは元々Go Cloudの内部で使われていたもので、汎用的なツールとして切り出したのだそうだ。このツールの特徴は依存グラフの解決がコード生成によって行われるという点で、リフレクションを使った動的なDIと比べるとエラーがコンパイル時に検出できるというアドバンテージがある。 ところで、The Go BlogのCompile-time Dependency Injection With Go Cloud’s Wireによると、コード生成によるDIというアイディアはJavaのDaggerにインスパイアされたものらしい。自分も以前、DaggerにインスパイアされてDIKitというSwiftのライブラリを開発したことがある。DIKitは今もiOSアプリの開発で使っていて生産性に貢献している実感があり、
Dec 6, 2018 Carthageによるフレームワークのビルドは時間が掛かるので、CIでは良い感じにキャッシュを当ててもらいたい。この記事の中ではそれをやってくれる平凡な設定を貼るのだけど、なぜそれが効率的なのか理解するにはCarthageとCIのキャッシュの仕組みを理解する必要があるので、まとめておく。我が社(エンジニア募集中)のCIはすべてCircleCIなのでCircleCIの話になるのだけど、たぶん他のCIサービスでも似た仕組みはありそう。 ちなみにこれは、半年ほど前に @chuganzy さんにTwitterで教えてもらったのがきっかけで調べ始めたもの。ずっとやろうと思ってたのだけど全然やってなくて、遂にやった。うっかりしている間に半年も経っていて、自分の先延ばし能力に驚かされた…。 Carthageのキャッシュ Carthage 0.20(2017年2月リリース)からCa
Aug 13, 2018 少し前に、自分のStoryboardの使い方をツイートしたら割と反応があったので、改めてまとめてみようと思います。これまで何年かiOSアプリの開発をしてきて、Storyboardとの付き合い方は何度も変わりました。なので、今回紹介するものはあくまで2018年現在のもので、来年には変わっているかもしれません。 説明のイメージを掴みやすくするため、画面の例を用意しました。左が編集時のStoryboardで、右が実行時のiOSシミュレーターです。具体的なトピックが出た時に、この例を説明に使うことがあります。 記事の最後にこれが動作するサンプルコードも用意しましたので、興味があればどうぞ。 Storyboardを使う目的 以下の2つを重視して、Storyboardを選択しています。 動作確認に掛かる時間を短縮する 成果物の構造を把握しやすくする ただし、Storyboar
Nov 9, 2018 最近お外で作業する機会が増えて、MacBookを開く度にメニューバーからテザリングを開始するのが億劫だと感じるようになった。本当は単体でモバイル通信ができるMacBookがあれば良いのだけど、今のところそういうモデルはないので、自分が手動でやっていることを自動化することにした。この手順は「スリープ解除のイベントを捕まえる」と「Bluetoothのメニューバーを操作する」の2つに分解できる。少し調べてみると、前者はSleepWatcherで、後者はAppleScriptで実現できることがわかった。 SleepWatcherは今日まで全然知らなかったけど、歴史が長いらしい。ドキュメントではMac OS X 10.1についても言及されているので、2000年くらいから開発されていてるみたい。そして、macOS Majave(10.14)の今でもきちんと動く。こういうプロダク
Aug 12, 2018 少し前に、自分のStoryboardの使い方をツイートしたら割と反応があったので、改めてまとめてみようと思います。これまで何年かiOSアプリの開発をしてきて、Storyboardとの付き合い方は何度も変わりました。なので、今回紹介するものはあくまで2018年現在のもので、来年には変わっているかもしれません。 説明のイメージを掴みやすくするため、画面の例を用意しました。左が編集時のStoryboardで、右が実行時のiOSシミュレーターです。具体的なトピックが出た時に、この例を説明に使うことがあります。 記事の最後にこれが動作するサンプルコードも用意しましたので、興味があればどうぞ。 Storyboardを使う目的 以下の2つを重視して、Storyboardを選択しています。 動作確認に掛かる時間を短縮する 成果物の構造を把握しやすくする ただし、Storyboar
Feb 7, 2018 最近は、モバイルアプリとサーバーの通信にgRPCを使っています。gRPCは、サーバー同士の通信では徐々に使われ始めている印象がありますが、モバイルアプリでの使用例はまだ少ないと思うので、動機とか、感想とか、ウチはこうしてるというものを共有します。 リクエストとレスポンスの定義を1箇所にまとめる 今のプロジェクトでは、同じデータをサーバー, iOS, Android, Webで扱う予定がありました。普通のREST APIでは同じデータを4つの言語に翻訳する必要がありましたが、これをprotoへの翻訳の1回だけで済ませたいというのが、gRPCを使う最初の動機でした。 gRPCでは、リクエストとレスポンスの全ての情報をprotoファイル上で表現し、それを元に各言語のコードを自動生成します。APIドキュメントを人間が各言語に翻訳する場合と比べると、コードを書く手間が省けます
Feb 8, 2018 移行前はBitriseの$50のプランでiOSのCIをしていました。最近はサーバーやAndroidの開発もやっているのですが、そちらのCIには元々CircleCIを使っていて、workflowの使いやすさやページの軽快さが気に入っていました。 CircleCIのmacOSマシンは$39から始められるのですが、一定時間以上使うとそこから従量課金制になります。CircleCI上でのビルドにどのくらい時間が掛かるか完全には読めなかったので、実際に移行してみて費用が安くなるのか高くなるのか不確定だったというわけです。そういう状況だと、わざわざ確認のために新しい環境でCIをセットアップするのも億劫に感じてしまい、なかなか手をつけられずにいました。 ところがある日、サーバーのリソースを見直した結果、月に$250ほど節約できることがわかりました。なぜかその時に背中を押されて、iO
Jan 1, 2018 去年の7月に、メルカリで同僚だった矢本さん(@yamotty3)と株式会社10Xを始めました。矢本さんが代表で、自分は開発全般を見ています。会社やプロダクトのストーリーは矢本さんのポエムに任せることにして、自分はエンジニアとして会社を立ち上げた雑感を書きます。 仕事を選ぶ理由は人それぞれですが、同じ人でも時期によって何を重視するかは違ってくると思います。新卒時に重視していたことは「開発ができるようになれること」でしたが、今の自分は少し変わって以下の3つを重視しているようです。 人が抱えている問題を解決すること 技術の幅を広げること チームとして機能すること いざ書いてみると月並みという感じですが、、。会社を始めるということをあまり想定していなかったタイプなのですが、それでも踏み切れた理由は、この3つがきちんと満たせそうだと思えたからではないかと思います。 以下、それ
Sep 18, 2017 このところかなり忙しく、iOSDCでちゃんとしたことを話せるのか不安でしたが、なんとか無事に終わりました。あまり会場を盛り上げることができず、後半はしどろもどろで死にたくなりましたが、面白かったと言ってくれた方もそれなりにいたので少し安心しました。 DIは今回の話以外にも色々なことに挑戦していて、最初はデフォルト引数を使った手動のinitializer injectionから始めて、SwinjectやCleanseなどのライブラリを試してみたり、Cake Patternを模倣してみたりしていました。それらを通じて、自分が求めるDIのプラクティスは 依存の宣言とインスタンスの取得のためのコードが単純かつ十分に少ない コンパイル時に依存関係の解決が検証される というものだとわかりました。もしも「dependencyの宣言さえしておけば、あとはコンパイルエラーを直してい
Mar 11, 2017 ユニットテストを書くときに、fixtureを読み込むなどの何らかの準備をすることがあります。そして、こういった処理もテスト対象の処理と同様に失敗する可能性があります。失敗を素直に表すならば、メソッドにthrowsをつけてエラーを投げられるようにします。 enum JSONFixture: String { struct FileNotFoundError: Error {} case foo case bar case baz func loadJSON() throws -> Any { let bundle = Bundle(for: TestBundleClass.self) guard let path = bundle.path(forResource: rawValue, ofType: "json") else { throw FileNotFoun
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
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つについても話そうと思っていましたが
{ "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を定義しま
May 7, 2016 TestScheduler RxSwiftにはVirtualTimeSchedulerというSchedulerがあって、仮想的な時間でイベントストリームを扱えます。仮想的な時間というとなんだか難しそうですが、要は時間を自分で操作できるSchedulerということです。 RxSwiftのテストライブラリのRxTestsには、TestSchedulerというSchedulerも用意されています。これはVirtualTimeSchedulerにテスト向けの機能をつけたもので、イベントを記録できたりします。記録したイベントはXCTAssertEqual(_:_:)で検証できるので、どの時刻にどの値が来くるかテストできるというわけです。 func test() { let scheduler = TestScheduler(initialClock: 0) let obser
Apr 19, 2016 Twitter for iOSには選択中のタブをもう1度タップしたら最上部までスクロールするという機能があります。便利ですね。 こういう機能を実装するには、1つ前に選択されていた値が何なのか知る必要があります。 桶の時代にはプロパティに前回の値を保存するのが定石でしたが、川の時代にはskip(1)してzip()するというのが定石です(たぶん)。 let tappedIndex: Observable<Int> = ... Observable .zip(tappedIndex, tappedIndex.skip(1)) { previousIndex, currentIndex in return previousIndex == currentIndex } .filter { $0 } .subscribeNext { _ in // 最上部までスクロール }
Mar 12, 2016 良いセッションはたくさんあったのですが、書き切れませんね。 平常心で型を消し去る (Gwendolyn Weston) Associated Typeを持つプロトコルは型制約でしか使えないため、型パラメーターが利用側に波及しがちになるという問題があります。セッションでは型パラメーター地獄について話していなかったと思いますが、紹介されていたAnyPokemonのようなパターンは(表面上の)型を消すことでこの問題を解決できそうだなあと思いました。また、このパターンはRxSwiftでもAnyObserverで使われています。 完全に余談ですが、Gwendolyn Westonさんはスピーカーディナー後のカラオケパーティでモーニング娘のLOVEマシーンを歌っていて、めっちゃ上手かったです。 Swiftのエラー処理についての三つの話 (Yuta Koshizawa) Swi
public struct Event: Decodable { public let id: String public let createdAt: NSDate public let payload: Payload public static func decode(e: Extractor) throws -> Event { guard let typeObject = e.rawValue["type"] else { throw DecodeError.MissingKeyPath("type") } guard let typeString = typeObject as? String else { throw DecodeError.TypeMismatch(expected: "String", actual: "\(typeObject)", keyPath: "
Nov 14, 2015 1年前に書いたprepareForSegue(_:)がoptional bindingとtype castingの地獄になっていたので、パターンマッチングで描き直してみました。確かにネストは浅くなりましたが、これはこれで地獄なのかもしれません。 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { switch (segue.identifier, segue.destinationViewController, sender) { case ("Web"?, let viewController as WebViewController, let cell as UITableViewCell) where cell == feedbackCell: viewC
Mar 31, 2013 最近、Node.jsを始めました。 サーバーサイドの経験はほとんどないので色々と新鮮に感じています。 クライアントサイドと違ってテストがないとプログラムが動いているかよくわからないのですが、 テストってどうやって書くのか全然わかんねーって感じだったのであれこれ模索しました。 その結果、supertestを使ってリクエストとレスポンスの対応をテストすることから始めるのが 良さそうかなと思いましたので紹介します。 対象はExpressアプリとします。 supertestとMochaをインストール mochaはなくても使えるのですが、あった方が楽なのでインストールします。 mochaについては以下のページが詳しいです。 http://d.hatena.ne.jp/hokaccha/20111202/1322840375
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というプロトコルを定義して種類ごとに
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?が比較できるようになりました。
Aug 31, 2015 The Swift Programming Language: Patterns Swiftのパターンは値の性質を表してマッチングを行うもので、switch文などに使われているものです。これまでは、switch文の柔軟さを知っていても背景にあるパターンという存在を知らなかったため、強力だけど気味が悪いなあと思っていました。パターンの文法がわかると気味の悪さがいくらか解消されて、気持よくパターンマッチングができるようになると思います。あとでハッシュタグを振り返ってみると同様に思っていた人が数人いたようで、発表して良かったなあと思いました。 スライドの最後の方に紹介されているUITableViewControllerの実例のような、実際にアプリ開発で使えるテクニックをもっと見つけていきたい。
Aug 23, 2015 Vimに特に不満があったわけではないものの、新しいものも受け入れないとな〜と思ってセットアップしてみた。 Vim自体を辞めるつもりはないので、Atomはvim-modeで使っています。 メインの業務はXcodeかIntelliJ IDEAでやっていて、それぞれプラグインでVimのキーバインディングを割り当てています。 それ以外の以下のようなものには大体Vimを使っていました。 色んな設定ファイル Markdown Go Rust 自分が最低限使えるようにするまでにやったものを紹介します。 カーソルの履歴 AtomにはVimのノーマルモードのC-i, C-oにあたるものがなさそうだったのでt9md/atom-cursor-historyというプラグインで解決しました。 Vimっぽい動きが良かったので以下の設定を選びました。 'atom-text-editor.vim
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
May 7, 2015 Swiftに慣れてくると!を避けたくなりますが、!を書きたくなるようなケースもあります。 func loadSignInViewController() -> SignInViewController { let storyboard = UIStoryboard(name: "SignIn", bundle: nil) let viewController = storyboard.instantiateInitialViewController() as! SignInViewController return viewController } func loadSignInViewController() -> SignInViewController { let storyboard = UIStoryboard(name: "SignIn", bundle
次のページ
このページを最初にブックマークしてみませんか?
『https://blog.ishkawa.org/』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く