Upgrade to Pro — share decks privately, control downloads, hide ads and more …

え!? Swift使ってるのにそんな書きかたしてるのですか!?

え!? Swift使ってるのにそんな書きかたしてるのですか!?

iOSアプリをSwiftらしいコードで記述するために

Yusei Nishiyama

November 25, 2014
Tweet

More Decks by Yusei Nishiyama

Other Decks in Technology

Transcript

  1. Who am I? • Mobile app engineer at Cookpad Inc.

    • Develop apps for iOS • Regulate “Auto Layout” day after day… :’-( • I’m interested in • Metal (new graphics API of Apple) • Functional programming (with Swift) • Reactive programming (Reactive Cocoa)
  2. In Objective-C era… @interface SomeClass : NSObject @property (nonatomic, strong)

    NSString *someString; @end ! @implementation SomeClass ! - (void)setSomeString:(NSString *)someString { _someString = someString; [self doSomething]; } ! - (void)doSomething { NSLog(@"I don't feel like doing anything..."); } ! @end ؆୯ʹ୅ೖ࣌ʹॲཧΛߦ͏͜ͱ͕Ͱ͖ͨ
  3. With Swift class SomeClass { private var backingStore = ""

    var value: String { get { return backingStore } set { backingStore = newValue doSomething() } } func doSomething() { println("I don't feel like doing anything.") } } 85'
  4. Keep calm class SomeClass { var someString: String = ""

    { didSet { doSomething() } } func doSomething() { println("Now I’m sleeping. Please don’t disturb.") } } XJMM4FU΍EJE4FUΛ࢖͑͹ಉ͜͡ͱ͕࣮ݱՄೳ
  5. Coalesce fallback class Person { var name: String! } !

    var quietPerson = Person() quietPerson.name = "Tom" ! var hisName: String! ! if quietPerson.name != nil { hisName = quietPerson.name } else { hisName = "I can't recognize what he says" }
  6. Use `??` class Person { var name: String! } !

    var quietPerson = Person() quietPerson.name = "Tom" ! var hisName = quietPerson.name ?? "I can't recognize what he says"
  7. (Annoying) weakSelf pattern class SomeClass { var ivar: Int? func

    methodA(function: ()->()) { function() } func methodB() { weak var weakSelf = self methodA { () -> () in weakSelf!.ivar = 3 } } }
  8. use `[unowned self]` class SomeClass { var ivar: Int? func

    methodA(function: ()->()) { function() } func methodB() { methodA { [unowned self] () -> () in self.ivar = 3 } } }
  9. Static variables in function - (BOOL)toggleSwitch { static BOOL aSwitch

    = true; aSwitch = !aSwitch; return aSwitch; }
  10. Use struct func toggleSwitch() -> Bool { struct Switch {

    static var aSwitch = true } Switch.aSwitch = !Switch.aSwitch return Switch.aSwitch }
  11. Cast var anyObject: AnyObject? = "WE ARE UPPERCASE" if anyObject

    is String { let string = anyObject as String println(string.lowercaseString + "?") } ৑௕ʁ
  12. You can check, cast and bind in one line !

    if let string = anyObject as? String { println(string.lowercaseString + "?") }
  13. Trailing closure func methodX(i: Int, function: ()->(String)) { function() }

    ! methodX(1, { () -> (String) in return "Do nothing" } ) ! methodX(1) { () -> (String) in return "Do nothing" }
  14. Swift array supports map, filter and reduce class Vehicle {

    var numberOfTires: Int = 0 } class Car: Vehicle { override init() { super.init() numberOfTires = 4 } } class Bicycle: Vehicle { override init() { super.init() numberOfTires = 2 } } class Unicycle: Vehicle { override init() { super.init() numberOfTires = 1 } } let vehicles = [Car(), Car(), Unicycle(), Bicycle(), Car(), Unicycle()] var numberOfAllTires = vehicles.map{ $0.numberOfTires }.reduce(0, +)
  15. Nested function func setUpViews() { func setupBarButton() { // set

    up bar buttons } func setupRefreshControl() { // set up refresh control } setupBarButton() setupRefreshControl() } είʔϓΛอͬͨ··ɺॲཧΛߏ଄Խ͢Δ͜ͱ͕Ͱ͖Δ
  16. Enum with method enum MyTableViewSection: Int { case A =

    0, B, C, D func heightForCell() -> CGFloat { switch self { case A: return 30 case B: return 44 case C: return 80 case D: return 44 } } } ! func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return MyTableViewSection(rawValue: indexPath.section)!.heightForCell() } ؔ࿈͢ΔॲཧΛ&OVNଆʹҠৡͨ͠΄͏͕Մಡੑ͕ߴ͍