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

Avatar for Pedro Piñera Buendía

Pedro Piñera Buendía

December 09, 2014
Tweet

More Decks by Pedro Piñera Buendía

Other Decks in Technology

Transcript

  1. 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()
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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") } }
  7. 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
  8. 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)") }
  9. 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 } }
  10. Closures & Blocks Fully compatible The only difference is that

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

    ^void() { NSLog(@"%@", myObject); }; Swift let customObject: MyObject = MyObject() let myBlock: () -> () = { in println("\(customObject)") }
  12. @objc @objc(ObjcCat) class SwiftCat { @objc(initWithName:) init (name: String) {

    /*...*/ } } @objc is inferred if it's a NSObject subclass
  13. 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 }
  14. 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 }
  15. Cocoa Data Types Some Swift and Objc can be used

    interchangeably (Remember to import Foundation)
  16. [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 }
  17. Most of libraries are in Objc And you can use

    them in Swift! (be patient and don't try to have everything in Swift)
  18. 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://[email protected]")! UIApplication.sharedApplication().openURL()