Upgrade to Pro — share decks privately, control downloads, hide ads and more …

アッテ開発の技術:Swift と RxSwift

アッテ開発の技術:Swift と RxSwift

atte FeS【Go・Swift開発編】での発表資料に加筆・修正をしたものです。
http://mercari.connpass.com/event/29506/

Shinichiro Oba

April 19, 2016
Tweet

More Decks by Shinichiro Oba

Other Decks in Programming

Transcript

  1. iOS版開発の歴史 4 できごと メンバー 2015年10⽉ ソウゾウに出向 モック作成開始 ライブラリ&設計検討開始 1 11⽉

    RxSwift採⽤決定 本実装開始 合宿 1 12⽉ 幻の初サブミット 1 2016年1⽉ 孤独な⼀⼈開発から脱出 2 2⽉ 紹介制で公開 3 3⽉ 正式オープン 4 4⽉ Go Boldに開発中 4.5
  2. JSONRPCKit 10 struct Like: RequestType { typealias Response = LikeResult

    let offerId: Int64 var method: String { return "LikeService.Like" } var params: AnyObject? { return ["offer_id": NSNumber(longLong: offerId)] } } { id: “1”, jsonrpc: “2.0", method: “LikeService.Like", params: { “offer_id”: 123456; } }
  3. ストリームの加⼯ 27 ストリーム上のデータに対して filter したり map したり merge したり zip

    し たり reduce したりできる オペレータと呼ばれる combineLatest や buffer など、時間 概念があるからこそのオペレータもある
  4. 例:条件を満たすまでボタンを押せないようにする 38 let textValidation = textField.rx_text .map { !$0.isEmpty }

    Observable.combineLatest( textValidation, loading.asObservable()) { text, loading in return text && !loading } .bindTo(submitButton.rx_enabled) .addDisposableTo(disposeBag)
  5. 例:インクリメンタルサーチ 39 textField.rx_text .debounce(0.5, scheduler: MainScheduler.instance) .distinctUntilChanged() .map { query

    -> Observable<[Item]> in if query.isEmpty { return Observable.just([]) } let request = GetItemsRequest(query: query) return API.responseFrom(request) } .switchLatest() .subscribeNext { [weak self] items in print("next: \(items.count)") self?.items = items self?.tableView.reloadData() } .addDisposableTo(disposeBag)
  6. アッテの実例:新規投稿・編集投稿のコード 43 class Photo { var image: UIImage var mediaId:

    String? } var request = createUpdateRequest() photos .map { photo -> Observable<String> in if let mediaId = photo.mediaId { return Observable.just(mediaId) } return ImageUploader.uploadImage(photo.image) } .combineLatest { $0 } .map { mediaIds -> Observable<UpdateOfferResult> in request.mediaIds = mediaIds return APIClient.sharedClient.responseFrom(request) } .switchLatest() .subscribe( // ౤ߘAPIͷ݁ՌΛॲཧ ) .addDisposableTo(disposeBag)