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
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()