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

Swift and Objective-C playing together

Swift and Objective-C playing together

Start using Swift in your Objective-C projects. Avoid some headaches with these useful tips and advices for the communication layer between your Objective-C code base and your future Swift implementations


Pedro Piñera Buendía

December 09, 2014

More Decks by Pedro Piñera Buendía

Other Decks in Technology


  1. Swift & Objective-C Playing together @pepibumur | www.ppinera.es

  2. SugarRecord Data Storage made easy with Swift (http://github.com/SugarRecord)

  3. Objective-C without the C Swift !

  4. None
  5. Play !

  6. Play ! Learn !

  7. Play ! Learn ! Try !

  8. None
  9. None
  10. None
  11. None
  12. Swift was Designed to play together

  13. None
  14. None
  15. Bridging

  16. None
  17. Objective-C into Swift Project-Bridging-Header.h

  18. Bridging header // // Use this file to import your

    target's public headers that you would like to expose to Swift. // // I can import CocoaPods Libraries here! #import <AFNetworking/AFNetworking.h> // And my Objective-C classes #import "CocaColaAlgorithm.h" Swift implementation // Use here your Objective-C exposed classes let cola = CocaColaAlgorithm.prepareCola()
  19. Swift into Objective-C Autogenerated ProductName-Swift.h file (Not TargetName!) Swift.swift class

    NSObjectSwiftClass: NSObject { } ProductName-Swift.h SWIFT_CLASS("_TtC9SwiftObjc18NSObjectSwiftClass") @interface NSObjectSwiftClass : NSObject - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end
  20. What's exposed? • Marked with @objc or Objective-C class descendant

    • public elements • private are exposed if marked with @IBAction, @IBOutlet, or @objc • internal are exposed if the project has an Objective-C bridging header • Objective-C compatible features
  21. Swift only features • Generics, tuples and Swift enums •

    Structures defined in Swift • Top-level functions defined in Swift • Global variables defined in Swift • Typealiases defined in Swift • Swift-style variadics • Nested types and curried functions
  22. No more imports! ! For .swift files in the same

  23. Be careful with circular dependencies Don't include Product-Swift.h in your

    Objc-C .h files
  24. Use forward declaration @class

  25. Naming your product Module • Non alpha-numeric characters replaced by

    "_" (or starting by a number) • XCode generates _fit-Swift.h from the product name 8fit
  26. What can we do? And what not?

  27. Inheriting Objective-C classes (Remember to use the @override keyword) class

    MyCell: UITableViewCell { override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
  28. You cannot subclass Swift classes in Objective-C (Even if the

    class is a Swift @objc or NSObject class) #if !defined(SWIFT_CLASS) # if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted) # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA # else # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA # endif #endif SWIFT_CLASS("_TtC9SwiftObjc9ObjcClass") @interface ObjcClass - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end
  29. AnyObject is the Swift equivalent of id (But it's a

    protocol and its type is not know until runtime) if let fifthCharacter = myObject.characterAtIndex?(5) { println("Found \(fifthCharacter) at index 5") } You can use casting if let date = lastRefreshDate as? NSDate { println("\(date.timeIntervalSinceReferenceDate)") }
  30. Objective-C nils Are implicitly unwrapped in Swift Be careful! The

    force awakens
  31. Objective-C - (NSDate *)dueDateForProject:(Project *)project; Swift func dueDateForProject(project: Project!) ->

  32. Extension & Category But swift extension can make classes conform

    protocols that they didn't extension MyClass: StringLiteralConvertible { typealias ExtendedGraphemeClusterLiteralType = StringLiteralType init(unicodeScalarLiteral value: UnicodeScalarLiteralType) { self.pattern = "\(value)" } init(extendedGraphemeClusterLiteral value: StringLiteralType) { self.pattern = value } init(stringLiteral value: StringLiteralType) { self.pattern = value } }
  33. Closures & Blocks Fully compatible The only difference is that

    variables are mutable rather than copied, e.g:
  34. Objective-C __block CustomObject *myObject = [CustomObject new]; void (^myBlock)() =

    ^void() { NSLog(@"%@", myObject); }; Swift let customObject: MyObject = MyObject() let myBlock: () -> () = { in println("\(customObject)") }
  35. FuckingBlockSyntax.com FuckingClosureSyntax.com !

  36. Comparison Objective-C isEqualTo() - Equality == - Object instance Swift

    == - Equality === - Object instance
  37. @objc @objc(ObjcCat) class SwiftCat { @objc(initWithName:) init (name: String) {

    /*...*/ } } @objc is inferred if it's a NSObject subclass
  38. Protocols • Swift can adopt Objective-C protocols • Objective-C can

    adopt Swift protocol if they are NSObjectProtocol Adopting swift protocols in objective-C /** MyProtocol.swift */ @objc protocol MyProtocol: NSObjectProtocol { // Protocol stuff }
  39. Protocols in Delegate pattern It must be declared as a

    class type (It can only be conformed by reference types, thus having a weak reference) protocol MyDelegate : class { // methods/properties }
  40. Cocoa Data Types Some Swift and Objc can be used

    interchangeably (Remember to import Foundation)
  41. String turns into NSString let myString: NSString = "123"

  42. NSLocalizedString Function into NSLocalizedString Macro

  43. Int, UInt, Float, Double, Bool into NSNumber let n =

    42 let m: NSNumber = n
  44. [AnyObject] into NSArray If casting to NSArray objects have to

    be AnyObject compatible NSArray into [AnyObject] for myItem in foundationArray as [UIView] { // Do whatever you want }
  45. NSDictionary into [NSObject: AnyObject] [NSObject: AnyObject] into NSDictionary Keys and

    values must be instances of a class or bridgeable
  46. [[MyClass alloc] initWithBird:bird]; MyClass(bird: bird) Failable Initialization: init?(...)

  47. CocoaPods

  48. ✅ Objective-C pods in Swift ⬜ Swift pods WIP

  49. With the theory in mind... Moving to Swift advices ✈

  50. Don't touch your Objc code base! (Unless it requires a

    refactor. Do it in Swift)
  51. Most of libraries are in Objc And you can use

    them in Swift! (be patient and don't try to have everything in Swift)
  52. Implement Swift on isolated features • Using Swift features internally

    • With @objc compatible output interface
  53. Swift libraries... when there is no objc option (or you

    have a pure Swift project)
  54. Why?

  55. None
  56. None
  57. None
  58. None
  59. But overall

  60. None
  61. Resources //MARK: - You should read let swiftTypes = "https://github.com/jbrennan/swift-tips/blob/master/swift_tips.md"

    let realmAndObjc = "http://realm.io/news/swift-objc-best-friends-forever" let swiftReady = "http://www.toptal.com/swift/swift-is-it-ready-for-prime-time" let swiftImprovesObjc = "http://spin.atomicobject.com/2014/06/13/swift-improves-objective-c/" //MARK: - Slides let slidesURL = "http://bit.ly/1AaKRfv" println("The slides are available here: \(slidesURL)") //MARK: - Contact let emailURL = NSURL(string: "mailto://pepibumur@gmail.com")! UIApplication.sharedApplication().openURL()
  62. Thanks Doubts?