Streaming is available in most browsers,
and in the Developer app.
-
A Swift Tour: Explore Swift’s features and design
Learn the essential features and design philosophy of the Swift programming language. We'll explore how to model data, handle errors, use protocols, write concurrent code, and more while building up a Swift package that has a library, an HTTP server, and a command line client. Whether you're just beginning your Swift journey or have been with us from the start, this talk will help you get the most out of the language.
Chapters
- 0:00 - Introduction
- 0:51 - Agenda
- 1:05 - The example
- 1:32 - Value types
- 4:26 - Errors and optionals
- 9:47 - Code organization
- 11:58 - Classes
- 14:06 - Protocols
- 18:33 - Concurrency
- 23:13 - Extensibility
- 26:55 - Wrap up
Resources
- Forum: Programming Languages
- The Swift Programming Language
- Tools used: Ubuntu
- Tools used: Visual Studio Code
- Tools used: Windows
- Value and Reference types
- Wrapping C/C++ Library in Swift
Related Videos
WWDC23
WWDC22
WWDC21
-
DownloadArray
-
-
1:49 - Integer variables
var x: Int = 1 var y: Int = x x = 42 y
-
3:04 - User struct
struct User { let username: String var isVisible: Bool = true var friends: [String] = [] } var alice = User(username: "alice") alice.friends = ["charlie"] var bruno = User(username: "bruno") bruno.friends = alice.friends alice.friends.append("dash") bruno.friends
-
3:05 - User struct error handling
struct User { let username: String var isVisible: Bool = true var friends: [String] = [] mutating func addFriend(username: String) throws { guard username != self.username else { throw SocialError.befriendingSelf } guard !friends.contains(username) else { throw SocialError.duplicateFriend(username: username) } friends.append(username) } } enum SocialError: Error { case befriendingSelf case duplicateFriend(username: String) } var alice = User(username: "alice") do { try alice.addFriend(username: "charlie") try alice.addFriend(username: "charlie") } catch { error } var allUsers = [ "alice": alice ] func findUser(_ username: String) -> User? { allUsers[username] } if let charlie = findUser("charlie") { print("Found \(charlie)") } else { print("charlie not found") } let dash = findUser("dash")!
-
11:01 - SocialGraph package manifest
// swift-tools-version: 6.0 import PackageDescription let package = Package( name: "SocialGraph", products: [ .library( name: "SocialGraph", targets: ["SocialGraph"]), ], dependencies: [ .package(url: "https://github.com/apple/swift-testing.git", branch: "main"), ], targets: [ .target( name: "SocialGraph"), .testTarget( name: "SocialGraphTests", dependencies: [ "SocialGraph", .product(name: "Testing", package: "swift-testing"), ]), ] )
-
11:12 - User struct
/// Represents a user in the social graph. public struct User: Equatable, Hashable { /// The user's username, which must be unique in the service. public let username: String /// Whether or not the user should be considered visible /// when performing queries. public var isVisible: Bool /// The usernames of the user's friends. public private(set) var friends: [String] public init( username: String, isVisible: Bool = true, friends: [String] = [] ) { self.username = username self.isVisible = isVisible self.friends = friends } /// Adds a username to the user's list of friends. Throws an /// error if the username cannot be added. public mutating func addFriend(username: String) throws { guard username != self.username else { throw SocialError.befriendingSelf } guard !friends.contains(username) else { throw SocialError.alreadyFriend(username: username) } friends.append(username) } }
-
12:36 - Classes
class Pet { func speak() {} } class Cat: Pet { override func speak() { print("meow") } func purr() { print("purr") } } let pet: Pet = Cat() pet.speak() if let cat = pet as? Cat { cat.purr() }
-
12:59 - Automatic reference counting
class Pet { var toy: Toy? } class Toy {} let toy = Toy() let pets = [Pet()] // Give toy to pets for pet in pets { pet.toy = toy } // Take toy from pets for pet in pets { pet.toy = nil }
-
13:26 - Reference cycles
class Pet { weak var owner: Owner? } class Owner { var pets: [Pet] }
-
14:20 - Protocols
protocol StringIdentifiable { var identifier: String { get } } extension User: StringIdentifiable { var identifier: String { username } }
-
15:21 - Common capabilities of Collections
let string = "🥚🐣🐥🐓" for char in string { print(char) } // => "🥚" "🐣" "🐥" "🐓" print(string[string.startIndex]) // => "🥚"
-
15:31 - Collection algorithms
let numbers = [1, 4, 7, 10, 13] let numberStrings = numbers.map { number in String(number) } // => ["1", "4", "7", "10", "13"] let primeNumbers = numbers.filter { number in number.isPrime } // => [1, 7, 13] let sum = numbers.reduce(0) { partial, number in partial + number } // => 35
-
15:45 - Collection algorithms with anonymous parameters
let numbers = [1, 4, 7, 10, 13] let numberStrings = numbers.map { String($0) } // => ["1", "4", "7", "10", "13"] let primeNumbers = numbers.filter { $0.isPrime } // => [1, 7, 13] let sum = numbers.reduce(0) { $0 + $1 } // => 35
-
16:13 - Friends of friends algorithm
/// An in-memory store for users of the service. public class UserStore { var allUsers: [String: User] = [:] } extension UserStore { /// If the username maps to a User and that user is visible, /// returns the User. Returns nil otherwise. public func lookUpUser(_ username: String) -> User? { guard let user = allUsers[username], user.isVisible else { return nil } return user } /// If the username maps to a User and that user is visible, /// returns the User. Otherwise, throws an error. public func user(for username: String) throws -> User { guard let user = lookUpUser(username) else { throw SocialError.userNotFound(username: username) } return user } public func friendsOfFriends(_ username: String) throws -> [String] { let user = try user(for: username) let excluded = Set(user.friends + [username]) return user.friends .compactMap { lookUpUser($0) } // [String] -> [User] .flatMap { $0.friends } // [User] -> [String] .filter { !excluded.contains($0) } // drop excluded .uniqued() } } extension Collection where Element: Hashable { func uniqued() -> [Element] { let unique = Set(self) return Array(unique) } }
-
19:23 - async/await
/// Makes a network request to download an image. func fetchUserAvatar(for username: String) async -> Image { // ... } let avatar = await fetchUserAvatar(for: "alice")
-
19:43 - Server
import Hummingbird import SocialGraph let router = Router() extension UserStore { static let shared = UserStore.makeSampleStore() } let app = Application( router: router, configuration: .init(address: .hostname("127.0.0.1", port: 8080)) ) print("Starting server...") try await app.runService()
-
20:20 - Data race example
// Look up user let user = allUsers[username] // Store new user allUsers[username] = user // UserStore var allUsers: [String: User]
-
22:24 - Server with friendsOfFriends route
import Hummingbird import SocialGraph let router = Router() extension UserStore { static let shared = UserStore.makeSampleStore() } router.get("friendsOfFriends") { request, context -> [String] in let username = try request.queryArgument(for: "username") return try await UserStore.shared.friendsOfFriends(username) } let app = Application( router: router, configuration: .init(address: .hostname("127.0.0.1", port: 8080)) ) print("Starting server...") try await app.runService()
-
23:27 - Property wrappers
struct FriendsOfFriends: AsyncParsableCommand { @Argument var username: String mutating func run() async throws { // ... } }
-
23:57 - SocialGraph command line client
import ArgumentParser import SocialGraph @main struct SocialGraphClient: AsyncParsableCommand { static let configuration = CommandConfiguration( abstract: "A utility for querying the social graph", subcommands: [ FriendsOfFriends.self, ]) } struct FriendsOfFriends: AsyncParsableCommand { @Argument(help: "The username to look up friends of friends for") var username: String func run() async throws { var request = Request(command: "friendsOfFriends", returning: [String].self) request.arguments = ["username" : username] let result = try await request.get() print(result) } }
-
26:07 - Result builders
import RegexBuilder let dollarValueRegex = Regex { // Equivalent to "\$[0-9]+\.[0-9][0-9]" "$" OneOrMore(.digit) "." Repeat(.digit, count: 2) }
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.