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

Dancing with Dinosaurs: Objective-C and Swift Interop

Bas Broek
November 18, 2021

Dancing with Dinosaurs: Objective-C and Swift Interop

In this presentation, we meet at an old friend (Objective-C) and how it interacts with its new friend (Swift).

From making our Objective-C code work great with Swift, to making our Swift code available in Objective-C as well; covering things from nullability and (advanced) renaming to option sets and generics.

… and the story behind me “meeting” the Swift programming language.

Bas Broek

November 18, 2021
Tweet

More Decks by Bas Broek

Other Decks in Programming

Transcript

  1. ▸ The Netherlands ▸ Germany ▸ The Netherlands (ish) ▸

    Spain (ish) ▸ Ireland ▸ Rotterdam, the Netherlands 6 — @basthomas, NSSpain, November 2021
  2. BAS ▸ XING Mobile Releases & Platform Team ▸ Apple

    macOS Accessibility ▸ WeTransfer 7 — @basthomas, NSSpain, November 2021
  3. BAS ▸ XING Mobile Releases & Platform Team Objective-C &

    Swift ▸ Apple macOS Accessibility Objective-C ▸ WeTransfer Swift 8 — @basthomas, NSSpain, November 2021
  4. #import <Foundation/Foundation.h> @interface BTBWatch : NSObject - (NSInteger)currentHour; - (NSDate

    *)currentDate; - (BOOL)setTimeWithHours:(NSInteger)hours minutes:(NSInteger)minutes seconds:(NSInteger)seconds error:(NSError **)error; - (void)printCurrentTime; @property (nonatomic) NSString *strapType; @property (nonatomic, readonly) NSArray *functions; @end 14 — @basthomas, NSSpain, November 2021
  5. open class BTBWatch : NSObject { open func currentHour() ->

    Int open func currentDate() -> Date! open func setTimeWithHours(_ hours: Int, minutes: Int, seconds: Int) throws open func printCurrentTime() open var strapType: String! open var functions: [Any]! { get } } 15 — @basthomas, NSSpain, November 2021
  6. open class BTBWatch : NSObject { open func currentHour() ->

    Int open func currentDate() -> Date open func setTimeWithHours(_ hours: Int, minutes: Int, seconds: Int) throws open func printCurrentTime() open var strapType: String open var functions: [Any] { get } } 17 — @basthomas, NSSpain, November 2021
  7. - (NSInteger)currentHour; - (NSDate *)currentDate; @property (nonatomic, readonly) NSInteger currentHour;

    @property (nonatomic, readonly) NSDate *currentDate; 21 — @basthomas, NSSpain, November 2021
  8. open func currentHour() -> Int open func currentDate() -> Date

    open var currentHour: Int { get } open var currentDate: Date { get } 22 — @basthomas, NSSpain, November 2021
  9. NS_ASSUME_NONNULL_BEGIN const NSString *patekPhilippe; const NSString *aLangeSoehne; const NSString *omega;

    const NSString *meisterSinger; NS_SWIFT_NAME(Watch) @interface BTBWatch : NSObject // ... 27 — @basthomas, NSSpain, November 2021
  10. public let patekPhilippe: String public let aLangeSoehne: String public let

    omega: String public let meisterSinger: String 28 — @basthomas, NSSpain, November 2021
  11. NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(Watch.Brand) typedef NSString * WatchBrand NS_TYPED_EXTENSIBLE_ENUM; const WatchBrand patekPhilippe;

    const WatchBrand aLangeSoehne; const WatchBrand omega; const WatchBrand meisterSinger; NS_SWIFT_NAME(Watch) @interface BTBWatch : NSObject // ... 29 — @basthomas, NSSpain, November 2021
  12. extension Watch { public struct Brand : Hashable, Equatable, RawRepresentable

    { public init(_ rawValue: String) public init(rawValue: String) } } extension Watch.Brand { public static let patekPhilippe: Watch.Brand public static let aLangeSoehne: Watch.Brand public static let omega: Watch.Brand public static let meisterSinger: Watch.Brand } 30 — @basthomas, NSSpain, November 2021
  13. typedef NS_OPTIONS(NSInteger, BTBComplication) { BTBComplicationDateWindow = 1 << 0, BTBComplicationPowerReserveIndicator

    = 1 << 1, BTBComplicationChronograph = 1 << 2 } NS_SWIFT_NAME(Watch.Complication); 32 — @basthomas, NSSpain, November 2021
  14. extension Watch { public struct Complication : OptionSet { public

    init(rawValue: Int) public static var dateWindow: Watch.Complication { get } public static var powerReserveIndicator: Watch.Complication { get } public static var chronograph: Watch.Complication { get } } } 33 — @basthomas, NSSpain, November 2021
  15. RECAP ▸ Generated Interfaces ▸ Nullability ▸ (Re)naming ▸ Enums

    and option sets ▸ Lightweight generics 37 — @basthomas, NSSpain, November 2021
  16. enum Bookcase: String { case billy case hemnes case kallax

    } Bookcase.billy.rawValue // "billy" 40 — @basthomas, NSSpain, November 2021
  17. // Bookcase.h // Nothing to be seeen here... 41 —

    @basthomas, NSSpain, November 2021
  18. class Library { let bookcases: [Bookcase?] init(bookcases: [Bookcase?]) { self.bookcases

    = bookcases } } Library(bookcases: [.billy, nil, .kallax, .kallax]) 43 — @basthomas, NSSpain, November 2021
  19. #if defined(__cplusplus) #define let auto const #else #define let const

    __auto_type #endif #if defined(__cplusplus) #define var auto #else #define var __auto_type #endif 49 — @basthomas, NSSpain, November 2021
  20. - (void)fetchShareParticipantWithUserRecordID:(CKRecordID *)userRecordID completionHandler:(void (^)(CKShareParticipant * _Nullable, NSError * _Nullable))completionHandler;

    func fetchShareParticipant( withUserRecordID userRecordID: CKRecord.ID, completionHandler: @escaping (CKShare.Participant?, Error?) -> Void ) func fetchShareParticipant( withUserRecordID userRecordID: CKRecord.ID ) async throws -> CKShare.Participant 53 — @basthomas, NSSpain, November 2021
  21. @objc func perform(operation: String) async -> Int { ... }

    - (void)performWithOperation:(NSString * _Nonnull)operation completionHandler:(void (^ _Nullable)(NSInteger))completionHandler; 54 — @basthomas, NSSpain, November 2021