BLoC Pattern Introduction with Swift

3925ee6eaa41031bac799de0f4f528ec?s=47 to4iki
January 20, 2019

BLoC Pattern Introduction with Swift

# TL;DL
BLoC is (Flutter発祥の)状態管理に関する軽量アーキテクチャパターン

# SeeAlso
- https://qiita.com/kabochapo/items/8738223894fb74f952d3
- https://medium.com/flutter-jp/bloc-provider-70e869b11b2f

3925ee6eaa41031bac799de0f4f528ec?s=128

to4iki

January 20, 2019
Tweet

Transcript

  1. BLoC Pattern Introduction with Swift 2019.01.20 #shinjukult @to4iki 1

  2. Me • @to4iki •  • AbemaTV • ! ☕

    ♨ $ 2
  3. BLoC? 3

  4. Business Logic Component 4

  5. DartConf 2018 Flutter / AngularDart – Code sharing, better together

    5
  6. Google I/O '18 Build reactive mobile apps with Flutter 6

  7. BLoC = (Flutterൃ঵ͷ) ঢ়ଶ؅ཧʹؔ͢Δ ΞʔΩςΫνϟύλʔϯ 7

  8. Motivation • Web (Angular Dart)ͱMobile (Flutter)ͰϏδωεϩδοΫͷ ίʔυΛڞ༗͍ͨ͠ • ݴޠɾϓϥοτϑΥʔϜΛ໰Θͳ͍ঢ়ଶ؅ཧͷύλʔϯ͕ཉ ͍͠

    8
  9. BLoC pattern layer design 9

  10. BLoC pattern layer design https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 10

  11. Guideline 1 1. BLoCͷೖग़ྗΠϯλʔϑΣʔε͸͢΂ͯ Stream/Sink Ͱ͋ Δ 2. BLoCͷґଘ͸ඞͣ஫ೖՄೳͰɺ؀ڥʹґଘ͠ͳ͍ 3.

    BLoC಺ʹ؀ڥ͝ͱͷ৚݅෼ذ͸࣋ͨͳ͍ 4. Ҏ্ͷϧʔϧʹै͏ݶΓɺଞͷ࣮૷ΛͲ͏͢Δ͔͸໰Θͳ͍ 1 https://github.com/tenhobi/flashcards/issues/12#issuecomment-373922966 11
  12. TL;DL • ϏδωεϩδοΫΛίϯϙʔωϯτπϦʔͱผͷ৔ॴʹஔ͘ • BLoCͷ֎෦΁ͷΠϯλʔϑΣʔε͸ Stream(Observable) 12

  13. https://www.youtube.com/watch?v=RS36gBEp8OI 13

  14. e.g. Dart class Bloc { final emailController = StreamController<String>(); //

    Add data to stream get changeEmail => emailController.sink.add; // Retrieve data from stream get email => emailController.stream; } void main() { final bloc = Bloc(); bloc.email.listen((value) { print(value); }); bloc.changeEmail("NEW EMAIL"); } 14
  15. ͜Μ͚ͩ ! ※ ΠϝʔδΛ௫ΉͨΊͷٖࣅίʔυͰ͢ class Bloc<T, U> { let input:

    Observer<T> let output: Observable<U> } 15
  16. e.g. Swift final class TaskBloc { /// input let addTask

    = PublishRelay<Task>() /// output var tasks: Observable<[Task]> { return _tasks.asObservable() } private let _tasks = BehaviorRelay<[Task]>(value: []) private let disposeBag = DisposeBag() init() { addTask .withLatestFrom(tasks) { ($0, $1) } .map { [$0] + $1 } .bind(to: _tasks) .disposed(by: disposeBag) } } 16
  17. e.g. Swift taskBlock.tasks .subscribe(onNext: { tasks in print(tasks) }) .disposed(by:

    disposeBag) addButton.rx.tap .throttle(0.5, latest: false, scheduler: ConcurrentMainScheduler.instance) .map { Task(name: "task_01") } .bind(to: taskBlock.addTask) .disposed(by: disposeBag) 17
  18. Feature • BLoC͔Βͷσʔλͷऔಘ͸ Observable.subscribe • BLoC΁ͷσʔλͷૹ৴͸ Observer.next 18

  19. Feature • Components(View)͸Stream͔Βड͚औΔɾStreamʹσʔλΛ௥Ճ͢Δ͚ͩ • simple • MVVM, Flux, Reduxͱಉ͡ 19

  20. Pros • ࣗ༝ • ܰྔReduxతͳ • ଞͷBLoCΛड͚औΔ͜ͱ΋Մೳ • Streamͷ߹੒ʹΑΓදݱྗ͕ߴ͍ Cons

    • Rxґଘ • Gࣾ 20
  21. and more.. 21

  22. ෳ਺ίϯϙʔωϯτ͔ΒBLoCΛࢀর͍ͨ͠2 • ֤ίϯϙʔωϯτ͔ΒBLoCΛΠϯελϯεԽ͢Δͱঢ়ଶ͕ڞ༗ग़དྷͳ͍ • BLoCΛSingletonΠϯελϯεʹ͢Δ? ! 2 https://qiita.com/kabochapo/items/8738223894fb74f952d3 22

  23. InheritedWidget 23

  24. Flutter.widgets.InheritedWidget3 Base class for widgets that efficiently propagate information down

    the tree. To obtain the nearest instance of a particular type of inherited widget from a build context, use BuildContext.inheritFromWidgetOfExactType. 3 https://docs.flutter.io/flutter/widgets/InheritedWidget-class.html 24
  25. InheritedWidget • Provider extends InheritedWidget • BLoCʹΞΫηε͍ͨ͠Widget͕௚઀ܨ͕ΔͷͰ͸ͳ͘ɺProviderΛܦ༝͢Δ 25

  26. e.g. Flutter class BlocProvider extends InheritedWidget { BlocProvider({Key key, Widget

    child}) : super(key: key, child: child); Bloc get bloc => Bloc(); @override bool updateShouldNotify(_) => true; // BlocProviderʹैଐ͢ΔWidgetͰ͜ͷϝιουΛ࢖͑͹BlocProviderͷΠϯελϯε͕ಘΒΕ // ͦΕΛ࢖ͬͯBlocͷΠϯελϯε΋ಘΒΕΔ static BlocProvider of(BuildContext context) { return (context.inheritFromWidgetOfExactType(BlocProvider) as BlocProvider); } } 26
  27. e.g. Swift TBD • context ͱ͍͏࢓૊Έ͕ͳ͍.. • ୳ࡧͰ͖Μ(ແཧ΍ΓͳΒ͍͚Δ͕) • BlocProvider͸ϚετͰ͸ͳ͍ͱࢥ͏

    • SingletonͰྑ͍͔ͳ ! • σʔλ૚͸ΞϓϦݻ༗Ͱอ࣋͢ΔͳͲ 27
  28. e.g. Swift ※ ΠϝʔδΛ௫ΉͨΊͷٖࣅίʔυͰ͢ final class BlocProvider<T> { let block:

    T static func of(_ view: UIView) -> TaskBloc { // Ҿ਺view͔Βଐ͢Δ `BLoC` Λ୳ࡧ͢Δ fatalError("implement") } } 28
  29. Conclusion • BLoCύλʔϯ͸ܰྔͳঢ়ଶ؅ཧͷख๏ • ߦ͖ண͘ઌ͸MVVM, Flux, ReduxͳͲͷύλʔϯʹۙࣅͯ͠ ͍͘ͱࢥ͏ 29

  30. "ઃܭύλʔϯ͸࠶ݱੑͷ͋Δ໰୊ʹର͢Δڞ௨ͷղܾࡦ"4 "ઃܭʹۜͷ஄ؙ͸ͳ͍͕ɺ ༷ʑͳύλʔϯΛ஌͍ͬͯΔ͜ͱͰۜͷ໋த཰͸্͛ΒΕΔ" 4 iOSΞϓϦઃܭύλʔϯೖ໳: https://peaks.cc/books/iOS_architecture 30

  31. ֓೦Λ஌ͬͯɺख਺Λ૿΍͍ͯ͜͠͏ 31

  32. Thanks 32

  33. SeeAlso • https://qiita.com/kabochapo/items/8738223894fb74f952d3 • https://medium.com/flutter-jp/bloc-provider-70e869b11b2f 33