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

From Objective-C to Swift - MOConf 2015

From Objective-C to Swift - MOConf 2015

Talk made during the MOConf 2015 in Minsk, Belarus

Junior B.

July 13, 2015

More Decks by Junior B.

Other Decks in Programming


  1. –Terry Pratchett “It is important that we know where we

    come from, because if you do not know where you come from, you don't know where you're going.”
  2. “Good” Old Times - 2008 - (void)dealloc { _delegate =

    nil; [self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; [_viewControllers release]; [_barButtonItem release]; [_hiddenPopoverController release]; [_dividerView release]; [_cornerViews release]; [super dealloc]; } source: MGSplitViewController
  3. “Good” Old Times - 2008 @implementation PageLoadOperation // NSOperation -

    (void)main { NSString *webpageString = [[[NSString alloc] initWithContentsOfURL:[self targetURL]] autorelease]; NSError *error = nil; NSXMLDocument *document = [[NSXMLDocument alloc] initWithXMLString: …]; if (error) { return; } [[AppDelegate shared] performSelectorOnMainThread:@selector(pageLoaded:) withObject:document waitUntilDone:YES]; [document release]; } @end source: Cocoa Is My Girlfriend (2009)
  4. Today • We don’t need anymore release, autorelease or retain.

    • NSOperation and related friends have been internally implemented using Grand Central Dispatch, the latter seems now generally preferred. • Objective-C has blocks, syntax can be learned on goshdarnblocksyntax.com (there’s a less polite version) • A lot more changed… and we have a new programming language!
  5. Why not Swift? • Compiler is new and “drama queen”

    with generics • The number of libraries available is still low compared to Objective-C, but is growing • Objective-C is not going anywhere soon • Syntax keeps changing (1.2 -> 2.0)
  6. Why Swift? • Swift is a statically-typed language • Dynamic

    Framework Support • It requires less code • Apple says is faster • Playgrounds • Less files, no more .h and .m, just one .swift file
  7. id has gone! • Finally isKindOfClass will not be required

    anymore • We now have 2 new types class and struct, we can pick the one that suits best our design • The code is safer with casting “as” // passed by reference class SomeClass { var foo: String init(foo: String) { self.foo = foo } } // passed by value (copy) struct SomeStruct { var bar: String init(bar: String) { self.bar = bar } }
  8. When class, when struct? • class preserves identity • struct

    preserves data • struct is easier to handle in a multi-thread environment • Apple suggests to use struct whenever is possible and to use class when is necessary (identity preservation or deinitializers)
  9. Statements sugar in 2.0 • guard has been added to

    make conditional checks and to throw exceptions • defer will take care to run “cleaning” operations when leaving the scope, no matter what (f.e.: closing a file) • do, try, catch have been added to make the error handling system more powerful taking advantage of the type ErrorType • Availability check easier with #available(iOS 9, *)
  10. Defer func deferTest() { var string: NSString? = nil defer

    { if let s = string { print(s) } } string = "test" } deferTest() // This call will print "test"
  11. Guard enum PasswordError: ErrorType { case Empty case Short }

    func encryptPassword(password: String) -> NSData { let count = password.characters.count guard count > 0 else { throw PasswordError.Empty } guard count > 5 else { throw PasswordError.Short } //Encrypt the password return ecryptedPassword }
  12. It’s required to catch every possible error, not just the

    ones supposed to be thrown. In Swift 2.0, the error handling model is exhaustive and resilient.
  13. Error Handling enum BeerError: ErrorType { case TooMuch case NotAvailable

    } do { let beer = try getAnAwesomeBeer(pub) print("I drink it \(beer)") } catch BeerError.TooMuch { print("Hmm... too much, bartender said NO!") } catch BeerError.NotAvailable { print("Let's find another place") } catch { // Catch must be exhaustive print("Ouch!") }
  14. Generics • Swift has Generics! • “Generic code enables you

    to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. You can write code that avoids duplication and expresses its intent in a clear, abstracted manner.” — The Swift Programming Language • A generic function uses a placeholder name, like “T” instead of an actual type, this means that the compiler will check that types are matching, throwing errors if something is wrong.
  15. Generics - Example func printIntFromArray(a: [Int]) { for i in

    a { print(i) } } func printDoubleFromArray(a: [Double]) { for d in a { print(d) } } // both functions can be rewritten with a single one func printItemsInArray<T>(a: [T]) { for item in a { print(item) } }
  16. Take advantage of syntax • If a function’s final argument

    is a closure, we can write it as “trailing closure”. • Closures in Swift are similar to blocks in Objective-C and to lambdas in other programming languages (ed: Java 7, C#, Scala, etc…) func someFunctionWithAClosure(closure: () -> ()) { // function body goes here } someFunctionWithAClosure(){ // closure's body goes here }
  17. In Swift there’s no KVO • Key Value Observing was

    one of the most used features of Objective-C • Swift doesn’t have KVO, but the language is very powerful and offers some good alternatives
  18. Alternatives to KVO • Create a custom observer class and

    use get and set to fire events • Consider binding abstraction and use frameworks like SwiftBond • Consider Functional Reactive Programming and implementations like RAC 3.0 or RxSwift
  19. SwiftBond var tableViewDataSourceBond: UITableViewDataSourceBond<UITableViewCell>! override func viewDidLoad() { super.viewDidLoad() //

    create a data source bond for table view tableViewDataSourceBond = UITableViewDataSourceBond(tableView: self.tableView) // map repositories to cells and bind repositories.map { [unowned self] (repository: Repository) -> RepositoryTableViewCell in let cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as RepositoryTableViewCell repository.name ->> cell.nameLabel repository.photo ->> cell.avatarImageView return cell } ->> tableViewDataSourceBond } source: SwiftBond documentation
  20. RxSwift override func viewDidLoad() { super.viewDidLoad() // ... let signingProcess

    = combineLatest(username, password) { ($0, $1) } >- sampleLatest(signupSampler) >- map { (username, password) in return API.signup(username, password: password) } >- switchLatest >- startWith(.InitialState) >- variable // ... } source: RxSwift Example
  21. Still not sure about Swift? • Swift is the future

    of Apple products, sooner or later it could be necessary to learn it • Learning Swift now will pay also in along term • Swift is going Open Source, we can influence its path
  22. Real World Example • Swift requires less code, some classes

    have been rewritten with 20% less lines • Using Swift made our project less error-prone, we decreased the number of crashes by a consistent factor
  23. Resources • The Swift Programming Book • Hacking with Swift,

    a complete Swift training course (online)