Slide 1

Slide 1 text

Discovering Na.ve Swi1 Pa3erns Developing clear, consise code Nick O'Neill • @nickoneill Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 2

Slide 2 text

That Thing in Swi+ let's think swi$y Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 3

Slide 3 text

How can I express what I'm doing more clearly? Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 4

Slide 4 text

Sta$c table cells Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 5

Slide 5 text

the objec)ve-c way if (indexPath.section == 0) { if (indexPath.row == 0) { cell.textLabel.text = @"Twitter" } else if (indexPath.row == 1) { cell.textLabel.text = @"Blog" } else { cell.textLabel.text = @"Contact Us" } } else { if (indexPath.row == 0) { cell.textLabel.text = @“@nickoneill" } else if (indexPath.row == 1) { cell.textLabel.text = @“@objctoswift" } else { cell.textLabel.text = @“@whyareyousodumb" } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 6

Slide 6 text

a be%er? swi+ way let shortPath = (indexPath.section, indexPath.row) switch shortPath { case (0, 0): cell.textLabel.text = "Twitter" case (0, 1): cell.textLabel.text = "Blog" case (0, 2): cell.textLabel.text = "Contact Us" case (1, 0): cell.textLabel.text = “@nickoneill" case (1, 1): cell.textLabel.text = “@objctoswift" case (1, 2): cell.textLabel.text = “@whyareyousodumb" default: cell.textLabel.text = "¯\\_(ϑ)_/¯" } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 7

Slide 7 text

the best? swi* way enum TwitterHandles: Int { case Nickoneill case Objctoswift case Whyareyousodumb func labelText() -> String { switch self { ... } } } let rowData = TwitterHandles(rawValue: indexPath.row) cell.textLabel.text = rowData.labelText() Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 8

Slide 8 text

Our idea of the best Swi/ pa1erns will change over 8me Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 9

Slide 9 text

Not every piece of clever code is a great pa0ern Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 10

Slide 10 text

objec&ve-c dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // do some task dispatch_async(dispatch_get_main_queue(), ^{ // update some UI }); }); Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 11

Slide 11 text

swi$ func mainToBackground(background: () -> (), main: () -> ()) { let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_async(dispatch_get_global_queue(priority, 0)) { background() dispatch_async(dispatch_get_main_queue()) { main() } } } mainToBackground({ // do some task }, { // update the ui }) Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 12

Slide 12 text

swi$? { /* do some task */ } ~> { /* update some UI */} Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 13

Slide 13 text

Great pa(erns provide convenience while maintaining clarity Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 14

Slide 14 text

Custom Operators not even once Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 15

Slide 15 text

class ViewController: UIViewController { let imageView = UIImageView() let goButton = UIButton() override func viewDidLoad() { imageView.image = UIImage(named: "profile") view.addSubview(imageView) goButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30) goButton.setTitle("GO!", forState: .Normal) view.addSubview(goButton) } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 16

Slide 16 text

class ViewController: UIViewController { let imageView: UIImageView = { let imageView = UIImageView() imageView.image = UIImage(named: "profile") return imageView }() let goButton: UIButton = { let button = UIButton() button.frame = CGRect(x: 0, y: 0, width: 30, height: 30) button.setTitle("GO!", forState: .Normal) return button }() override func viewDidLoad() { view.addSubview(imageView) view.addSubview(goButton) } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 17

Slide 17 text

@IBOutlet weak var arrivalLabel: UILabel! { didSet { arrivalLabel.text = "Arriving in 10 minutes".uppercaseString arrivalLabel.font = UIFont(name: "Lato", size: 11) arrivalLabel.textColor = UIColor.blueColor() arrivalLabel.textAlignment = .Center arrivalLabel.numberOfLines = 1 } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 18

Slide 18 text

Swi$ pa(erns to make Swi$ be(er Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 19

Slide 19 text

override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) if let paths = tableView.indexPathsForSelectedRows { for path in paths { tableView.deselectRowAtIndexPath(path, animated: true) } } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 20

Slide 20 text

tableView.indexPathsForSelectedRows?.forEach({ (path) in tableView.deselectRowAtIndexPath(path, animated: true) }) Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 21

Slide 21 text

tableView.indexPathsForSelectedRows?.forEach { tableView.deselectRowAtIndexPath($0, animated: true) } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 22

Slide 22 text

Simple pa)erns can replace large dependencies Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 23

Slide 23 text

Unboxing1, or any JSON -> struct framework let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []) if let object = json as? Dictionary, places: [Place] = Unbox(object) { return places } 1 h$ps:/ /github.com/JohnSundell/Unbox Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 24

Slide 24 text

struct Place: Unboxable { let id: String let address: Int? let text: String init(unboxer: Unboxer) { self.id = unboxer.unbox("id") self.address = unboxer.unbox("address") self.placeName = unboxer.unbox("place_name") } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 25

Slide 25 text

struct Place { // ... init?(json: Dictionary) { guard let id = json["_id"] as? String else { return nil } self.id = id self.address = json["address"] as? Int self.placeName = (json["name"] as? String) ?? "No place name" } } Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 26

Slide 26 text

Smart architecture decisions are just big pa4erns • Networking • Core Data • No0fica0onCenter/KVO/delegates Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 27

Slide 27 text

Tips for finding new pa0erns • Develop an intui.on for code smell • Experiment in playgrounds or simplified projects • Re-read the language guide • Keep things clear Discovering Na.ve Swi1 Pa3erns • June 9th, 2016

Slide 28

Slide 28 text

Thanks! Ques%ons? Comments? @nickoneill • [email protected] Discovering Na.ve Swi1 Pa3erns • June 9th, 2016