SlideShare ist ein Scribd-Unternehmen logo
1 von 143
Downloaden Sie, um offline zu lesen
Functional Reactive
Programming
with
ReactiveCocoa
@EliSawic
About me
Eliasz Sawicki
Blog: www.eliaszsawicki.com
Twitter: @EliSawic
@EliSawic
Agenda
• What is functional reactive programming?
• Working with streams
• ReactiveCocoa - Thinking in signals
• Example
@EliSawic
Functional Reactive Programming
@EliSawic
Wikipedia
Functional reactive programming (FRP) is a programming
paradigm for reactive programming (asynchronous dataflow
programming) using the building blocks of functional
programming (e.g. map, reduce, filter).
@EliSawic
Reactive
Programming
@EliSawic
C = A + B
@EliSawic
C = A + B
A B C
1 2 3
@EliSawic
C = A + B
A B C
1 2 3
1 5 6
@EliSawic
Functional
Programming
@EliSawic
Blocks
@EliSawic
Functional
Reactive
Programming?
@EliSawic
Reactive
Programming?
@EliSawic
Imperative
vs
Declarative
@EliSawic
Imperative
@EliSawic
Imperative
let array = [0, 1, 2, 3, 4, 5]
var evenNumbers = [Int]()
for element in array {
if element % 2 == 0 {
evenNumbers.append(element)
}
}
@EliSawic
Declarative
@EliSawic
Declarative
let array = [0, 1, 2, 3, 4, 5]
let evenNumbers = array.filter { $0 % 2 == 0 }
@EliSawic
Working with streams
@EliSawic
Stream
@EliSawic
Manipulating streams
@EliSawic
Map
@EliSawic
Filter
@EliSawic
Aggregating
@EliSawic
Manipulating
multiple streams
@EliSawic
Combine latest
@EliSawic
Composable
@EliSawic
Composable
stream.filter {}
@EliSawic
Composable
stream.filter {}
.map {}
@EliSawic
Composable
stream.filter {}
.map {}
.reduce {}
@EliSawic
Composable
stream.filter {}
.map {}
.reduce {}
.map {}
@EliSawic
www.rxmarbles.com
@EliSawic
ReactiveSwift
@EliSawic
ReactiveCocoa
@EliSawic
Thinking in Signals
@EliSawic
What is a signal?
@EliSawic
This screen is a signal
@EliSawic
Represents events
over time
@EliSawic
Observing does not
trigger side effects
@EliSawic
No random access to
events
@EliSawic
Observe
@EliSawic
@EliSawic
If you don't listen, it's
gone
@EliSawic
What is event?
@EliSawic
Non-Terminating
• Next
@EliSawic
Terminating
• Completed
• Failed
• Interrupted (Reactive Cocoa)
@EliSawic
Location Service
protocol LocationServiceDelegate {
func locationService(locationService: LocationService, didUpdateLocation update: LocationUpdate)
}
class LocationService {
var delegate: LocationServiceDelegate?
private func onUpdate() {
let update = LocationUpdate()
delegate?.locationService(locationService: self, didUpdateLocation: update)
}
}
@EliSawic
Location Service
class LocationService {
private func onUpdate() {
let update = LocationUpdate()
NotificationCenter.default.post(name: "LocationUpdate", object: update)
}
}
@EliSawic
Location Service
class LocationService {
let locationUpdates: Signal<LocationUpdate, NoError>
private let locationUpdatesSink: Signal<LocationUpdate, NoError>.Observer
init() {
(locationUpdates, locationUpdatesSink) = Signal<LocationUpdate, NoError>.pipe()
}
private func onUpdate() {
let update = LocationUpdate()
locationUpdatesSink.send(value: update)
}
}
@EliSawic
Location Service
class LocationService {
let locationUpdates: Signal<LocationUpdate, NoError>
private let locationUpdatesSink: Signal<LocationUpdate, NoError>.Observer
init() {
(locationUpdates, locationUpdatesSink) = Signal<LocationUpdate, NoError>.pipe()
}
private func onUpdate() {
let update = LocationUpdate()
locationUpdatesSink.send(value: update)
}
}
@EliSawic
Location Service
class LocationService {
let locationUpdates: Signal<LocationUpdate, NoError>
private let locationUpdatesSink: Signal<LocationUpdate, NoError>.Observer
init() {
(locationUpdates, locationUpdatesSink) = Signal<LocationUpdate, NoError>.pipe()
}
private func onUpdate() {
let update = LocationUpdate()
locationUpdatesSink.send(value: update)
}
}
@EliSawic
Location Service
class LocationService {
let locationUpdates: Signal<LocationUpdate, NoError>
private let locationUpdatesSink: Signal<LocationUpdate, NoError>.Observer
init() {
(locationUpdates, locationUpdatesSink) = Signal<LocationUpdate, NoError>.pipe()
}
private func onUpdate() {
let update = LocationUpdate()
locationUpdatesSink.send(value: update)
}
}
@EliSawic
Observing
locationUpdates.observeValues { update in
// react to update
}
@EliSawic
Manipulating
let homeUpdates = locationUpdates.filter { update in
isHomeArea(update)
}
homeUpdates.observeValues { update in
presentAlert("Welcome home")
}
@EliSawic
Manipulating
let homeUpdates = locationUpdates.filter { update in
isHomeArea(update)
}
homeUpdates.observeValues { update in
presentAlert("Welcome home")
}
@EliSawic
Signal producer
@EliSawic
Represents a tasks
@EliSawic
Possible side effects
@EliSawic
Does not start it's
work if not asked
@EliSawic
HTTP request
func fetchUser() -> SignalProducer<User, FetchError> {
return SignalProducer { observer, _ in
// fetching user
let user = User()
observer.send(value: user)
observer.sendCompleted()
}
}
@EliSawic
HTTP request
func fetchUser() -> SignalProducer<User, FetchError> {
return SignalProducer { observer, _ in
// fetching user
let user = User()
observer.send(value: user)
observer.sendCompleted()
}
}
@EliSawic
HTTP request
func fetchUser() -> SignalProducer<User, FetchError> {
return SignalProducer { observer, _ in
// fetching user
let user = User()
observer.send(value: user)
observer.sendCompleted()
}
}
@EliSawic
HTTP request
func fetchUser() -> SignalProducer<User, FetchError> {
return SignalProducer { observer, _ in
// fetching user
let user = User()
observer.send(value: user)
observer.sendCompleted()
}
}
@EliSawic
Work with presentation
fetchUser().startWithResult { (result) in
switch result {
case .success(let user):
//save user
case .failure(let error):
//show alert
}
}
@EliSawic
Work with presentation
fetchUser().startWithResult { (result) in
switch result {
case .success(let user):
//save user
case .failure(let error):
//show alert
}
}
@EliSawic
Work with presentation
fetchUser().startWithResult { (result) in
switch result {
case .success(let user):
//save user
case .failure(let error):
//show alert
}
}
@EliSawic
Cold vs Hot
@EliSawic
Signal SignalProducer
presentation.observeValues presentation.startWithValues
@EliSawic
Signal SignalProducer
presentation.observeValues presentation.startWithValues
emits values all the time waits for your request
@EliSawic
// push based
locationUpdates.observeValues { update in
}
// pull based
fetchUser.startWithValues { user in
}
@EliSawic
// push based
locationUpdates.subscribe { update in
}
// pull based
fetchUser.subscribe { user in
}
@EliSawic
Properties
@EliSawic
Mutable Property
let firstSlide = Slide(number: 1)
let slide = MutableProperty<Slide>(firstSlide)
slide.producer.startWithValues { (text) in
print(text)
}
slide.value = Slide(number: 2)
@EliSawic
Mutable Property
let firstSlide = Slide(number: 1)
let slide = MutableProperty<Slide>(firstSlide)
slide.producer.startWithValues { (text) in
print(text)
}
slide.value = Slide(number: 2)
@EliSawic
Mutable Property
let firstSlide = Slide(number: 1)
let slide = MutableProperty<Slide>(firstSlide)
slide.producer.startWithValues { (text) in
print(text)
}
slide.value = Slide(number: 2)
@EliSawic
Mutable Property
let firstSlide = Slide(number: 1)
let slide = MutableProperty<Slide>(firstSlide)
slide.producer.startWithValues { (text) in
print(text)
}
slide.value = Slide(number: 2)
@EliSawic
Mutable Property
let firstSlide = Slide(number: 1)
let slideContainer = MutableProperty<Slide>(firstSlide)
slideContainer.producer.startWithValues { (text) in
print(text)
}
slideContainer.value = Slide(number: 2)
@EliSawic
Exposing
properties
let firstSlide = Slide(number: 1)
let mutableSlideContainer = MutableProperty<Slide>(firstSlide)
let readOnlySlide = Property(mutableSlideContainer)
exposedSlide.producer.startWithValues { (text) in
print(text)
}
@EliSawic
Exposing
properties
let firstSlide = Slide(number: 1)
let mutableSlideContainer = MutableProperty<Slide>(firstSlide)
let readOnlySlide = Property(mutableSlideContainer)
exposedSlide.producer.startWithValues { (text) in
print(text)
}
@EliSawic
Exposing
properties
let firstSlide = Slide(number: 1)
let mutableSlideContainer = MutableProperty<Slide>(firstSlide)
let readOnlySlide = Property(mutableSlideContainer)
exposedSlide.producer.startWithValues { (text) in
print(text)
}
@EliSawic
Bindings
@EliSawic
Binding example
let slideNumber = MutableProperty<Int>(0)
let (slideSignal, _) = Signal<Slide, NoError>.pipe()
slideNumber <~ slideSignal.map { return $0.number }
@EliSawic
Binding example
let slideNumber = MutableProperty<Int>(0)
let (slideSignal, _) = Signal<Slide, NoError>.pipe()
slideNumber <~ slideSignal.map { return $0.number }
slideNumber signal
0 -
@EliSawic
Binding example
let slideNumber = MutableProperty<Int>(0)
let (slideSignal, _) = Signal<Slide, NoError>.pipe()
slideNumber <~ slideSignal.map { return $0.number }
slideNumber signal
0 -
2 Slide(number: 2)
@EliSawic
Reactive extensions
let (slideSignal, _) = Signal<Slide, NoError>.pipe()
label.reactive.text
@EliSawic
Reactive extensions
let (slideSignal, _) = Signal<Slide, NoError>.pipe()
label.reactive.text <~ slideSignal.map { return "Slide: ($0.number)" }
@EliSawic
Schedulers
@EliSawic
Know where you are
signal.observeValues { data in
print("Performing UI updates")
}
@EliSawic
Know where you are
signal.observe(on: QueueScheduler.main)
.observeValues { data in
print("Performing UI updates")
}
@EliSawic
Memory Management
@EliSawic
Disposables
@EliSawic
Free your memory
let disposable = locationService.observeValues { update in
// update location
}
disposable.dispose()
@EliSawic
Lifetime
let (lifetime, token) = Lifetime.make()
locationService
.take(during: lifetime)
.observeValues { update in
// update location
}
@EliSawic
Lifetime
let (lifetime, token) = Lifetime.make()
locationService
.take(during: lifetime)
.observeValues { update in
// update location
}
@EliSawic
Lifetime
let (lifetime, token) = Lifetime.make()
locationService
.take(during: lifetime)
.observeValues { update in
// update location
}
@EliSawic
Recap
@EliSawic
Recap
• Signals / SignalProducers
@EliSawic
Recap
• Signals / SignalProducers
• Events
@EliSawic
Recap
• Signals / SignalProducers
• Events
• Properties
@EliSawic
Recap
• Signals / SignalProducers
• Events
• Properties
• Bindings / Reactive extensions
@EliSawic
Recap
• Signals / SignalProducers
• Events
• Properties
• Bindings / Reactive extensions
• Schedulers
@EliSawic
Recap
• Signals / SignalProducers
• Events
• Properties
• Bindings / Reactive extensions
• Schedulers
• Disposables / Lifetime
@EliSawic
Example
@EliSawic
@EliSawic
How does it work?
@EliSawic
Is name valid?
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
@EliSawic
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
nameSignal isValidNameSignal
E false
@EliSawic
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
nameSignal isValidNameSignal
E false
El false
@EliSawic
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
nameSignal isValidNameSignal
E false
El false
Eli true
@EliSawic
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
nameSignal isValidNameSignal
E false
El false
Eli true
Elia true
Elias true
@EliSawic
let isValidNameSignal = nameSignal.map { (name) -> Bool in
return name.characters.count > 2
}
nameSignal isValidNameSignal
E false
El false
Eli true
Elia true
Elias true
Eliasz true
@EliSawic
Is surname valid?
let isValidSurnameSignal = surnameSignal.map { (surname) -> Bool in
return surname.characters.count > 2
}
@EliSawic
Is mail valid?
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
@EliSawic
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
mailSignal isValidMailSignal
a false
@EliSawic
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
mailSignal isValidMailSignal
a false
a@ false
@EliSawic
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
mailSignal isValidMailSignal
a false
a@ false
a@b false
@EliSawic
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
mailSignal isValidMailSignal
a false
a@ false
a@b false
a@b. false
@EliSawic
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
mailSignal isValidMailSignal
a false
a@ false
a@b false
a@b. false
a@b.c false
@EliSawic
let isValidMailSignal = mailSignal.map { (mail) -> Bool in
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluateWithObject(mail)
}
mailSignal isValidMailSignal
a false
a@ false
a@b false
a@b. false
a@b.c false
a@b.cd true
@EliSawic
Combine Latest
let formDataSignal = Signal.combineLatest(
isValidNameSignal,
isValidSurnameSignal,
isValidMailSignal)
@EliSawic
Combine Latest
let formData = Signal.combineLatest(
name,
surname,
mail)
@EliSawic
let formData = Signal.combineLatest(
name,
surname,
mail)
formData name surname mail
@EliSawic
let formData = Signal.combineLatest(
name,
surname,
mail)
formData name surname mail
- true - -
@EliSawic
let formData = Signal.combineLatest(
name,
surname,
mail)
formData name surname mail
- true - -
- true false -
@EliSawic
let formData = Signal.combineLatest(
name,
surname,
mail)
formData name surname mail
- true - -
- true false -
(true,false,true) true false true
@EliSawic
let formData = Signal.combineLatest(
name,
surname,
mail)
formData name surname mail
- true - -
- true false -
(true,false,true) true false true
(true,true,true) true true true
@EliSawic
Is form valid?
let isValidFormSignal = formDataSignal.map {
(isValidName, isValidSurname, isValidMail) -> Bool in
return isValidMail && isValidSurname && isValidMail
}
@EliSawic
let isValidFormSignal = formDataSignal.map {
(isValidName, isValidSurname, isValidMail) -> Bool in
return isValidMail && isValidSurname && isValidMail
}
isValidForm formData
false (true,false,true)
@EliSawic
let isValidFormSignal = formDataSignal.map {
(isValidName, isValidSurname, isValidMail) -> Bool in
return isValidMail && isValidSurname && isValidMail
}
isValidForm formData
false (true,false,true)
true (true,true,true)
@EliSawic
Update the state
isValidFormSignal.observeValues { isValid in
updateButtonWith(state: isValid)
}
@EliSawic
Binding
let isValidForm = MutableProperty<Bool>(false)
isValidForm <~ isFormValidSignal
@EliSawic
Reactive everywhere!
@EliSawic
Drawbacks
@EliSawic
Know the drawbacks
• Another layer for your app
@EliSawic
Know the drawbacks
• Another layer for your app
• Learning curve
@EliSawic
Know the drawbacks
• Another layer for your app
• Learning curve
• Tricky debugging
@EliSawic
Enjoy the pros
@EliSawic
Enjoy the pros
• Composable streams
@EliSawic
Enjoy the pros
• Composable streams
• Easier asynchronous code
@EliSawic
Enjoy the pros
• Composable streams
• Easier asynchronous code
• Works great with MVVM
@EliSawic
Stay Reactive
@EliSawic
Stay Reactive
sendCompleted()
@EliSawic
@Elisawic
www.eliaszsawicki.com
@EliSawic

Weitere ähnliche Inhalte

Was ist angesagt?

Swift Ready for Production?
Swift Ready for Production?Swift Ready for Production?
Swift Ready for Production?Crispy Mountain
 
Akka streams - Umeå java usergroup
Akka streams - Umeå java usergroupAkka streams - Umeå java usergroup
Akka streams - Umeå java usergroupJohan Andrén
 
Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Konrad Malawski
 
Flying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightFlying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightWiem Zine Elabidine
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014hezamu
 
Architecture for scalable Angular applications
Architecture for scalable Angular applicationsArchitecture for scalable Angular applications
Architecture for scalable Angular applicationsPaweł Żurowski
 

Was ist angesagt? (12)

Firebase ng2 zurich
Firebase ng2 zurichFirebase ng2 zurich
Firebase ng2 zurich
 
React lecture
React lectureReact lecture
React lecture
 
Akka and futures
Akka and futuresAkka and futures
Akka and futures
 
Swift Ready for Production?
Swift Ready for Production?Swift Ready for Production?
Swift Ready for Production?
 
Akka streams - Umeå java usergroup
Akka streams - Umeå java usergroupAkka streams - Umeå java usergroup
Akka streams - Umeå java usergroup
 
Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Flying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightFlying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnight
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014
 
Architecture for scalable Angular applications
Architecture for scalable Angular applicationsArchitecture for scalable Angular applications
Architecture for scalable Angular applications
 
Next Level Testing Revisited
Next Level Testing RevisitedNext Level Testing Revisited
Next Level Testing Revisited
 
Alteryx SDK
Alteryx SDKAlteryx SDK
Alteryx SDK
 

Ähnlich wie Tech fest

Introduction to Functional Reactive Programming
Introduction to Functional Reactive ProgrammingIntroduction to Functional Reactive Programming
Introduction to Functional Reactive ProgrammingEliasz Sawicki
 
Intro to ReactiveCocoa
Intro to ReactiveCocoaIntro to ReactiveCocoa
Intro to ReactiveCocoakleneau
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivitynklmish
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkDaniel Spector
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesPeter Pilgrim
 
Reactive Applications in Enterprise Java
Reactive Applications in Enterprise JavaReactive Applications in Enterprise Java
Reactive Applications in Enterprise JavaOPEN KNOWLEDGE GmbH
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)jeffz
 
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo EditionDon't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo EditionAnthony Ferrara
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Jo Cranford
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sRoel Hartman
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Davide Cerbo
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React NativeMuhammed Demirci
 
Julio Capote, Twitter
Julio Capote, TwitterJulio Capote, Twitter
Julio Capote, TwitterOntico
 

Ähnlich wie Tech fest (20)

Code europe
Code europeCode europe
Code europe
 
Introduction to Functional Reactive Programming
Introduction to Functional Reactive ProgrammingIntroduction to Functional Reactive Programming
Introduction to Functional Reactive Programming
 
iOSCon
iOSConiOSCon
iOSCon
 
Intro to ReactiveCocoa
Intro to ReactiveCocoaIntro to ReactiveCocoa
Intro to ReactiveCocoa
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
React js
React jsReact js
React js
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
 
Reactive Applications in Enterprise Java
Reactive Applications in Enterprise JavaReactive Applications in Enterprise Java
Reactive Applications in Enterprise Java
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
 
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo EditionDon't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React Native
 
Java Enterprise goes Reactive
Java Enterprise goes ReactiveJava Enterprise goes Reactive
Java Enterprise goes Reactive
 
Julio Capote, Twitter
Julio Capote, TwitterJulio Capote, Twitter
Julio Capote, Twitter
 
JavaFX introduction
JavaFX introductionJavaFX introduction
JavaFX introduction
 

Mehr von Eliasz Sawicki

Eliasz sawickimeetupit
Eliasz sawickimeetupitEliasz sawickimeetupit
Eliasz sawickimeetupitEliasz Sawicki
 
Developing more in less time
Developing more in less timeDeveloping more in less time
Developing more in less timeEliasz Sawicki
 
The art-of-developing-more-in-less-time-berlin
The art-of-developing-more-in-less-time-berlinThe art-of-developing-more-in-less-time-berlin
The art-of-developing-more-in-less-time-berlinEliasz Sawicki
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react nativeEliasz Sawicki
 
Doing more in less time - Mobiconf
Doing more in less time - MobiconfDoing more in less time - Mobiconf
Doing more in less time - MobiconfEliasz Sawicki
 
Time traveling with ReSwift
Time traveling with ReSwiftTime traveling with ReSwift
Time traveling with ReSwiftEliasz Sawicki
 
ReSwift CocoaHeads Tricity
ReSwift CocoaHeads TricityReSwift CocoaHeads Tricity
ReSwift CocoaHeads TricityEliasz Sawicki
 
ReactiveCocoa workshop
ReactiveCocoa workshopReactiveCocoa workshop
ReactiveCocoa workshopEliasz Sawicki
 

Mehr von Eliasz Sawicki (10)

Redux - 4Developers
Redux - 4DevelopersRedux - 4Developers
Redux - 4Developers
 
Eliasz sawickimeetupit
Eliasz sawickimeetupitEliasz sawickimeetupit
Eliasz sawickimeetupit
 
Developing more in less time
Developing more in less timeDeveloping more in less time
Developing more in less time
 
The art-of-developing-more-in-less-time-berlin
The art-of-developing-more-in-less-time-berlinThe art-of-developing-more-in-less-time-berlin
The art-of-developing-more-in-less-time-berlin
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
 
Doing more in less time - Mobiconf
Doing more in less time - MobiconfDoing more in less time - Mobiconf
Doing more in less time - Mobiconf
 
Time traveling with ReSwift
Time traveling with ReSwiftTime traveling with ReSwift
Time traveling with ReSwift
 
Calabash
CalabashCalabash
Calabash
 
ReSwift CocoaHeads Tricity
ReSwift CocoaHeads TricityReSwift CocoaHeads Tricity
ReSwift CocoaHeads Tricity
 
ReactiveCocoa workshop
ReactiveCocoa workshopReactiveCocoa workshop
ReactiveCocoa workshop
 

Tech fest