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

Dancing with Dinosaurs: Objective-C and Swift I...

Avatar for Bas Broek 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.

Avatar for Bas Broek

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