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. ͑!? Swift࢖ͬͯΔͷʹͦΜͳ
    ॻ͖͔ͨͯ͠ΔͷͰ͔͢!?
    potatotips#11
    @yuseinishiyama

    View Slide

  2. 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)

    View Slide

  3. 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
    ؆୯ʹ୅ೖ࣌ʹॲཧΛߦ͏͜ͱ͕Ͱ͖ͨ

    View Slide

  4. 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'

    View Slide

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

    View Slide

  6. 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"
    }

    View Slide

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

    View Slide

  8. (Annoying) weakSelf pattern
    class SomeClass {
    var ivar: Int?
    func methodA(function: ()->()) {
    function()
    }
    func methodB() {
    weak var weakSelf = self
    methodA { () -> () in
    weakSelf!.ivar = 3
    }
    }
    }

    View Slide

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

    View Slide

  10. Static variables in function
    - (BOOL)toggleSwitch
    {
    static BOOL aSwitch = true;
    aSwitch = !aSwitch;
    return aSwitch;
    }

    View Slide

  11. 4XJGU͸ߏ଄ମͰ͔͠TUBUJDม਺Λαϙʔ
    τ͍ͯ͠ͳ͍ʜ

    View Slide

  12. Use struct
    func toggleSwitch() -> Bool {
    struct Switch {
    static var aSwitch = true
    }
    Switch.aSwitch = !Switch.aSwitch
    return Switch.aSwitch
    }

    View Slide

  13. Cast
    var anyObject: AnyObject? = "WE ARE UPPERCASE"
    if anyObject is String {
    let string = anyObject as String
    println(string.lowercaseString + "?")
    }
    ৑௕ʁ

    View Slide

  14. You can check, cast and bind
    in one line
    !
    if let string = anyObject as? String {
    println(string.lowercaseString + "?")
    }

    View Slide

  15. Trailing closure
    func methodX(i: Int, function: ()->(String)) {
    function()
    }
    !
    methodX(1, { () -> (String) in return "Do nothing" } )
    !
    methodX(1) { () -> (String) in return "Do nothing" }

    View Slide

  16. 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, +)

    View Slide

  17. Nested function
    func setUpViews() {
    func setupBarButton() {
    // set up bar buttons
    }
    func setupRefreshControl() {
    // set up refresh control
    }
    setupBarButton()
    setupRefreshControl()
    }
    είʔϓΛอͬͨ··ɺॲཧΛߏ଄Խ͢Δ͜ͱ͕Ͱ͖Δ

    View Slide

  18. 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ଆʹҠৡͨ͠΄͏͕Մಡੑ͕ߴ͍

    View Slide

  19. Any Questions?

    View Slide