Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
@NatashaTheRobot
Protocol-Oriented Programming in Swift
Dave Abrahams Professor of Blowing-Your-Mind
–- Professor of Blowing-Your-Mind
"Swift Is a Protocol-Oriented Programming Language"
Practical POP
• View
• (UITable)ViewController
• Networking
POP Views
// FoodImageView.swift
import UIKit
class FoodImageView: UIImageView {
func shake() {
let animation = CABasicAnimation(key...
// ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var foodImageView: FoodImageV...
💃💃💃
// ShakeableButton.swift
import UIKit
class ActionButton: UIButton {
func shake() {
let animation = CABasicAnimation(keyPa...
// ViewController.swift
class ViewController: UIViewController {
@IBOutlet weak var foodImageView: FoodImageView!
@IBOutle...
🤔
// UIViewExtension.swift
import UIKit
extension UIView {
func shake() {
let animation = CABasicAnimation(keyPath: "positio...
class FoodImageView: UIImageView {
// other customization here
}
class ActionButton: UIButton {
// other customization her...
// Shakeable.swift
import UIKit
protocol Shakeable { }
extension Shakeable where Self: UIView {
func shake() {
// implemen...
class FoodImageView: UIImageView, Shakeable {
}
class ActionButton: UIButton, Shakeable {
}
class FoodImageView: UIImageView, Shakeable, Dimmable {
}
class FoodImageView: UIImageView, Dimmable {
}
Transparent View Controllers
and Dim Backgrounds
totem.training
👯👯👯👯👯
POP (UITable)ViewControllers
// FoodLaLaViewController
override func viewDidLoad() {
super.viewDidLoad()
let foodCellNib = UINib(nibName: "FoodTableVie...
let foodCellNib = UINib(nibName: String(FoodTableViewCell), bundle: nil)
tableView.registerNib(foodCellNib,
forCellReuseId...
protocol ReusableView: class {}
extension ReusableView where Self: UIView {
static var reuseIdentifier: String {
return St...
extension UITableViewCell: ReusableView { }
FoodTableViewCell.reuseIdentifier
// FoodTableViewCell
let foodCellNib = UINib(nibName: "FoodTableViewCell",
bundle: nil)
tableView.registerNib(foodCellNib,
forCellReuseIdentifi...
protocol NibLoadableView: class { }
extension NibLoadableView where Self: UIView {
static var nibName: String {
return Str...
extension FoodTableViewCell: NibLoadableView { }
FoodTableViewCell.nibName
// "FoodTableViewCell"
let foodCellNib = UINib(nibName: FoodTableViewCell.nibName, bundle: nil)
tableView.registerNib(foodCellNib,
forCellReuseId...
extension UITableView {
func register<T: UITableViewCell where T: ReusableView, T: NibLoadableView>(_: T.Type) {
let nib =...
let foodCellNib = UINib(nibName: "FoodTableViewCell", bundle: nil)
tableView.registerNib(foodCellNib,
forCellReuseIdentifi...
tableView.register(FoodTableViewCell)
extension UITableView {
func dequeueReusableCell<T: UITableViewCell where T: ReusableView>(forIndexPath indexPath: NSIndex...
guard let cell = tableView.dequeueReusableCellWithIdentifier(“FoodTableViewCell", forIndexPath: indexPath)
as? FoodTableVi...
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath) as FoodTableViewCell
if indexPath.row == 0 {
return tableView.dequeueReusableCell(forIndexPath: indexPath) as DesertTableViewCell
}
return tabl...
iOS Cell Registration & Reusing with
Swift Protocol Extensions and
Generics
medium.com/@gonzalezreal
Protocol-Oriented Segue
Identifiers in Swift
natashatherobot.com
POP Networking
struct FoodService {
func get(completionHandler: Result<[Food]> -> Void) {
// make asynchronous API call
// and return app...
enum Result<T> {
case Success(T)
case Failure(ErrorType)
}
struct FoodService {
func get(completionHandler: Result<[Food]> -> Void) {
// make asynchronous API call
// and return app...
// FoodLaLaViewController
var dataSource = [Food]() {
didSet {
tableView.reloadData()
}
}
override func viewDidLoad() {
su...
View Controller Tests?!!! 😱
// FoodLaLaViewController
var dataSource = [Food]() {
didSet {
tableView.reloadData()
}
}
override func viewDidLoad() {
su...
// FoodLaLaViewController
func getFood(fromService service: FoodService) {
service.getFood() { [weak self] result in
// ha...
// FoodLaLaViewControllerTests
func testFetchFood() {
viewController.getFood(fromService: FoodService())
// 🤔 now what?
}
struct FoodService {
func get(completionHandler: Result<[Food]> -> Void) {
// make asynchronous API call
// and return app...
protocol Gettable {
associatedtype T
func get(completionHandler: Result<T> -> Void)
}
struct FoodService: Gettable {
func get(completionHandler: Result<[Food]> -> Void) {
// make asynchronous API call
// and ...
// FoodLaLaViewController
override func viewDidLoad() {
super.viewDidLoad()
getFood(fromService: FoodService())
}
func get...
// FoodLaLaViewControllerTests
class Fake_FoodService: Gettable {
var getWasCalled = false
func get(completionHandler: Res...
// FoodLaLaViewControllerTests
func testFetchFood() {
let fakeFoodService = Fake_FoodService()
viewController.getFood(from...
Update: View Controller Data
Injection with Storyboards and
Segues in Swift
natashatherobot.com
Protocols with Associated Types
Alexis Gallagher
2015.funswiftconf.com
😎😎😎
Practical POP
• View
• (UITable)ViewController
• Networking
Beyond Crusty: Real-World
Protocols
Rob Napier
thedotpost.com
Blending Cultures: The Best of
Functional, Protocol-Oriented, and
Object-Oriented Programming
Daniel Steinberg
realm.io
@NatashaTheRobot
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Upcoming SlideShare
Loading in …5
×

Practical Protocol-Oriented-Programming

68,825 views

Published on

Value types are at the core of Swift (seriously, mostly everything in the Swift standard library is a value type). But how do you avoid subclassing? That’s where the power of Protocol-Oriented programming comes in. Learn how to structure your code to never subclass (almost) again! Practical everyday examples and ideas for your own code base will be included.

Published in: Technology
  • Nice !! Download 100 % Free Ebooks, PPts, Study Notes, Novels, etc @ https://www.ThesisScientist.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Imagine if you had a fully automated Sports betting robot that not only calculates all the stats and probabilities but also gives you EXACT picks you need to place to win? With EXACT unit sizes! Yes, complete No Brainer. 60 days money back guarantee, 100% risk free; Watch video here: http://bit.ly/jordantopaulvideo
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Download this 3-step guide to generating insane amounts of media coverage for your from LinkedIn: http://bit.ly/linkedin3stepguide
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • nice, Find Latest Presentation on Free at www.ThesisScientist.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • MRW I read these slides: https://j.gifs.com/mZVlYR.gif
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Practical Protocol-Oriented-Programming

  1. @NatashaTheRobot
  2. Protocol-Oriented Programming in Swift Dave Abrahams Professor of Blowing-Your-Mind
  3. –- Professor of Blowing-Your-Mind "Swift Is a Protocol-Oriented Programming Language"
  4. Practical POP • View • (UITable)ViewController • Networking
  5. POP Views
  6. // FoodImageView.swift import UIKit class FoodImageView: UIImageView { func shake() { let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.05 animation.repeatCount = 5 animation.autoreverses = true animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 4.0, self.center.y)) animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 4.0, self.center.y)) layer.addAnimation(animation, forKey: "position") } }
  7. // ViewController.swift import UIKit class ViewController: UIViewController { @IBOutlet weak var foodImageView: FoodImageView! @IBAction func onShakeButtonTap(sender: AnyObject) { foodImageView.shake() } }
  8. 💃💃💃
  9. // ShakeableButton.swift import UIKit class ActionButton: UIButton { func shake() { let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.05 animation.repeatCount = 5 animation.autoreverses = true animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 4.0, self.center.y)) animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 4.0, self.center.y)) layer.addAnimation(animation, forKey: "position") } }
  10. // ViewController.swift class ViewController: UIViewController { @IBOutlet weak var foodImageView: FoodImageView! @IBOutlet weak var actionButton: ActionButton! @IBAction func onShakeButtonTap(sender: AnyObject) { foodImageView.shake() actionButton.shake() } }
  11. 🤔
  12. // UIViewExtension.swift import UIKit extension UIView { func shake() { let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.05 animation.repeatCount = 5 animation.autoreverses = true animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 4.0, self.center.y)) animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 4.0, self.center.y)) layer.addAnimation(animation, forKey: "position") } }
  13. class FoodImageView: UIImageView { // other customization here } class ActionButton: UIButton { // other customization here } class ViewController: UIViewController { @IBOutlet weak var foodImageView: FoodImageView! @IBOutlet weak var actionButton: ActionButton! @IBAction func onShakeButtonTap(sender: AnyObject) { foodImageView.shake() actionButton.shake() } }
  14. // Shakeable.swift import UIKit protocol Shakeable { } extension Shakeable where Self: UIView { func shake() { // implementation code } }
  15. class FoodImageView: UIImageView, Shakeable { } class ActionButton: UIButton, Shakeable { }
  16. class FoodImageView: UIImageView, Shakeable, Dimmable { }
  17. class FoodImageView: UIImageView, Dimmable { }
  18. Transparent View Controllers and Dim Backgrounds totem.training
  19. 👯👯👯👯👯
  20. POP (UITable)ViewControllers
  21. // FoodLaLaViewController override func viewDidLoad() { super.viewDidLoad() let foodCellNib = UINib(nibName: "FoodTableViewCell", bundle: nil) tableView.registerNib(foodCellNib, forCellReuseIdentifier: "FoodTableViewCell") }
  22. let foodCellNib = UINib(nibName: String(FoodTableViewCell), bundle: nil) tableView.registerNib(foodCellNib, forCellReuseIdentifier: String(FoodTableViewCell))
  23. protocol ReusableView: class {} extension ReusableView where Self: UIView { static var reuseIdentifier: String { return String(self) } }
  24. extension UITableViewCell: ReusableView { } FoodTableViewCell.reuseIdentifier // FoodTableViewCell
  25. let foodCellNib = UINib(nibName: "FoodTableViewCell", bundle: nil) tableView.registerNib(foodCellNib, forCellReuseIdentifier: FoodTableViewCell.reuseIdentifier)
  26. protocol NibLoadableView: class { } extension NibLoadableView where Self: UIView { static var nibName: String { return String(self) } }
  27. extension FoodTableViewCell: NibLoadableView { } FoodTableViewCell.nibName // "FoodTableViewCell"
  28. let foodCellNib = UINib(nibName: FoodTableViewCell.nibName, bundle: nil) tableView.registerNib(foodCellNib, forCellReuseIdentifier: FoodTableViewCell.reuseIdentifier)
  29. extension UITableView { func register<T: UITableViewCell where T: ReusableView, T: NibLoadableView>(_: T.Type) { let nib = UINib(nibName: T.nibName, bundle: nil) registerNib(nib, forCellReuseIdentifier: T.reuseIdentifier) } }
  30. let foodCellNib = UINib(nibName: "FoodTableViewCell", bundle: nil) tableView.registerNib(foodCellNib, forCellReuseIdentifier: "FoodTableViewCell")
  31. tableView.register(FoodTableViewCell)
  32. extension UITableView { func dequeueReusableCell<T: UITableViewCell where T: ReusableView>(forIndexPath indexPath: NSIndexPath) -> T { guard let cell = dequeueReusableCellWithIdentifier(T.reuseIdentifier, forIndexPath: indexPath) as? T else { fatalError("Could not dequeue cell with identifier: (T.reuseIdentifier)") } return cell } }
  33. guard let cell = tableView.dequeueReusableCellWithIdentifier(“FoodTableViewCell", forIndexPath: indexPath) as? FoodTableViewCell else { fatalError("Could not dequeue cell with identifier: FoodTableViewCell") }
  34. let cell = tableView.dequeueReusableCell(forIndexPath: indexPath) as FoodTableViewCell
  35. if indexPath.row == 0 { return tableView.dequeueReusableCell(forIndexPath: indexPath) as DesertTableViewCell } return tableView.dequeueReusableCell(forIndexPath: indexPath) as FoodTableViewCell
  36. iOS Cell Registration & Reusing with Swift Protocol Extensions and Generics medium.com/@gonzalezreal
  37. Protocol-Oriented Segue Identifiers in Swift natashatherobot.com
  38. POP Networking
  39. struct FoodService { func get(completionHandler: Result<[Food]> -> Void) { // make asynchronous API call // and return appropriate result } }
  40. enum Result<T> { case Success(T) case Failure(ErrorType) }
  41. struct FoodService { func get(completionHandler: Result<[Food]> -> Void) { // make asynchronous API call // and return appropriate result } }
  42. // FoodLaLaViewController var dataSource = [Food]() { didSet { tableView.reloadData() } } override func viewDidLoad() { super.viewDidLoad() getFood() } private func getFood() { FoodService().getFood() { [weak self] result in switch result { case .Success(let food): self?.dataSource = food case .Failure(let error): self?.showError(error) } } }
  43. View Controller Tests?!!! 😱
  44. // FoodLaLaViewController var dataSource = [Food]() { didSet { tableView.reloadData() } } override func viewDidLoad() { super.viewDidLoad() getFood() } private func getFood() { FoodService().getFood() { [weak self] result in switch result { case .Success(let food): self?.dataSource = food case .Failure(let error): self?.showError(error) } } }
  45. // FoodLaLaViewController func getFood(fromService service: FoodService) { service.getFood() { [weak self] result in // handle result } }
  46. // FoodLaLaViewControllerTests func testFetchFood() { viewController.getFood(fromService: FoodService()) // 🤔 now what? }
  47. struct FoodService { func get(completionHandler: Result<[Food]> -> Void) { // make asynchronous API call // and return appropriate result } }
  48. protocol Gettable { associatedtype T func get(completionHandler: Result<T> -> Void) }
  49. struct FoodService: Gettable { func get(completionHandler: Result<[Food]> -> Void) { // make asynchronous API call // and return appropriate result } }
  50. // FoodLaLaViewController override func viewDidLoad() { super.viewDidLoad() getFood(fromService: FoodService()) } func getFood<S: Gettable where S.T == [Food]>(fromService service: S) { service.get() { [weak self] result in switch result { case .Success(let food): self?.dataSource = food case .Failure(let error): self?.showError(error) } } }
  51. // FoodLaLaViewControllerTests class Fake_FoodService: Gettable { var getWasCalled = false func get(completionHandler: Result<[Food]> -> Void) { getWasCalled = true completionHandler(Result.Success(food)) } }
  52. // FoodLaLaViewControllerTests func testFetchFood() { let fakeFoodService = Fake_FoodService() viewController.getFood(fromService: fakeFoodService) XCTAssertTrue(fakeFoodService.getWasCalled) XCTAssertEqual(viewController.dataSource.count, food.count) XCTAssertEqual(viewController.dataSource, food) }
  53. Update: View Controller Data Injection with Storyboards and Segues in Swift natashatherobot.com
  54. Protocols with Associated Types Alexis Gallagher 2015.funswiftconf.com
  55. 😎😎😎
  56. Practical POP • View • (UITable)ViewController • Networking
  57. Beyond Crusty: Real-World Protocols Rob Napier thedotpost.com
  58. Blending Cultures: The Best of Functional, Protocol-Oriented, and Object-Oriented Programming Daniel Steinberg realm.io
  59. @NatashaTheRobot

×