KEMBAR78
iOS 개발자의 Flutter 체험기 | PDF
! I O S F L U T T E R
C H O I @ WA N B O K . C O MF B . C O M /
L I N E B I Z P L U S
D I S C L A I M E R
F L U T T E R "
.
# .
•
• iOS
• , ,
• iOS Flutter
• https://flutter.dev/docs/get-started/flutter-for/ios-devs
• https://flutter-ko.dev/docs/get-started/flutter-for/ios-devs
• ‘ Flutter ?’
• iOS / / / / /
• iOS Flutter
• iOS Flutter
http://sli.do
#Flutter
📋 A U T O C L I P
, F L U T T E R ?
📋 A U T O C L I P
📋 A U T O C L I P
📋 A U T O C L I P
📋 A U T O C L I P
📋 A U T O C L I P
📋 A U T O C L I P
📋 A U T O C L I P
💫 R O U T I N E
R O U T I N E
•
•
• , , ,
• Bloc Architecture
! I O S
I O S
IDE
Declarative UI Pattern
Data flow & Architecture
Asynchrony Support Pattern matching
Annotations
Documents
🛠 I D E
I D E
I D E
I D E
:https://stackoverflow.com/questions/43635522/what-is-lldb-rpc-server-when-does-it-crash-in-xcode-why-it-crashes
I D E
I D E
I D E
I D E
• Light
• Configurable
• I know it
I D E
• Strong / Heavy
• Required for android
• Familiar for android developer
🗺 D E C L A R AT I V E U I PAT T E R N
D E C L A R AT I V E P R O G R A M M I N G
•
•
• (Impertive)
• (Declarative)
D E C L A R AT I V E P R O G R A M M I N G
•
• (Impertive)
•
• ? (How it is to be computed)
• (Declarative)
D E C L A R AT I V E P R O G R A M M I N G
•
• (Impertive)
• (Declarative)
• SQL, Apache Ant(partially), HTML
• ? (What is to be computed)
D E C L A R AT I V E U I
• UI ?
• UI ?
// Declarative style
return ViewB(
color: red,
child: ViewC(...),
)
// Imperative style
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)
P R O S
• UI
•
• UI
•
C O N S ( C O N C E R N )
• Overhead
• Mindset
• Performance
• Too many Elements and Properties
D ATA F L O W & A R C H I T E C T U R E
📊 D ATA F L O W
S O U R C E O F T R U T H
: https://developer.apple.com/videos/play/wwdc2019/226/
D U P L I C AT E D S O U R C E O F T R U T H
: https://developer.apple.com/videos/play/wwdc2019/226/
S I N G L E S O U R C E O F T R U T H
: https://developer.apple.com/videos/play/wwdc2019/226/
S I N G L E S O U R C E O F T R U T H
Scope Source Of Truth State
UI StatefulWidget Ephemeral State
App ? App State
D ATA F L O W
: https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
S I N G L E S O U R C E O F T R U T H
Scope Source Of Truth State
UI StatefulWidget Ephemeral State
App MyApp? App State
🏛 A R C H I T E C T U R E
F L U X
A R C H I T E C T U R E
B L O C
R E A C T O R K I T
B L O C V S R E A C T O R K I T
Bloc ReactorKit
Presentational Component View
BLoC Reactor
Event Action
States State
Backend Service
📬 A S Y N C H R O N Y S U P P O R T
D A R T
Single Items Multiple Items
Synchronous T getData() List<T> getData()
Asynchronous Future<T> getData() Stream<T> getData()
S W I F T
Single Items Multiple Items
Synchronous T getData() Collection<T> getData()
Asynchronous None
Beta
(Publisher<T> in Combine)
S W I F T W I T H R X
Single Items Multiple Items
Synchronous T getData() Collection<T> getData()
Asynchronous Single<T> getData() Observable<T> getData()
W H Y D O E S R X D A R T E X I S T ?
🤔
🧩 PAT T E R N M AT C H I N G
B L O C E X A M P L E : I N F I N I T Y L I S T
import 'package:equatable/equatable.dart';
abstract class PostEvent extends Equatable {}
class Fetch extends PostEvent {
@override
String toString() => 'Fetch';
}
...
class PostUninitialized extends PostState { ... }
class PostError extends PostState { ... }
class PostLoaded extends PostState {
final List<Post> posts;
final bool hasReachedMax;
PostLoaded({ this.posts, this.hasReachedMax,})
: super([posts, hasReachedMax]);
PostLoaded copyWith({ List<Post> posts, bool hasReachedMax, }) {
return PostLoaded(
posts: posts ?? this.posts,
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
);
}
...
}
class PostBloc extends Bloc<PostEvent, PostState> {
...
@override
Stream<PostState> mapEventToState(PostEvent event) async* {
if (event is Fetch && !_hasReachedMax(currentState)) {
try {
if (currentState is PostUninitialized) {
final posts = await _fetchPosts(0, 20);
yield PostLoaded(posts: posts, hasReachedMax: false);
return;
}
if (currentState is PostLoaded) {
final posts =
await _fetchPosts((currentState as PostLoaded).posts.length, 20);
yield posts.isEmpty
? (currentState as PostLoaded).copyWith(hasReachedMax: true)
: PostLoaded(
posts: (currentState as PostLoaded).posts + posts,
hasReachedMax: false,
);
}
} catch (_) {
yield PostError();
}
}
}
}
R E A C T O R K I T E X A M P L E
import RxSwift
class PostListReactor {
enum Action {
...
case fetch([Post])
}
enum Mutation {
case setIsInitialized(Bool)
case setIsLoaded(Bool)
case setPosts([Post])
case setHasReachedMax(Bool)
case setError(Error?)
}
struct State {
let isInitialized: Bool = false
let isLoaded: Bool = false
let posts: [Post] = []
let hasReachedMax: Bool = false
let error: Error? = nil
}
let initialState: State = .init()
...
func mutate(action: Action) -> Observable<Mutation> {
switch action {
...
case let .fetch(posts):
let posts: Observable<Mutation> = .just(.setPosts(posts))
let hasReachedMax: Observable<Mutation> = .just(.setHasReachedMax(posts.isEmpty))
return .concat(posts, hasReachedMax)
}
}
func reduce(mutation: Mutation, state: State) -> Observable<State> {
var state = state
switch mutation {
case let .setPost(posts) where currentState.isLoaded:
state.posts += posts
case let .setPost(posts) where !currentState.isLoaded:
state.posts = posts
case let .setHasReachedMax(hasReachedMax):
state.hasReachedMax = hasReachedMax
}
return state
}
}
📍 A N N O TAT I O N
A N N O TAT I O N
• Property Wrapper 16 Accepted
• https://github.com/apple/swift-evolution/blob/master/proposals/0258-
property-wrappers.md
📑 D O C U M E N TAT I O N
D O C U M E N TAT I O N
• Flutter
• YouTube
•
• Google I/O
• iOS
•
• WWDC
📚
IDE
IDE
Declarative UI Pattern
IDE
Declarative UI Pattern
Data flow & Architecture
IDE
Declarative UI Pattern
Data flow & Architecture
Asynchrony Support
IDE
Declarative UI Pattern
Data flow & Architecture
Asynchrony Support Pattern matching
IDE
Declarative UI Pattern
Data flow & Architecture
Asynchrony Support Pattern matching
Annotations
IDE
Declarative UI Pattern
Data flow & Architecture
Asynchrony Support Pattern matching
Annotations
Documents
IDE
Declarative UI Pattern
Data flow & Architecture
Asynchrony Support Pattern matching
Annotations
Documents
R E F E R E N C E
• Wikipedia: Declarative Programming
• https://en.wikipedia.org/wiki/Declarative_programming
• Declarative UI and Vaadin Designer
• https://www.youtube.com/watch?v=MwuIDsFizMA
• Practical advantages of declarative programming
• ftp://cliplab.org/pub/papers/PARFORCE/second_review/D.WP3.1.M2.3.ps.Z
• Algorithm = Logic + Control
• https://www.doc.ic.ac.uk/~rak/papers/algorithm%20=%20logic%20+%20control.pdf
• List of programming languages by type
• https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Declarative_languages
R E F E R E N C E
• Flutter Youtube
• https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw
• WWDC 2019 Data Flow through SwiftUI
• https://developer.apple.com/videos/play/wwdc2019/226/
• Flux
• https://facebook.github.io/flux/docs/in-depth-overview
• ReactorKit
• https://github.com/ReactorKit/ReactorKit
iOS 개발자의 Flutter 체험기

iOS 개발자의 Flutter 체험기

  • 1.
    ! I OS F L U T T E R
  • 2.
    C H OI @ WA N B O K . C O MF B . C O M / L I N E B I Z P L U S
  • 3.
    D I SC L A I M E R F L U T T E R " . # .
  • 4.
  • 5.
    • iOS Flutter •https://flutter.dev/docs/get-started/flutter-for/ios-devs • https://flutter-ko.dev/docs/get-started/flutter-for/ios-devs • ‘ Flutter ?’
  • 6.
    • iOS // / / / • iOS Flutter • iOS Flutter
  • 7.
  • 8.
    📋 A UT O C L I P , F L U T T E R ?
  • 9.
    📋 A UT O C L I P
  • 10.
    📋 A UT O C L I P
  • 11.
    📋 A UT O C L I P
  • 12.
    📋 A UT O C L I P
  • 13.
    📋 A UT O C L I P
  • 14.
    📋 A UT O C L I P
  • 15.
    📋 A UT O C L I P
  • 16.
    💫 R OU T I N E
  • 17.
    R O UT I N E • • • , , , • Bloc Architecture
  • 19.
  • 20.
    I O S IDE DeclarativeUI Pattern Data flow & Architecture Asynchrony Support Pattern matching Annotations Documents
  • 21.
  • 22.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
    I D E •Light • Configurable • I know it
  • 30.
    I D E •Strong / Heavy • Required for android • Familiar for android developer
  • 31.
    🗺 D EC L A R AT I V E U I PAT T E R N
  • 32.
    D E CL A R AT I V E P R O G R A M M I N G • • • (Impertive) • (Declarative)
  • 33.
    D E CL A R AT I V E P R O G R A M M I N G • • (Impertive) • • ? (How it is to be computed) • (Declarative)
  • 34.
    D E CL A R AT I V E P R O G R A M M I N G • • (Impertive) • (Declarative) • SQL, Apache Ant(partially), HTML • ? (What is to be computed)
  • 36.
    D E CL A R AT I V E U I • UI ? • UI ? // Declarative style return ViewB( color: red, child: ViewC(...), ) // Imperative style b.setColor(red) b.clearChildren() ViewC c3 = new ViewC(...) b.add(c3)
  • 37.
    P R OS • UI • • UI •
  • 38.
    C O NS ( C O N C E R N ) • Overhead • Mindset • Performance • Too many Elements and Properties
  • 39.
    D ATA FL O W & A R C H I T E C T U R E
  • 40.
    📊 D ATAF L O W
  • 41.
    S O UR C E O F T R U T H : https://developer.apple.com/videos/play/wwdc2019/226/
  • 42.
    D U PL I C AT E D S O U R C E O F T R U T H : https://developer.apple.com/videos/play/wwdc2019/226/
  • 43.
    S I NG L E S O U R C E O F T R U T H : https://developer.apple.com/videos/play/wwdc2019/226/
  • 45.
    S I NG L E S O U R C E O F T R U T H Scope Source Of Truth State UI StatefulWidget Ephemeral State App ? App State
  • 46.
    D ATA FL O W : https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
  • 47.
    S I NG L E S O U R C E O F T R U T H Scope Source Of Truth State UI StatefulWidget Ephemeral State App MyApp? App State
  • 48.
    🏛 A RC H I T E C T U R E
  • 49.
  • 50.
    A R CH I T E C T U R E
  • 51.
  • 52.
    R E AC T O R K I T
  • 53.
    B L OC V S R E A C T O R K I T Bloc ReactorKit Presentational Component View BLoC Reactor Event Action States State Backend Service
  • 54.
    📬 A SY N C H R O N Y S U P P O R T
  • 55.
    D A RT Single Items Multiple Items Synchronous T getData() List<T> getData() Asynchronous Future<T> getData() Stream<T> getData()
  • 56.
    S W IF T Single Items Multiple Items Synchronous T getData() Collection<T> getData() Asynchronous None Beta (Publisher<T> in Combine)
  • 57.
    S W IF T W I T H R X Single Items Multiple Items Synchronous T getData() Collection<T> getData() Asynchronous Single<T> getData() Observable<T> getData()
  • 58.
    W H YD O E S R X D A R T E X I S T ? 🤔
  • 59.
    🧩 PAT TE R N M AT C H I N G
  • 60.
    B L OC E X A M P L E : I N F I N I T Y L I S T import 'package:equatable/equatable.dart'; abstract class PostEvent extends Equatable {} class Fetch extends PostEvent { @override String toString() => 'Fetch'; }
  • 61.
    ... class PostUninitialized extendsPostState { ... } class PostError extends PostState { ... } class PostLoaded extends PostState { final List<Post> posts; final bool hasReachedMax; PostLoaded({ this.posts, this.hasReachedMax,}) : super([posts, hasReachedMax]); PostLoaded copyWith({ List<Post> posts, bool hasReachedMax, }) { return PostLoaded( posts: posts ?? this.posts, hasReachedMax: hasReachedMax ?? this.hasReachedMax, ); } ... }
  • 62.
    class PostBloc extendsBloc<PostEvent, PostState> { ... @override Stream<PostState> mapEventToState(PostEvent event) async* { if (event is Fetch && !_hasReachedMax(currentState)) { try { if (currentState is PostUninitialized) { final posts = await _fetchPosts(0, 20); yield PostLoaded(posts: posts, hasReachedMax: false); return; } if (currentState is PostLoaded) { final posts = await _fetchPosts((currentState as PostLoaded).posts.length, 20); yield posts.isEmpty ? (currentState as PostLoaded).copyWith(hasReachedMax: true) : PostLoaded( posts: (currentState as PostLoaded).posts + posts, hasReachedMax: false, ); } } catch (_) { yield PostError(); } } } }
  • 63.
    R E AC T O R K I T E X A M P L E import RxSwift class PostListReactor { enum Action { ... case fetch([Post]) } enum Mutation { case setIsInitialized(Bool) case setIsLoaded(Bool) case setPosts([Post]) case setHasReachedMax(Bool) case setError(Error?) } struct State { let isInitialized: Bool = false let isLoaded: Bool = false let posts: [Post] = [] let hasReachedMax: Bool = false let error: Error? = nil } let initialState: State = .init() ...
  • 64.
    func mutate(action: Action)-> Observable<Mutation> { switch action { ... case let .fetch(posts): let posts: Observable<Mutation> = .just(.setPosts(posts)) let hasReachedMax: Observable<Mutation> = .just(.setHasReachedMax(posts.isEmpty)) return .concat(posts, hasReachedMax) } } func reduce(mutation: Mutation, state: State) -> Observable<State> { var state = state switch mutation { case let .setPost(posts) where currentState.isLoaded: state.posts += posts case let .setPost(posts) where !currentState.isLoaded: state.posts = posts case let .setHasReachedMax(hasReachedMax): state.hasReachedMax = hasReachedMax } return state } }
  • 65.
    📍 A NN O TAT I O N
  • 66.
    A N NO TAT I O N • Property Wrapper 16 Accepted • https://github.com/apple/swift-evolution/blob/master/proposals/0258- property-wrappers.md
  • 67.
    📑 D OC U M E N TAT I O N
  • 68.
    D O CU M E N TAT I O N • Flutter • YouTube • • Google I/O • iOS • • WWDC
  • 69.
  • 70.
  • 71.
  • 72.
    IDE Declarative UI Pattern Dataflow & Architecture
  • 73.
    IDE Declarative UI Pattern Dataflow & Architecture Asynchrony Support
  • 74.
    IDE Declarative UI Pattern Dataflow & Architecture Asynchrony Support Pattern matching
  • 75.
    IDE Declarative UI Pattern Dataflow & Architecture Asynchrony Support Pattern matching Annotations
  • 76.
    IDE Declarative UI Pattern Dataflow & Architecture Asynchrony Support Pattern matching Annotations Documents
  • 77.
    IDE Declarative UI Pattern Dataflow & Architecture Asynchrony Support Pattern matching Annotations Documents
  • 78.
    R E FE R E N C E • Wikipedia: Declarative Programming • https://en.wikipedia.org/wiki/Declarative_programming • Declarative UI and Vaadin Designer • https://www.youtube.com/watch?v=MwuIDsFizMA • Practical advantages of declarative programming • ftp://cliplab.org/pub/papers/PARFORCE/second_review/D.WP3.1.M2.3.ps.Z • Algorithm = Logic + Control • https://www.doc.ic.ac.uk/~rak/papers/algorithm%20=%20logic%20+%20control.pdf • List of programming languages by type • https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Declarative_languages
  • 79.
    R E FE R E N C E • Flutter Youtube • https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw • WWDC 2019 Data Flow through SwiftUI • https://developer.apple.com/videos/play/wwdc2019/226/ • Flux • https://facebook.github.io/flux/docs/in-depth-overview • ReactorKit • https://github.com/ReactorKit/ReactorKit