binary frameworks in swift - apple

236
© 2019 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. #WWDC19 Harlan Haskins, Swift Team Jordan Rose, Swift Team Binary Frameworks in Swift

Upload: others

Post on 02-Jul-2022

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Binary Frameworks in Swift - Apple

© 2019 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

#WWDC19

Harlan Haskins, Swift Team Jordan Rose, Swift Team

•Binary Frameworks in Swift

Page 2: Binary Frameworks in Swift - Apple

Swift Packages

Page 3: Binary Frameworks in Swift - Apple

Swift Packages

Page 4: Binary Frameworks in Swift - Apple

Swift Packages

Dependencies managed by Xcode

Page 5: Binary Frameworks in Swift - Apple

Swift Packages

Dependencies managed by Xcode

Versions managed by Xcode

Page 6: Binary Frameworks in Swift - Apple

Swift Packages

Dependencies managed by Xcode

Versions managed by Xcode

No binary compatibility requirements

Page 7: Binary Frameworks in Swift - Apple

Swift Packages XCFrameworks

Page 8: Binary Frameworks in Swift - Apple

Agenda

Page 9: Binary Frameworks in Swift - Apple

Agenda

•Introducing XCFrameworks

Page 10: Binary Frameworks in Swift - Apple

Agenda

•Introducing XCFrameworks•Creating an XCFramework

Page 11: Binary Frameworks in Swift - Apple

Agenda

•Introducing XCFrameworks•Creating an XCFramework•Framework author considerations

Page 12: Binary Frameworks in Swift - Apple

XCFramework

NEW

Page 13: Binary Frameworks in Swift - Apple

NEW

Page 14: Binary Frameworks in Swift - Apple

NEW

Page 15: Binary Frameworks in Swift - Apple

NEW

Page 16: Binary Frameworks in Swift - Apple

NEW

iOS mac OS

watch OStvOS

Page 17: Binary Frameworks in Swift - Apple

NEW

Page 18: Binary Frameworks in Swift - Apple

NEW

AppKit UIKit

Page 19: Binary Frameworks in Swift - Apple

NEW

Page 20: Binary Frameworks in Swift - Apple

NEW

Page 21: Binary Frameworks in Swift - Apple

NEW

Page 22: Binary Frameworks in Swift - Apple

NEW

Page 23: Binary Frameworks in Swift - Apple

•Demo •Using an XCFramework

Page 24: Binary Frameworks in Swift - Apple

•Using Frameworks

Page 25: Binary Frameworks in Swift - Apple

•Trust

Page 26: Binary Frameworks in Swift - Apple
Page 27: Binary Frameworks in Swift - Apple
Page 28: Binary Frameworks in Swift - Apple
Page 29: Binary Frameworks in Swift - Apple
Page 30: Binary Frameworks in Swift - Apple
Page 31: Binary Frameworks in Swift - Apple
Page 32: Binary Frameworks in Swift - Apple
Page 33: Binary Frameworks in Swift - Apple
Page 34: Binary Frameworks in Swift - Apple

Adopting Swift Packages in Xcode WWDC 2019

Creating Swift Packages WWDC 2019

Page 35: Binary Frameworks in Swift - Apple
Page 36: Binary Frameworks in Swift - Apple

•Creating an XCFramework

Page 37: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 38: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 39: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 40: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 41: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 42: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 43: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 44: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 45: Binary Frameworks in Swift - Apple

New Build Setting in Xcode 11NEW

Build OptionsSetting FlightKit

Build Libraries for Distribution Yes

Page 46: Binary Frameworks in Swift - Apple
Page 47: Binary Frameworks in Swift - Apple

Importing a Module

exec

Page 48: Binary Frameworks in Swift - Apple

Importing a Module

exec

.swiftmoduleFoo.swift

import MyFramework

func doSomething()

Page 49: Binary Frameworks in Swift - Apple

Compiled Module Format

.swiftmodule

Page 50: Binary Frameworks in Swift - Apple

Compiled Module Format

Serialized, binary format

.swiftmodule

Page 51: Binary Frameworks in Swift - Apple

Compiled Module Format

Serialized, binary format

Internal compiler data structures .swiftmodule

Page 52: Binary Frameworks in Swift - Apple

Compiled Module Format

Serialized, binary format

Internal compiler data structures

Changes between compiler versions.swiftmodule

Page 53: Binary Frameworks in Swift - Apple

Swift Module InterfacesNEW

Page 54: Binary Frameworks in Swift - Apple

Swift Module Interfaces

Textual listing of public API

NEW

Page 55: Binary Frameworks in Swift - Apple

Swift Module Interfaces

Textual listing of public API

Compatible across compiler versions

NEW

Page 56: Binary Frameworks in Swift - Apple

Swift Module Interfaces

Textual listing of public API

Compatible across compiler versions

Enabled with “Build Libraries for Distribution”

NEW

Page 57: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 58: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash(

3import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 59: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash(

Page 60: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash(

Page 61: Binary Frameworks in Swift - Apple

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 62: Binary Frameworks in Swift - Apple

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 63: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 64: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 65: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 66: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 67: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 68: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 69: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 70: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 71: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 72: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 73: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

-swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 74: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 75: Binary Frameworks in Swift - Apple

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash( into hasher: inout Swift.Hasher) }.

public struct Location { public var coordinates: FlightKit.Coordinates }.

Page 76: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit

import Swift import UIKit

public class Spaceship { public let name: Swift.String

public init(name: Swift.String) public func fly( to destination: FlightKit.Location, speed: FlightKit.Speed)

@objc deinit }.

public enum Speed: Swift.Hashable { case leisurely case fast

public static func ==( a: FlightKit.Speed, b: FlightKit.Speed) -> Swift.Bool public func hash(

We are using Green highlights here for visual distinction from the blue highlights

on the left

import UIKit

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

Page 77: Binary Frameworks in Swift - Apple

•Building an XCFramework

Page 78: Binary Frameworks in Swift - Apple

Archiving Your Framework

Page 79: Binary Frameworks in Swift - Apple

Archiving Your Framework

Builds framework in Release

Page 80: Binary Frameworks in Swift - Apple

Archiving Your Framework

Builds framework in Release

Available in Xcode Organizer

Page 81: Binary Frameworks in Swift - Apple

Archiving Your Framework

Builds framework in Release

Available in Xcode Organizer

Keeps track of dSYMs

Page 82: Binary Frameworks in Swift - Apple

Archiving Your Framework

xcodebuild archive

Page 83: Binary Frameworks in Swift - Apple

Archiving Your Framework

xcodebuild archive-scheme FlightKit

Page 84: Binary Frameworks in Swift - Apple

Archiving Your Framework

xcodebuild archive-scheme FlightKit-destination "…"-destination "…"

…-destination "…"

Page 85: Binary Frameworks in Swift - Apple

Archiving Your Framework

xcodebuild archive-scheme FlightKit-destination "…"-destination "…"

…-destination "…"SKIP_INSTALL=NO

Page 86: Binary Frameworks in Swift - Apple

Archiving Your Framework

Page 87: Binary Frameworks in Swift - Apple

Archiving Your Framework

Page 88: Binary Frameworks in Swift - Apple

Archiving Your Framework

Page 89: Binary Frameworks in Swift - Apple

Archiving Your Framework

Page 90: Binary Frameworks in Swift - Apple

Building an XCFrameworkNEW

Page 91: Binary Frameworks in Swift - Apple

Building an XCFrameworkNEW

Page 92: Binary Frameworks in Swift - Apple

Building an XCFramework

xcodebuild -create-xcframework

Page 93: Binary Frameworks in Swift - Apple

Building an XCFramework

xcodebuild -create-xcframework-framework [path]-framework [path]

…-framework [path]-output FlightKit.xcframework

Page 94: Binary Frameworks in Swift - Apple

Building an XCFramework

Page 95: Binary Frameworks in Swift - Apple

Building an XCFramework

1. Enable “Build Libraries for Distribution”

Page 96: Binary Frameworks in Swift - Apple

Building an XCFramework

1. Enable “Build Libraries for Distribution”

2. xcodebuild archive

Page 97: Binary Frameworks in Swift - Apple

Building an XCFramework

1. Enable “Build Libraries for Distribution”

2. xcodebuild archive

3. xcodebuild -create-xcframework

Page 98: Binary Frameworks in Swift - Apple

Jordan Rose, Swift Team

•Framework Author Considerations

Page 99: Binary Frameworks in Swift - Apple

•Evolving your framework •Trading flexibility for optimizability •Helping your clients

Page 100: Binary Frameworks in Swift - Apple

Evolving Your Framework

1.0

Page 101: Binary Frameworks in Swift - Apple

Evolving Your Framework

1.01.1

Page 102: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

Page 103: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

Page 104: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

Page 105: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

1.0

1.0

Page 106: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

1.0

1.02.0

Page 107: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

1.0

2.1

Page 108: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

1.01.1

2.1

Page 109: Binary Frameworks in Swift - Apple

Why Is Binary Compatibility Important?

1.01.1

2.1

Page 110: Binary Frameworks in Swift - Apple

Framework Versions

Page 111: Binary Frameworks in Swift - Apple

Framework Versions

Page 112: Binary Frameworks in Swift - Apple

Semantic Versioning semver.org

Page 113: Binary Frameworks in Swift - Apple

Patch Version Bug fixes

1.2.4

Page 114: Binary Frameworks in Swift - Apple

Minor Version Compatible additions

1.2.4

Page 115: Binary Frameworks in Swift - Apple

Major Version Breaking changes (source, binary, semantic)

1.2.4

Page 116: Binary Frameworks in Swift - Apple

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

Page 117: Binary Frameworks in Swift - Apple

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

Page 118: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

Page 119: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public enum Speed { case leisurely case fast }.

public struct Location { public var coordinates: Coordinates }.

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

Page 120: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0

Page 121: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 1.0.0

Page 122: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 1.0.0

Page 123: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 1.0.0

Page 124: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 1.0.1

Page 125: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 1.0.1

Page 126: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 1. .01

Page 127: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 0.1.1

Page 128: Binary Frameworks in Swift - Apple

public class Spaceship { public let name: String private static var defaultLocation: Location? private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = Spaceship.defaultLocation ?? .launchpad }.

public func doABarrelRoll() { // … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

public class Spaceship { public let name: String private var currentLocation: Location

public init(name: String) { self.name = name currentLocation = .launchpad }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

1.0.0 0. .2 0

Page 129: Binary Frameworks in Swift - Apple

// … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public struct Location: Hashable { public var coordinates: Coordinates public var label: String }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

}.public struct Location { public var coordinates: Coordinates

}.

1.0.0 0.0.2

Page 130: Binary Frameworks in Swift - Apple

// … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public struct Location: Hashable { public var coordinates: Coordinates public var label: String }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

}.public struct Location { public var coordinates: Coordinates

}.

1.0.0 0.0.2

Page 131: Binary Frameworks in Swift - Apple

// … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public struct Location: Hashable { public var coordinates: Coordinates public var label: String }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

}.public struct Location { public var coordinates: Coordinates

}.

1.0.0 0.0.2

Page 132: Binary Frameworks in Swift - Apple

// … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public struct Location: Hashable { public var coordinates: Coordinates public var label: String }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

}.public struct Location { public var coordinates: Coordinates

}.

1.0.0 0.0.2

Page 133: Binary Frameworks in Swift - Apple

// … }.

public func fly( to destination: Location, speed: Speed, stealthily: Bool = false) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast case ludicrous }.

public struct Location: Hashable { public var coordinates: Coordinates public var label: String }.

public func fly( to destination: Location, speed: Speed) { currentLocation = destination }. }.

public enum Speed { case leisurely case fast

}.public struct Location { public var coordinates: Coordinates

}.

1.0.0 0.1.2

Page 134: Binary Frameworks in Swift - Apple

Implications for API Design

Page 135: Binary Frameworks in Swift - Apple

Implications for API Design

Keep your interface small — easy to add, hard to remove!

Page 136: Binary Frameworks in Swift - Apple

Implications for API Design

Keep your interface small — easy to add, hard to remove!

Choose names and requirements carefully

Page 137: Binary Frameworks in Swift - Apple

Implications for API Design

Keep your interface small — easy to add, hard to remove!

Choose names and requirements carefully

Avoid unnecessary extensibility (open classes, arbitrary callbacks, etc.)

Page 138: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection at module boundaries

public class Spaceship { public init() public func fly( to destination: Location, speed: Speed) }

Page 139: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection at module boundaries

public class Spaceship { public init() public func fly( to destination: Location, speed: Speed) }

spaceship.fly(to: home, speed: .fast)

Page 140: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection at module boundaries

public class Spaceship { public init() public func fly( to destination: Location, speed: Speed) }

spaceship.fly(to: home, speed: .fast)

fly(to:speed:)?

Page 141: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection at module boundaries

public class Spaceship { public init() public func fly( to destination: Location, speed: Speed) }

spaceship.fly(to: home, speed: .fast)

Method #2!

fly(to:speed:)?

Page 142: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection when clients use the framework’s structs and enums

public enum Speed { case leisurely case fast }

spaceship.fly(to: home, speed: .fast)

Page 143: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection when clients use the framework’s structs and enums

public enum Speed { case leisurely case fast }

spaceship.fly(to: home, speed: .fast)

Page 144: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection when clients use the framework’s structs and enums

public enum Speed { case leisurely case fast }

spaceship.fly(to: home, speed: .fast)

How big?

Page 145: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection when clients use the framework’s structs and enums

public enum Speed { case leisurely case fast }

spaceship.fly(to: home, speed: .fast)

1 byte!

How big?

Page 146: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection when clients use the framework’s structs and enums

public enum Speed { case leisurely case fast }

Clean it up!

spaceship.fly(to: home, speed: .fast)

Page 147: Binary Frameworks in Swift - Apple

Behind the Scenes Extra indirection when clients use the framework’s structs and enums

public enum Speed { case leisurely case fast }

Okay!

Clean it up!

spaceship.fly(to: home, speed: .fast)

Page 148: Binary Frameworks in Swift - Apple

•Trading Flexibility for Optimizability

Page 149: Binary Frameworks in Swift - Apple

Flexibility Optimizability

Page 150: Binary Frameworks in Swift - Apple

Flexibility Optimizability

Page 151: Binary Frameworks in Swift - Apple

Flexibility Optimizability

Build OptionsSetting FlightKit

Build Libraries for Distribution Yes

Page 152: Binary Frameworks in Swift - Apple

Flexibility Optimizability

Build OptionsSetting FlightKit

Build Libraries for Distribution Yes

Page 153: Binary Frameworks in Swift - Apple

Flexibility Optimizability

Build OptionsSetting FlightKit

Build Libraries for Distribution Yes

Page 154: Binary Frameworks in Swift - Apple

@inlinable functions

@frozen enums

@frozen structs

Flexibility Optimizability

Page 155: Binary Frameworks in Swift - Apple

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }.

Page 156: Binary Frameworks in Swift - Apple

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }.

Page 157: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass> }

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }.

Page 158: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass> }

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }.

Page 159: Binary Frameworks in Swift - Apple

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass> }

Page 160: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass> }

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }

Page 161: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass> }

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }

Page 162: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass> }

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }

cargo.mass <= self.capacity

Page 163: Binary Frameworks in Swift - Apple

“But what happens if I change it?”

Page 164: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass> }.

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }.

cargo.mass <= self.capacity

Page 165: Binary Frameworks in Swift - Apple

// swift-interface-format-version: 1.0 // swift-compiler-version: Swift version 5.1 // swift-module-flags: -target arm64-apple-ios13.0 -enable-library-evolution -swift-version 5 -O -module-name FlightKit public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity }.

@usableFromInline internal var capacity: Measurement<UnitMass> }.

public class CargoShip: Spaceship { @inlinable public func canCarry( _ cargo: Cargo) -> Bool { return cargo.mass <= self.capacity && !cargo.isRadioactive }.

@usableFromInline internal var capacity: Measurement<UnitMass>

internal var currentCargo: Cargo? }.

cargo.mass <= self.capacity

Page 166: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 167: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

📦

Page 168: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

📦

Page 169: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

📦

Page 170: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

📦

Page 171: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 172: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 173: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 174: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 175: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 176: Binary Frameworks in Swift - Apple

cargo.mass <= self.capacity &&

!cargo.isRadioactive

cargo.mass <= self.capacity

Page 177: Binary Frameworks in Swift - Apple

Changing an @inlinable Function

Rule of thumb — don’t change the output or observable behavior • Better algorithms are okay

Page 178: Binary Frameworks in Swift - Apple

@frozen Enums

public enum FlightPlanKind {. case oneWay case roundTrip }.

Page 179: Binary Frameworks in Swift - Apple

@frozen Enums

public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

Page 180: Binary Frameworks in Swift - Apple

@frozen Enums

public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

Page 181: Binary Frameworks in Swift - Apple

@frozen Enums

public enum FlightPlanKind {. case oneWay case roundTrip }.

How big?

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

Page 182: Binary Frameworks in Swift - Apple

@frozen Enums

public enum FlightPlanKind {. case oneWay case roundTrip }.

1 byte!

How big?

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

Page 183: Binary Frameworks in Swift - Apple

@frozen Enums

public enum FlightPlanKind {. case oneWay case roundTrip }.

1 byte!

How big?

Clean it up!

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

Page 184: Binary Frameworks in Swift - Apple

@frozen Enums

@frozen public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

NEW

Page 185: Binary Frameworks in Swift - Apple

@frozen Enums

@frozen public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

NEW

Page 186: Binary Frameworks in Swift - Apple

@frozen Enums

Promise not to add new cases

@frozen public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

NEW

Page 187: Binary Frameworks in Swift - Apple

@frozen Enums

Promise not to add new cases

Clients won’t write default in switches

@frozen public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") @unknown default: print("Have a good flight!") }.

NEW

Page 188: Binary Frameworks in Swift - Apple

@frozen Enums

Promise not to add new cases

Clients won’t write default in switches

@frozen public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") }.

NEW

Page 189: Binary Frameworks in Swift - Apple

@frozen Enums

Promise not to add new cases

Clients won’t write default in switches

Better performance, especially when no cases have associated values

@frozen public enum FlightPlanKind {. case oneWay case roundTrip }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") }.

NEW

Page 190: Binary Frameworks in Swift - Apple

Changing @frozen Enums

@frozen public enum FlightPlanKind {. case oneWay case roundTrip case multiHop([Location]) }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") }.

Page 191: Binary Frameworks in Swift - Apple

Changing @frozen Enums

@frozen public enum FlightPlanKind {. case oneWay case roundTrip case multiHop([Location]) }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") }.

Page 192: Binary Frameworks in Swift - Apple

Changing @frozen Enums

2.1.0

@frozen public enum FlightPlanKind {. case oneWay case roundTrip case multiHop([Location]) }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") }.

Page 193: Binary Frameworks in Swift - Apple

Changing @frozen Enums

3.0.0

@frozen public enum FlightPlanKind {. case oneWay case roundTrip case multiHop([Location]) }.

switch kind {. case .oneWay: print("See you there!") case .roundTrip: print("See you in a few weeks!") }.

Page 194: Binary Frameworks in Swift - Apple

@frozen Structs

public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

Page 195: Binary Frameworks in Swift - Apple

@frozen Structs

public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

How big?

Page 196: Binary Frameworks in Swift - Apple

@frozen Structs

public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

24 bytes!

How big?

Page 197: Binary Frameworks in Swift - Apple

@frozen Structs

public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

24 bytes!

How big?

Clean it up!

Page 198: Binary Frameworks in Swift - Apple

@frozen Structs

@frozen public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

NEW

Page 199: Binary Frameworks in Swift - Apple

@frozen Structs

@frozen public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

NEW

Page 200: Binary Frameworks in Swift - Apple

@frozen Structs

Promise not to add or reorder stored properties

@frozen public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

NEW

Page 201: Binary Frameworks in Swift - Apple

@frozen Structs

Promise not to add or reorder stored properties

Types of stored properties must be public or @usableFromInline

@frozen public struct Coordinates {. public var radius, azimuth, inclination: Double public init(r: Double, alpha: Double, theta: Double) {…} }.

NEW

Page 202: Binary Frameworks in Swift - Apple

@frozen Structs

Promise not to add or reorder stored properties

Types of stored properties must be public or @usableFromInline

Allows inlinable initializers

@frozen public struct Coordinates {. public var radius, azimuth, inclination: Double @inlinable public init(r: Double, alpha: Double, theta: Double) {…} }.

NEW

Page 203: Binary Frameworks in Swift - Apple

@frozen Structs

Promise not to add or reorder stored properties

Types of stored properties must be public or @usableFromInline

Allows inlinable initializers

@frozen public struct Coordinates {. public var radius, azimuth, inclination: Double @inlinable public init(r: Double, alpha: Double, theta: Double) {…} }.

NEW

Page 204: Binary Frameworks in Swift - Apple

Flexibility Is the Default

Page 205: Binary Frameworks in Swift - Apple

Flexibility Is the Default

Breaking changes are inconvenient

Page 206: Binary Frameworks in Swift - Apple

Flexibility Is the Default

Breaking changes are inconvenient

These attributes only affect client code

Page 207: Binary Frameworks in Swift - Apple

Flexibility Is the Default

Breaking changes are inconvenient

These attributes only affect client code

Profile before reaching for @inlinable or @frozen

Page 208: Binary Frameworks in Swift - Apple

•Helping Your Clients

Page 209: Binary Frameworks in Swift - Apple

Entitlements

Page 210: Binary Frameworks in Swift - Apple

Entitlements

Page 211: Binary Frameworks in Swift - Apple

Entitlements

Document your requirements

Page 212: Binary Frameworks in Swift - Apple

Entitlements

Document your requirements

Minimize entitlement requests

Page 213: Binary Frameworks in Swift - Apple

Entitlements

Document your requirements

Minimize entitlement requests

Handle denial gracefully

Page 214: Binary Frameworks in Swift - Apple

Dependencies

Page 215: Binary Frameworks in Swift - Apple

Dependencies

Page 216: Binary Frameworks in Swift - Apple

Dependencies

Document your dependencies

Page 217: Binary Frameworks in Swift - Apple

Dependencies

Document your dependencies

Minimize your dependencies

Page 218: Binary Frameworks in Swift - Apple

Dependencies

Document your dependencies

Minimize your dependencies

Dependencies must use“Build Libraries for Distribution”

Page 219: Binary Frameworks in Swift - Apple

Binary Frameworks Cannot Depend on Packages

Page 220: Binary Frameworks in Swift - Apple

Binary Frameworks Cannot Depend on Packages

Page 221: Binary Frameworks in Swift - Apple

Binary Frameworks Cannot Depend on Packages

Page 222: Binary Frameworks in Swift - Apple

Binary Frameworks Cannot Depend on Packages

2.3.0

Page 223: Binary Frameworks in Swift - Apple

Binary Frameworks Cannot Depend on Packages

1.0.5

2.3.0

Page 224: Binary Frameworks in Swift - Apple

Your Objective-C Interface

@import FlightKit;

Page 225: Binary Frameworks in Swift - Apple

Your Objective-C Interface

@import FlightKit;

FlightKit.h FlightKit-Swift.h

Page 226: Binary Frameworks in Swift - Apple

If Your Swift Code Has No Objective-C API

@import FlightKit;

FlightKit.h FlightKit-Swift.h

Page 227: Binary Frameworks in Swift - Apple

If Your Swift Code Has No Objective-C API

@import FlightKit;

FlightKit.h FlightKit-Swift.h

Page 228: Binary Frameworks in Swift - Apple

If Your Swift Code Has No Objective-C API

@import FlightKit;

FlightKit.h

Page 229: Binary Frameworks in Swift - Apple

If Your Framework Has No Objective-C API

@import FlightKit;

FlightKit.h

Page 230: Binary Frameworks in Swift - Apple

If Your Framework Has No Objective-C API

@import FlightKit;

FlightKit.h

Page 231: Binary Frameworks in Swift - Apple

If Your Framework Has No Objective-C API

@import FlightKit;

FlightKit.h

Page 232: Binary Frameworks in Swift - Apple

If Your Framework Has No Objective-C API

@import FlightKit;

Page 233: Binary Frameworks in Swift - Apple

•Summary

Page 234: Binary Frameworks in Swift - Apple

Summary

XCFrameworks — for distributing multiple framework variants

“Build Libraries for Distribution” build setting

Framework owners — know your responsibilities

Page 235: Binary Frameworks in Swift - Apple

More Informationdeveloper.apple.com/wwdc19/416

Swift Open Hours Thursday, 3:00

Building, Signing, and Distributing Lab Friday, 9:00

Page 236: Binary Frameworks in Swift - Apple