$30 off During Our Annual Pro Sale. View Details »

Converting Objective-C to Swift

Converting Objective-C to Swift

Learn about a lot of issues encountered when converting code to Swift, and about Swift in general.

Avatar for David Kobilnyk

David Kobilnyk

August 14, 2014
Tweet

Other Decks in Programming

Transcript

  1. Swift Types Value Types Reference Types Enums Structs Classes Int

    Float Array Dictionary String Bool Double
  2. No Implicit Casting float red = (arc4random() % 100) /

    100.0; ! ! let red = (arc4random() % 100) / 100.0 'UInt32' is not convertible to 'Int' ! let red = Float(arc4random() % 100) / 100.0 // Ok
  3. Arrays ! NSArray *a = @[@"pale ale", @"stella"]; ! !

    let a: [String] = ["pale ale", "stella"] // or let a = ["pale ale", "stella"]
  4. Mutating an Array ! NSMutableArray *a = @[]; [a addObject:@"hefeweizen"];

    ! ! var a = [String]() a.append("hefeweizen") a += ["hefeweizen"]
  5. Dictionaries ! NSMutableDictionary *ages = [NSMutableDictionary new]; ! ! var

    ages: [String: Int] = [String: Int]() var ages = [String: Int]()
  6. Iterating Dictionaries for (NSString *name in ages) { NSLog(@"%@ is

    %@", name, [ages objectForKey:name]); } ! for (name, age) in ages { println("\(name) is \(age)") }
  7. Value Type Mutability let a = [1, 2] a[0] =

    5 '@lvalue $T5' is not identical to 'Int' ! var a = [1, 2] a[0] = 5 // no error
  8. Mutability of Classes let str1 = NSMutableAttributedString(string:"yo") str1.appendAttributedString(str1) // no

    error ! var str2 = NSAttributedString(string: "yo") str2.appendAttributedString(str2) ! 'NSAttributedString' does not have a member named 'appendAttributedString'
  9. Mutability of Classes let str1 = NSMutableAttributedString(string: "yo") var str2

    = NSAttributedString(string: "yo") ! str2 = str1 // no error str1 = str2 ! 'Cannot assign to 'let' value 'str1'
  10. Class Initialization [UIColor colorWithRed:0.1 green:0.6 blue:0.3 alpha:1.0]; [[UIColor alloc] initWithRed:0.1

    green:0.6 blue:0.3 alpha:1.0]; ! UIColor(red: 0.1, green: 0.6, blue: 0.3, alpha: 1.0)
  11. Nil let a: Int = nil Type 'Int' does not

    conform to protocol 'NilLiteralConvertible' ! let b: Int? = nil // No error
  12. Unwrapping Optionals let a: Int? = 10 println(a) // prints

    "Optional(10)" println(a!) // prints "10" ! let b: Int? = nil println(b!) // fatal error: unexpectedly found nil while unwrapping an Optional value
  13. Unwrapping Optionals var name: String? = "Al" if let unwrappedName

    = name { println(unwrappedName) } else { println("name is nil") }
  14. Unwrapping Optionals var name: String? = "Al" if let name

    = name { // This is ok println(name) // Using unwrapped 'name' }
  15. Mutating Optional Value Types if var unwrappedName = name {

    unwrappedName.write("bert") // unwrappedName changes to "Albert" // name remains "Al" }
  16. Mutating Optional Value Types var unwrappedName = name! unwrappedName.write("bert") //

    name is still "Al" name!.write("bert") // force unwrap // name is now "Albert" name?.write("bert") // safe unwrap // name is now "Albertbert"
  17. Mutating Optional Class Types let v: UIView? = UIView() if

    let u = v { u.hidden = true } // v is updated as well
  18. Mutating Optional Class Types let v: UIView? = UIView() let

    u = v! u.hidden = true // v is updated as well
  19. Checking for Nil var name: String? = "Al" if name

    { // causes error // … } Type 'String?' does not conform to protocol 'BooleanType.Protocol'
  20. Checking for Nil var name: String? = "Al" if let

    _ = name { // … } // No error
  21. Stored Properties class Food { var name: String init() {}

    } Error: Property 'self.name' not initialized
  22. Designated Inits class Food { var name: String init(name: String)

    { self.name = name } } var food = Food(name: "hard-boiled egg")
  23. Designated Inits class Food { var name: String init(name: String)

    { self.name = name } } var food = Food() !
  24. Designated Inits class Food { var name: String init(name: String)

    { self.name = name } } var food = Food() Missing argument for parameter 'name' in call
  25. Convenience Inits class Food { var name: String init(name: String)

    { self.name = name } convenience init() { self.init(name: "[Unnamed]") } }
  26. Inits and Inheritance class RecipeIngredient: Food { var quantity: Int

    } Error: Class ‘RecipeIngredient’ has no initializers
  27. Inits and Inheritance class RecipeIngredient: Food { var quantity: Int

    init(name: String, quantity: Int) { self.quantity = quantity super.init(name: name) } } // No error
  28. Inits and Inheritance class RecipeIngredient: Food { var quantity: Int

    init(name: String, quantity: Int) { … } override convenience init(name: String) { self.init(name: name, quantity: 1) } }
  29. Init Code Conversion Example @interface BNRDrawView () <UIGestureRecognizerDelegate> ! @property

    (nonatomic, strong) UIPanGestureRecognizer *moveRecognizer; ! @end
  30. Init Code Conversion Example @implementation BNRDrawView - (instancetype)initWithFrame:(CGRect)r { self

    = [super initWithFrame:r]; if (self) { self.moveRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveLine:)]; [self addGestureRecognizer:self.moveRecognizer]; } return self; }
  31. Init Code Conversion Example override init(frame: CGRect) { moveRecognizer =

    UIPanGestureRecognizer(target: self, action: "moveLine:") addGestureRecognizer(moveRecognizer) super.init(frame: frame) }
  32. Init Code Conversion Example override init(frame: CGRect) { moveRecognizer =

    UIPanGestureRecognizer(target: self, action: "moveLine:") addGestureRecognizer(moveRecognizer) super.init(frame: frame) } 'self' used before super.init call
  33. Init Code Conversion Example override init(frame: CGRect) { super.init(frame: frame)

    moveRecognizer = UIPanGestureRecognizer(target: self, action: "moveLine:") addGestureRecognizer(moveRecognizer) } Property 'self.moveRecognizer' not initialized at super.init call
  34. Init Code Conversion Example override init(frame: CGRect) { super.init(frame: frame)

    moveRecognizer = UIPanGestureRecognizer(target: self, action: "moveLine:") addGestureRecognizer(moveRecognizer) } // No error
  35. IBOutlets @property (nonatomic, weak) IBOutlet UIDatePicker *datePicker; ! @IBOutlet weak

    var datePicker: UIDatePicker? @IBOutlet weak var datePicker: UIDatePicker!
  36. Custom Setters @property (nonatomic, strong) BNRItem *containedItem; // … -

    (void)setContainedItem:(BNRItem *)containedItem { _containedItem = containedItem; self.containedItem.container = self; }
  37. willSet/didSet var containedItem: BNRItem? { didSet { if let containedItem

    = containedItem { containedItem.container = self } } }
  38. Privately Mutable Public Properties ! @interface BNRItemStore () @property (nonatomic,

    readonly) NSArray *allItems; @end ! @interface BNRItemStore () @property (nonatomic) NSMutableArray *privateItems; @end