O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Swift Delhi: Practical POP

2.263 visualizações

Publicada em

Presented at the Swift Delhi Meetup https://swiftindia.github.io/swiftindia/

Publicada em: Tecnologia
  • I just began eight weeks past and i have become four check for an entire of $4,15000...this is the best call I made in quite a while! "Much obliged to you for giving American express this unprecedented opportunity to make more cash from home. This further cash has adjusted my life in such a lot of courses in which, bestow you!".......GOOD LUCK Click this snap this connection -=-=-=-=-=-=-=-=-=-=-= http://www.cash-review.com
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui

Swift Delhi: Practical POP

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

×