View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Todos los videos
  • Información

Más videos

  • Información
  • Código
  • Refine Objective-C frameworks for Swift

    Fine-tune your Objective-C headers to work beautifully in Swift. We'll show you how to take an unwieldy Objective-C framework and transform it into an API that feels right at home. Learn about the suite of annotations you can use to provide richer type information, more idiomatic names, and better errors to Swift. And discover Objective-C conventions you might not have known about that are key to a well-behaved Swift API.

    To get the most out of this session, you should be familiar with Swift and Objective-C.

    For more on working with Swift and Objective-C, check out our Developer Documentation and take a look at “Behind the Scenes of the Xcode Build Process” from WWDC18.

    Recursos

    • Objective-C and C Code Customization
      • Video HD
      • Video SD
  • Buscar este video…
    • 4:43 - Describe nullability to control optionals (method and property annotations)

      //
      // SKMission.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      @interface SKMission : NSObject
      
      @property (readonly, nullable) NSString *name;
      
      - (nonnull instancetype)initWithName:(nullable NSString *)name;
      
      @end
    • 6:53 - Describe nullability to control optionals (ASSUME_NONNULL blocks)

      //
      // SKMission.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKMission : NSObject
      
      @property (readonly, nullable) NSString *name;
      
      - (instancetype)initWithName:(nullable NSString *)name;
      
      @end
      
      NS_ASSUME_NONNULL_END
    • 7:14 - Describe nullability to control optionals (qualifiers)

      //
      // Misc.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NSString * _Nonnull const SKRocketSaturnV;
      
      @interface ResourceValueContainer : NSObject
      
      - (BOOL)getResourceValue:(id _Nullable * _Nonnull)outValue error:(NSError**)error;
      
      @end
    • 8:09 - Finding nullability mistakes with Objective-C tools

      //
      // SKMission.h
      //
      
      #import <Foundation/Foundation.h>
      
      @interface SKMission : NSObject
      
      @property (strong, nonnull) NSString *rocket;
      @property (strong, nonnull) NSString *capsule;
      
      @end
      
      //
      // SKRocket.h
      //
      
      #import <Foundation/Foundation.h>
      
      extern NSString *_Nonnull const SKRocketSaturnV;
      
      // 
      // SKMission.m
      //
      // Try building this file and then try analyzing it.
      //
      
      #import "SKRocket.h"
      #import "SKMission.h"
      
      @implementation SKMission @end
      
      @interface SKMissionConfigurator : NSObject
      
      @property (strong, nullable) SKMission *mission;
      
      @end
      
      @implementation SKMissionConfigurator
      
      - (void)testBadUseWithWarning {
          [self.mission setCapsule:nil];
      }
      
      - (void)testBadUseWithStaticAnalyzer:(BOOL)missionIsSkylab1 {
          NSString *capsule = nil;
      
          if (!missionIsSkylab1) {
              capsule = SKCapsuleApolloCSM;
          }
          
          self.mission.capsule = capsule;
      }
      
      @end
    • 11:07 - Use Objective-C generics for Foundation types

      //
      // SKAstronaut.h
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKAstronaut : NSObject
      // Stub declaration
      @end
      
      NS_ASSUME_NONNULL_END
      
      //
      // SKMission.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      #import <SpaceKit/SKAstronaut.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKMission : NSObject
      
      @property (readonly) NSArray<SKAstronaut *> *crew;
      
      @end
      
      NS_ASSUME_NONNULL_END
    • 11:33 - Use Int for numbers—unsigned types are for bitwise operations

      //
      // SKRocket.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      NSInteger SKRocketStageCount(NSString *);
      
      NS_ASSUME_NONNULL_END
      
      //
      // NSData+xor.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      @interface NSData (xor)
      
      - (void)xorWithByte:(uint8_t)value;
      
      @end
    • 13:23 - Strengthen stringly-typed constants

      //
      // SKRocket.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      typedef NSString *SKRocket NS_STRING_ENUM;
      
      extern SKRocket const SKRocketAtlas;
      extern SKRocket const SKRocketTitanII;
      extern SKRocket const SKRocketSaturnIB;
      extern SKRocket const SKRocketSaturnV;
      
      NSInteger SKRocketStageCount(SKRocket);
      
      NS_ASSUME_NONNULL_END
    • 15:24 - Specify initializer behavior

      //
      // SKAstronaut.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKAstronaut : NSObject
      
      - (instancetype)initWithNameComponents:(NSPersonNameComponents *)name NS_DESIGNATED_INITIALIZER;
      - (instancetype)initWithName:(NSString *)name;
      - (instancetype)init NS_UNAVAILABLE;
      
      @property (strong, readwrite) NSPersonNameComponents *nameComponents;
      @property (readonly) NSString *name;
      
      @end
      
      NS_ASSUME_NONNULL_END
      
      // 
      // SKAstronaut.m
      // 
      
      #import "SKAstronaut.h"
      
      @interface SKAstronaut ()
      @property (class, readonly, strong) NSPersonNameComponentsFormatter *nameFormatter;
      @end
      
      @implementation SKAstronaut
      
      - (id)initWithNameComponents:(NSPersonNameComponents *)name {
          self = [super init];
          if (self) {
              _name = name;
          }
          return self;
      }
      
      - (id)initWithName:(NSString *)name {
          return [self initWithNameComponents:[SKAstronaut _componentsFromName:name]];
      }
      
      - (id)init {
        [self doesNotRecognizeSelector:_cmd];
        return nil;
      }
      
      - (NSString *)name {
          return [SKAstronaut.nameFormatter stringFromPersonNameComponents:self.nameComponents];
      }
      
      + (NSPersonNameComponents*)_componentsFromName:(NSString*)name {
          return [self.nameFormatter personNameComponentsFromString:name];
      }
      
      + (NSPersonNameComponentsFormatter *)nameFormatter {
          static NSPersonNameComponentsFormatter *singleton;
          static dispatch_once_t onceToken;
          dispatch_once(&onceToken, ^{
              singleton = [NSPersonNameComponentsFormatter new];
          });
          return singleton;
      }
      
      @end
    • 20:00 - Follow the error handling convention

      //
      // SKMission.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKMission : NSObject
      
      /// \returns \c YES if saved; \c NO with non-nil \c *error if failed to save;
      ///          \c NO with nil \c *error` if nothing needed to be saved.
      - (BOOL)saveToURL:(NSURL *)url error:(NSError **)error NS_SWIFT_NOTHROW DEPRECATED_ATTRIBUTE;
      
      /// @param[out] wasDirty If provided, set to \c YES if the file needed to be
      ///   saved or \c NO if there weren’t any changes to save.
      - (BOOL)saveToURL:(NSURL *)url wasDirty:(nullable BOOL *)wasDirty error:(NSError **)error;
      
      @end
      
      NS_ASSUME_NONNULL_END
    • 22:40 - Refine an Objective-C API for Swift users

      //
      // SKMission.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKMission : NSObject
      
      /// \returns \c YES if saved; \c NO with non-nil \c *error if failed to save;
      ///          \c NO with nil \c *error` if nothing needed to be saved.
      - (BOOL)saveToURL:(NSURL *)url error:(NSError **)error NS_SWIFT_NOTHROW DEPRECATED_ATTRIBUTE;
      
      /// @param[out] wasDirty If provided, set to \c YES if the file needed to be
      ///   saved or \c NO if there weren’t any changes to save.
      - (BOOL)saveToURL:(NSURL *)url wasDirty:(nullable BOOL *)wasDirty error:(NSError **)error NS_REFINED_FOR_SWIFT;
      
      @end
      
      NS_ASSUME_NONNULL_END
      
      // 
      // SwiftExtensions.swift
      //
      
      import Foundation
      
      extension SKMission {
          public func save(to url: URL) throws -> Bool {
              var wasDirty: ObjCBool = false
              try self.__save(to: url, wasDirty: &wasDirty)
              return wasDirty.boolValue
          }
      }
    • 31:35 - Fix method names with NS_SWIFT_NAME

      //
      // SKMission.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      #import <SKAstronaut/SKAstronaut.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKMission : NSObject
      
      - (NSSet<SKMission *> *)previousMissionsFlownByAstronaut:(SKAstronaut *)astronaut NS_SWIFT_NAME(previousMissions(flownBy:));
      
      @end
    • 33:12 - Rename and rework value types with NS_SWIFT_NAME

      //
      // SKFuelKind.h
      //
      // View the generated interface to see how Swift imports this header.
      //
      
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface SKFuel : NSObject
      // Stub class
      @end
      
      typedef NS_ENUM(NSInteger, SKFuelKind) {
          SKFuelKindH2 = 0,
          SKFuelKindCH4 = 1,
          SKFuelKindC12H26 = 2
      } NS_SWIFT_NAME(SKFuel.Kind);
      
      NSString *SKFuelKindToNSString(SKFuelKind kind)
          NS_SWIFT_NAME(getter:SKFuelKind.description(self:));
    • 35:59 - Add conformances to Objective-C types using custom Swift code

      extension SKFuel.Kind: CustomStringConvertible {}
    • 37:02 - Improve error code enums

      //
      //  SKError.h
      //  SpaceKit
      //
      
      #import <Foundation/Foundation.h>
      
      extern NSString *const SKErrorDomain;
      
      typedef NS_ERROR_ENUM(SKErrorDomain, SKErrorCode) {
          SKErrorLaunchAborted = 1,
          SKErrorLaunchOutOfRange,
          SKErrorRapidUnscheduledDisassembly,
          SKErrorNotGoingToSpaceToday
      };

Developer Footer

  • Videos
  • WWDC20
  • Refine Objective-C frameworks for Swift
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines