Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
@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
Prochain SlideShare
Chargement dans…5
×

Practical Protocol-Oriented-Programming

76 053 vues

Publié le

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.

Publié dans : Technologie
  • Sex in your area is here: www.bit.ly/sexinarea
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • If you want a girl to "chase" you, then you have to use the right "bait". We discovered 4 specific things that FORCE a girl to chase after you and try to win YOU over. copy and visiting... ★★★ http://ishbv.com/unlockher/pdf
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Dating for everyone is here: www.bit.ly/2AJerkH
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Instantly Hard-Wire Your Mind For Millionaire SUCCESS ➤➤ http://ishbv.com/manifestd1/pdf
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • My special guest's 3-Step "No Product Funnel" can be duplicated to start earning a significant income online. ●●● http://dwz1.cc/G9GauKYg
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

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

×