Home


How to enable an upcoming compiler feature

Instead of:

.unsafeFlags(["-enable-upcoming-feature", "NonisolatedNonsendingByDefault"])  
  

Use:

.enableUpcomingFeature("NonisolatedNonsendingByDefault")  

Testing Package.swift changes

I’ve found that Xcode will just silently let invalid Package.swift build.
Instead, make changes and then:

sudo xcode-select -switch /Applications/Xcode-version.app  
swift package resolve  
swift build  

NonisolatedNonsending

Introduced in Swift 6.2, -enable-upcoming-feature  
NonisolatedNonsendingByDefault changes the execution semantics of nonisolated  
async functions to always run on the caller’s actor by default. A new  
@concurrent attribute can be added in order to specify that a function must  
always switch off of an actor to run.  

Source: https://docs.swift.org/compiler/documentation/diagnostics/nonisolated-nonsending-by-default/

Sendable gotcha

Don’t assume that reference types should be sendable. Instead, try to remove concurrency.
Try to prevent them from crossing isolation boundaries in the first place.

Refernces:
https://youtu.be/N5iIXwBW54A?t=1205
and 20:30 here: https://developer.apple.com/videos/play/wwdc2025/268/

Trick to satisfy “main actor-isolated property can not be referenced from a Sendable closure”

Create a copy of the value I need in the closure’s capture list. E.g.

@MainActor  
struct MyView: View {  
    @State private var pulse = false  
    var body: some View {  
        Text("hi")  
            .visualEffect { [pulse] content, _ in   
                content.blur(radius: pulse ? 2 : 0)  
            }  
    }  
}  

Example from “Explore concurrency in SwiftUI” 2025

Taskgroup 101

await withTaskGroup { group in
for thing in things {
group.addTask {
return await expensiveWork(on: thing)
}
}
for await result in group {
// Do something with each result
}
}

Example from “Elevate an app with Swift concurrency” 2025

Modern way to move parallel work to background thread (Swift 6)

Script to demonstrate @concurrent nonisolated. Note that f and g
are not marked async, yet I can async let them.

@concurrent  
nonisolated func foo() async -> Int {  
    async let f = f()  
    async let g = g()  
    return await f + g  
}  

func f() -> Int {  
    print(Thread.current)  
    return 1  
}  
func g() -> Int {  
    print(Thread.current)  
    return 2  
}  

Task {  
    print(await foo()) // Prints 3  
}  

RunLoop.current.run()  

I opened a question about this here: https://forums.swift.org/t/using-async-let-with-synchronous-functions/81907

Naming free functions

In swift they are called ‘module-scoped’ functions

nonisolated confusion, Concurrency gotcha

nonisolated isn’t a hint to the compiler that the function isn’t protected!

This is all the swift book has to say about nonisolated:

Actors can also have nonisolated members,  
whose declarations are marked with the `nonisolated` keyword.  
A nonisolated member executes like code outside of the actor:  
It can't interact with any of the actor's isolated state,  
and callers don't mark it with `await` when using it.  

This is inconsistent with Doug Gregor’s take in “Embracing Swift Concurrency” wwdc 2025:

nonisolated code is very flexible, because you can call it from anywhere.  
If you call it from the main actor, it will stay on the main actor. If you  
call it from a background thread, it will stay on a background thread.  

And Massicotte’s understanding is that marking an async function
nonisolated and calling it from the main actor guarantees that it will not be
run on the MainActor. I’m not sure if that conclusion is warranted.

In my tests, though, it seems to be true but you have to follow the pattern
of making the _go() function async. I.e. you can’t just mark the function nonisolated
and expect it to run off the main thread
.

@MainActor  
final class C {  
    func go() {  
        Task {  
            await expensive()  
        }  
    }  
    nonisolated func expensive() async {  
        MainActor.assertIsolated()  // Traps, as we want  
    }  
}  

In his article, he says: “we’ve now made a function that is guaranteed to not be on the MainActor”
https://www.massicotte.org/step-by-step-network-request

There is one addition that 2025 session “Elevate an app with swift concurrency” makes at min 14.
Instead of nonisolated she uses @concurrent nonisolated, which removes the ambiguity.

Note that @concurrent requires that the fn is async (which expensive is).
I.e. I can have nonisolated func fn() but not @concurrent nonisolated fn().

When to use TaskGroup

await withTaskGroup is structured concurrency, just like async let.
Use it instead of Task and Task.detached if possible.

When to use:
- Known number of child concurrent tasks -> Use async let
- Unknown/dynamic number of child concurrent tasks -> Use TaskGroup

Tasks inherit the isolation of the type they are defined in

Tasks do inherit actor isolation. Task.detached do not:

@MainActor
class C {
var thisIsIsolated = “hi”
func f() {
Task {
print(self.thisIsIsolated) // No need to await here. On the main executor
MainActor.assertIsolated()
}

    Task.detached {  
        print(self.thisIsIsolated) // Throws a compiler error  
        MainActor.assertIsolated() // Traps at runtime  
    }  
}  

}

https://stackoverflow.com/questions/78826226/swift-concurrency-why-my-task-didnt-inherit-the-parent-tasks-executor-and-pr

Rob says “And note that in Task {…} in viewDidLoad, the @MainActor in is redundant. The UViewController is isolated to the main actor, as are its methods in your subclass, so the Task is already isolated to the main actor.”

Also, from https://www.massicotte.org/intro-to-isolation

@MainActor  
class MyIsolatedClass {  
    func myMethod() {  
        Task {  
            // still isolated to the MainActor here!  
        }  

        Task.detached {  
            // explicitly non-isolated, regardless  
            // the enclosing scope  
        }  
    }  
}  

And a fun one that I didn’t anticipate, but makes sense since value types are copied:

// Does not compile with:  
// Main actor-isolated property 'x' cannot be accessed from outside of the actor  
@MainActor  
class A {  
    var x = "x"  
    func fn() {  
        Task.detached {  
            self.x  
        }  
    }  
}  

// Compiles fine:  
@MainActor  
struct A {  
    var x = "x"  
    func fn() {  
        Task.detached {  
            self.x  
        }  
    }  
}  

Motivation for lazy on a sequence

Given the sequence

let sequence: any Sequence<Int> = [1,2,3]  

If I do this:

for element in sequence {}  

the sequences iterator will call next and walk through the sequence until exhausted. So this is lazy by default.

Why does the .lazy method exist then? It’s intended to prefix operations on the sequence that would normally eagerly compute the full result:

sequence.map { $0 * 2 }  

That operation would call .next() four times before returning. But:

sequence.lazy.map { $0 * 2 }  

doesn’t call .next() at all, until a consumer starts consuming the sequence. Then .next is called lazily, as needed by the consumer

AI foundation models swift interface file, foundationmodels

Find it at:

/Applications/Xcode-beta 2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/FoundationModels.framework/Modules/FoundationModels.swiftmodule/arm64e-apple-ios.swiftinterface  

Find swift concurrency interface at

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/swift/_Concurrency.swiftmodule/arm64e-apple-ios.swiftinterface  

How to extend a generic based on the type of a generic parameter

These are called parameterized extensions, and they are not implemented in the language.

Workaround here:
https://forums.swift.org/t/extension-on-array-where-element-is-generic-type/10225/4

With primary associated types, Nate’s example can be simplified a touch to:

protocol Rangey<Bound> {  
    associatedtype Bound: Comparable  
    var range: Range<Bound> { get }  
}  

extension Range: Rangey {  
    var range: Range<Bound> { return self }  
}  

extension Array where Element: Rangey<Date> {  
    func contains(date: Date) -> Bool {  
        return contains(where: { $0.range.contains(date) })  
    }  
}  

Remember Range is defined in the stdlib as:

public struct Range<Bound> where Bound : Comparable  

Swift protocol primary associated type

Swift 5.7+ allows for some additional sugar with PATs.
But, while they look like generic parameters, they are not!

It’s still a PAT (protocol with associated type), but it has a “primary” associated type.
This gives us some sugar.

When we used to constrain an associated type on a function, something like:

func fn<S>(_ s: S) where S: Sequence, S.Element == Character {  
    var iterator = s.makeIterator()  
    if let x = iterator.next() {  
        print(x)  
    }  
}  

fn("abc")  
// prints a  

we can now write:

func fn<S>(_ s: S) where S: Sequence<Character> {  
    var iterator = s.makeIterator()  
    if let x = iterator.next() {  
        print(x)  
    }  
}  

Protocols do not have generic parameters:

“[protocols] don’t (and can’t) have generic parameters. Protocols just have associated types, whether primary or not.”
https://forums.swift.org/t/understating-primary-associated-types-in-swift-5-7/59916/4

Also, I don’t know if this used to be possible, but you can now constrain an existential using the primary associated type:

let sequence: Sequence<Int> = [1,2,3]  
sequence.map { $0 * 2 }  

Swift inspect the stdlib interface file:

vim /Library/Developer/CommandLineTools/SDKs/MacOSX15.5.sdk/System/iOSSupport/usr/lib/swift/Swift.swiftmodule/arm64e-apple-ios-macabi.swiftinterface  

Swift criticism

If you just want to get something done, Swift is not the language.
It has gone so far in the ‘advanced PL’ direction that when you use it you have two puzzles:
1. The problem that you are actually setting out to solve
2. The types and constraints puzzle that swift imposes on you

For large teams this burden can pay off, because the compiler’s role in keeping
the evolvoing codebase correct becomes meaningful.

For a startup that’s just trying to get domain ideas out to market, it really sucks.

^ Immediately after typing this up, I needed to create a queue. Should be easy enough, right?
I punch this into a repl:

struct Queue<T> {  
    var backing = [T]()  
    mutating func enqueue(_ item: T) {  
        backing.append(item)  
    }  
    mutating func dequeue() -> T? {  
        backing.popFirst()  
    }  
}  

And I get:

error: referencing instance method 'popFirst()' on 'Collection' requires the types '[T]' and 'Array<T>.SubSequence' (aka 'ArraySlice<T>') be equivalent  

So now I need to scratch my head about the type puzzle.
Can I specify that [T] and Array<T>.SubSequence are equal?
And why is the error talking about [T] instead of T?

Then after some digging I find this:

extension Collection where Self == Self.SubSequence {  
    mutating func popFirst() -> Element?  
}  

meaning popFirst is only defined on collections where the collection type is the same as the subsequence type. Ok? Does that apply to Array? No:

extension Array : RandomAccessCollection, MutableCollection {  
    public typealias SubSequence = ArraySlice<Element>  
}  

So now I’ve wasted a bunch of time puzzling over something that has nothing to do with my goal!
Weirdly, if you use popLast instead of popFirst it compiles just fine. I’m using Swift 6.1.2

Swift power of POP, when it works

If I implement my own Collection, and add the following:

struct MyCollection: Collection {  
    public typealias Index = Int  
    public var startIndex: Index { ... }  
    public var endIndex: Index { ... }  
    public subscript(i: Index) -> Base.Element { ... }  
    public func index(after i: Index) -> Index { ... }  
}  

I then get the full Collection and Sequence APIs at my disposal. On myCollection I can now

allSatisfy  
compactMap  
drop(while:)  
dropFirst  
dropLast  
firstIndex(of:)  
firstIndex(where:)  
flatMap  
map  
max  
min  
prefix  
prefix(upTo:)  
prefix(while:)  
reversed  
sorted(by:)  
etc. etc.  

That’s pretty cool.

Note from Dave Abrahams on conforming to Collection instead of Sequence:

Finally, because it is at the root of the protocol hierarchy and has so few  
requirements, it is very attractive to implement Sequence where implementing  
Collection would be more appropriate. Making a type conform to Sequence instead  
of Collection has both efficiency and capability costs for operations on that  
type.  

Swift Collection is a stronger guarantee than Sequence

A Collection refines Sequence, e.g. public protocol Collection<Element>: Sequence

From Apple’s docs, a collection is:
> A sequence whose elements can be traversed multiple times, nondestructively, and accessed by an indexed subscript.

Swift toString gotcha

It’s not String([1,2,3]) it’s String(describing: [1,2,3])

How to view swift interface files without Xcode wrecking them

locate .swiftinterface | grep swiftuicore | grep iPhoneOS  

There is both a SwiftUICore.swiftmodule and a SwiftUI.swiftmodule:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64e-apple-ios.swiftinterface  

Type erasure 101

Repl session.

protocol P {  
    func f()  
}  

func callF(_ p: P) {  
    p.f()  
}  

struct A: P {  
    func f() {  
        print("Hi from A")  
    }  
}  

callF(A()) // prints "Hi from A"  

struct B: P {  
    func f() {  
        print("Hi from B")  
    }  
}  
callF(B()) // prints "Hi from B"  

[A(), B()].forEach { callF($0) }  // Compiler error  

struct AnyP: P {  
    let base: P  
    init<U: P>(_ concrete: U) {  
        self.base = concrete  
    }  
    func f() {  
        self.base.f()  
    }  
}  

[AnyP(A()), AnyP(B())].forEach { callF($0) }  // prints "Hi from A" followed by "Hi from B"  

rethrows

In the stdlib there are signatures like filter on Sequence that uses rethrows:

@inlinable  
public __consuming func filter(  
  _ isIncluded: (Element) throws -> Bool  
) rethrows -> [Element] {  
  return try _filter(isIncluded)  
}  

It lets us call filter without a try:

[1,2,3].filter { $0 > 1 }  

But with a try if the argument can throw:

enum MyError: Error { case bad }  

func fn(_ x: Int) throws -> Bool {  
    throw MyError.bad  
}  

do {  
    _ = try [1, 2, 3].filter(fn)  
} catch {  
    print("Caught error: \(error)")  
}  

Unchecked Sendable

An @unchecked Sendable is “A type whose values can safely be passed across concurrency domains by copying, but which disables some safety checking at the conformance site.”
Source: https://developer.apple.com/documentation/swift/unsafesendable

Versus a Sendable which is “A thread-safe type whose values can be shared across arbitrary concurrent contexts without introducing a risk of data races.”
Source: https://developer.apple.com/documentation/Swift/Sendable

Hack to understand ‘some’ better

When I see it in code, read it as ‘particular’ instead of ‘some’.

‘any’ is an existential. Relies on dynamic dispatch.

‘some’ is an opaque type to the caller, but still has identity that the compiler knows of.

Easiest to think of as ‘reverse generics’:

"An opaque return type can be thought of as putting the generic signature "to the right" of the  
function arrow; instead of being a type chosen by the caller that the callee sees as  
abstracted, the return type is chosen by the callee, and comes back to the caller as  
abstracted"  

Soruce: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0244-opaque-result-types.md

Swift Customization Point

protocol X {
var y: String // this is a customization point
}

extension X {
var z: String {
“Not a customization point!”
}

// default implementation  
var y: String {  
    "hello world"  
}  

}

// X#z can’t be customized, but X#y can

How to propagate task cancellation to an asyncstream

func makeStream() -> AsyncStream<Int> {  
return AsyncStream { continuation in  
    let task = Task {  
        var n = 0  
        while !Task.isCancelled {  
            print("Sending", n)  
            continuation.yield(n)  
            try? await Task.sleep(nanoseconds: 1_000_000_000)  
            n += 1  
        }  
        print("Cancelled!")  
    }  

    continuation.onTermination = { _ in  
        task.cancel()  
    }  
}  

}

Source: https://forums.swift.org/t/why-asyncstream-breaks-structured-concurrency/71477/4

Swift gotcha: A Task does not create a child task.
https://forums.swift.org/t/why-asyncstream-breaks-structured-concurrency/71477/3
Read all answers by robert.ryan in that thread

Visual on different ways to create a task:
https://forums.swift.org/t/should-task-groups-inherit-actor/57547/2

More info on the swift gotcha of a Task not creating a child task:
> Tasks created with Task are not child tasks of the current task, and
changes to the current task like cancellation and priority escalation are
not propagated to them. Task just copies more of the context of the current
task than Task.detached does.
> The only true child tasks (currently) are the tasks created by async let
and TaskGroup.
Source: https://forums.swift.org/t/calling-synchronous-function-with-async-let/59211/8

Can use compiler version as proxy for base sdk version

Handy when trying to conditionally compile a lib feature that is backdeployed
but not available for customers on older versions of Xcode:

https://forums.swift.org/t/conditionally-compile-based-on-ios-version-previewcgimagerepresentation-broke/50883/2

The case for allowing force unwraps in prod code

Quinn the Eskimo: https://forums.swift.org/t/how-to-handle-errors-in-swift-when-coming-from-a-java-world/20821/13

Swift dictionaries are value types, but not immutable

struct S {  
    var x = 1  
}  

var y: [String: S] = ["a": S()]  
y["a"]?.x = 2  
y["a"]?.x  // Returns 2!  

I figured I would have to do this:

var y: [String: S] = ["a": S()]  
y["a"] = S(x: 2)  

The first snippet rewritten with an assignment does what I expect:

struct S {  
    var x = 1  
}  

var y: [String: S] = ["a": S()]  
var z = y["a"]  
z?.x = 2  
y["a"]?.x  // Returns 1  

Returning to first snippet. Will didSet handlers get called with this setup:

struct S {  
    var x = 1  
}  

final class C {  
    var y: [String: S] = ["a": S()] {  
        didSet {  
            print("Am I called?")  
        }  
    }  
    func mutate() {  
        self.y["a"]?.x = 2  
    }  
}  

C().mutate()  
// Prints "Am I called?"  

Swift concurrency nonisolated

“Marking something as nonisolated tells the compiler that you’re not going to touch any of the
isolated state and therefore this function can be called from anywhere”
https://developer.apple.com/videos/play/wwdc2021/10194/?time=2302

Swift concurrency what happens at suspension point

Quinn the Eskimo!

In Swift concurrency, tasks are run by threads from the Swift concurrency cooperative thread  
pool. When a task suspends at an await, the thread running that task returns to the thread pool  
and looks for more work to do.  

https://developer.apple.com/forums/thread/708182

Swift concurrency task cancelation

Structured tasks are canceled when they go out of scope (that means for async let and await withTaskGroup).
Unstructured tasks are canceled cooperatively, meaning it’s up to my code to check for either:

Task.isCancelled  
or  
try Task.checkCancellation  

Swift concurrency equivalent of dispatching async to the main queue in gcd

Another Quinn the Eskimo! gem: https://developer.apple.com/forums/thread/760725

actor MyActor {  
    func doStuff() {  
        Task { @MainActor in  
            MainActorState.counter += 1  
        }  
    }  
}  

Also notice how he annotates the static var below as @MainActor. You can’t apply that
annotation to the enclosing type:

enum MainActorState {  
    @MainActor static var counter: Int = 0  
}  

actor MyActor {  

    func doStuff() {  
        MainActorState.counter += 1  
                    // ^ Main actor-isolated static property 'counter' can not  
                    // be mutated on a non-isolated actor instance  
    }  
}  

Modern equivalent of kicking off a task on a background thread

Swift 6.2

Task { @concurrent in  
    // Do work   
}  

Swift gotcha: actors do not isolate static properties and methods

This does not isolate doSomething:

@globalActor public actor RealtimeActor {  
    public static let shared = RealtimeActor()  
}  

@RealtimeActor  
final class Foo {  
    static func doSomething() {}  
}  

Try it in a sample project. You can call Foo.doSomething outside of a task, and it will
execute on the main thread.

Ah, it’s by design

Static methods, properties, and subscripts do not have a self parameter that is an instance of the actor, so they are not actor-isolated.

https://github.com/swiftlang/swift-evolution/blob/main/proposals/0306-actors.md

Parallel async and join

https://x.com/nsobject/status/1892611473144213584

For functions that return void:

let d = Date()  
async let parallelDep1: Void = wait1()  
async let parallelDep2: Void = wait2()  
_ = await (parallelDep1, parallelDep2)  
print(String(format: "Deps loaded in %.2f seconds", Date().timeIntervalSince(d)))  

private func wait1() async {  
    try? await Task.sleep(for: .seconds(1))  
}  

private func wait2() async {  
    try? await Task.sleep(for: .seconds(1))  
}  

Pause and signal

Quinn the Eskimo! says:

My favourite trick for this problem in general is to add a pause() system call to the front of  
my code. That stops the process until it receives a signal, and the act of attaching the  
debugger generates that signal and thus you can just continue from there.  

https://forums.swift.org/t/editing-and-debugging-a-swiftpm-plugin/71935/6

How to write an async getter

private static var myString: String {  
    get async {  
        return await getTheString()  
    }  
}  

How to sleep

try? await Task.sleep(nanoseconds: 1_000_000_000)  

How to perform an action after delay

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {  
    print("hello")  
}  

// or  

Task {  
    try? await Task.sleep(nanoseconds: 2_000_000_000)  
    print("world")  
}  

AI can’t understand customization points

AI bad at POP. When to use customization points vs default extensions.
It can tell you what they are, but it won’t design w/ them. Yet.

How to inspect SPM package

From root of package:

swift package dump-package  

How to check if a task was canceled

From within the task:

try Task.checkCancellation()  

How to use an enum with associated value outside of switch

if case let .longHTTP(wait: wait) = strategy {  
    request.addValue("Prefer", forHTTPHeaderField: "wait=\(wait)")  
}  

How to deserialize without Decodable

First, use Decodable. But if I’m roughing something in:

import Foundation  
let myData: Data = ...  
let deserialized = try JSONSerialization.jsonObject(with: myData)  
guard let json = deserialized as? [String: Any] else {  
    throw MyError("Could not deserialize data to [String: Any]")  
}  

How to catch Foundation URLError:

URLRequest comes with a default timeout of 60 seconds. Can catch timeouts with (see line 27):
https://gist.github.com/lzell/42b47aa5e521a3e20840aba093a7c835

Why not use snake case option in decodable everywhere?

It fails for properties that I have setup with acronyms, e.g. 

struct Response: Decodable {  
    let fooURL // I want this to map to "foo_url"  
}  

JSONDecoder throw encountering unescaped newline

The error:

"Unescaped control character '0xa' around line 3, column 0."  

is due to an unescaped newline in a JSON field. Repro:

let response = """  
{  
  "message": "will\nfail"  
}  
"""  

struct Response: Decodable {  
    let message: String  
}  

_ = try! JSONDecoder().decode(Response.self, from: response.data(using: .utf8)!)  

How to modify localizedDescription on an error

It’s actually Foundation that adds the localizedDescription property on an error. For example,
this fails in a repl:

enum MyError: Error {  
    case foo  
}  
do {  
    throw MyError.foo  
} catch {  
    print(error.localizedDescription)  
}  

but if I import Foundation first, it works as expected.

To modify the error description, use this:

import Foundation   
   
enum MyError: LocalizedError {    
    case foo    

    var errorDescription: String? {    
        switch self {    
        case .foo:    
            return "My description"    
        }    
    }    
}    
   
do {    
    throw MyError.foo    
} catch {    
    print(error.localizedDescription) // prints 'My description'  
}  

Swift Foundation URL

URLComponents are not needed to get out the domain and path.

let url = URL(string: "https://api.aiproxy.pro/foo/bar")!  

Get the domain

url.host  

Get the path

url.path  

Swift errors versus exceptions

Error handling in Swift resembles exception handling in other languages, with the use of the  
try, catch and throw keywords. Unlike exception handling in many languages — including  
Objective-C — error handling in Swift doesn’t involve unwinding the call stack, a process that  
can be computationally expensive. As such, the performance characteristics of a throw statement  
are comparable to those of a return statement.  

From: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/errorhandling/

Pattern to split nested types out into their own files

// A.swift  
struct A {  
}  

// A+B.swift  
extension A {  
    struct B {  
    }  
}  

I think it’s more common to use this pattern for protocol conformance, but I like it for nested
structs too. I searched around for examples of Apple code that uses this pattern. It’s in
swift-foundation:

https://developer.apple.com/documentation/foundation/date/iso8601formatstyle
https://github.com/apple/swift-foundation/blob/main/Sources/FoundationEssentials/Formatting/Date%2BISO8601FormatStyle.swift#L24

How to use a generic constraint

f and g are equivalent here:

protocol P {}  

struct S: P {}  

func f<T>(_ t: T) where T: P {}  

func g<T: P>(_ t: T) {}  

f(S())  
g(S())  

Apple calls the first syntax a ‘generic where clause’ and the second a ‘generic parameter
clause’. The only difference, as far as I can tell, is the where clause can support constraints
on a protocol’s associated types, e.g. where S1.Iterator.Element == S2.Iterator.Element

If I am not working with PATs, I prefer the syntax func g<T: P>(_ t: T)

How to conditionally add extensions to generic types

struct S<T> {  
    let s: T  
}  

extension S where T == Int {  
    func plusOne() -> Int {  
        return self.s + 1  
    }  
}  

let x = S<Int>(s: 1)  
print(x.plusOne())  // prints 2  

Syntax to create a string that contains double quotes

Instead of

"{\"x\":\"y\"}"  

Use

#"{"x":"y"}"#  

For a multiline string that I don’t want to escape quotes or slashes:

#"""  
This is  
"cool"  
"""#  

Future proof decodables with enums

See the ‘future proof’ section here: https://www.donnywals.com/writing-custom-json-encoding-and-decoding-logic/

Encodable enum with associated value

Always name the associated value, otherwise you get a 0: "whatever" in your encoded json.

JSON encoding with heterogeneous dict

The fact that I need to introduce type erasure for a concept this simple is still wild to me:

let dict = ["A": "x", "B": 2]  
try? JSONEncoder().encode(dict)  // Won't work  

We had this with obj-c out of the box.

Redditor to the rescue: https://www.reddit.com/r/swift/comments/1ecv7dw/wrangling_json_in_swift/

let dict: [String: Any] = ["A": "x", "B": 2]  
let data = try? JSONSerialization.data(withJSONObject: dict)  
String(data: data!, encoding: .utf8)  

How to achieve a sum type

Swift doesn’t have a sum or union. What do people use instead? Enum with associated values

How to concatenate Data

Use the + overload:

Data() + Data()  

How to generate a UUID

import Foundation  
UUID().uuidString  

How to use FatalError versus throwing Errors

Swift closure with named argument

[1,2,3].map { x in x + 1 }  

Swift closure with unnamed argument

[1,2,3].map { $0 + 1 }  

Swift make command line tool run forever

RunLoop.current.run()  

Swift Encodable, Decodable, Codable

Codable is defined as

public typealias Codable = Decodable & Encodable  

If I only want to create types that are encodable, use struct MyMessage: Encodable

Swift Encodable example, to json

import Foundation  

struct S: Encodable {  
    let x: String  
    let y: Int  
}  

let s = S(x: "hello", y: 123)  
let jsonData = JSONEncoder().encode(s)  
if let jsonStr = String(data: jsonData, encoding: .utf8) {  
    print(jsonStr)  
    // prints {"x":"hello","y":123}  
}  

Writing unit tests against encodable structs

There is no guarantee of key order when structs are encoded. For unit tests,
create the encoder with the following for predictable serialization results:

let encoder = JSONEncoder()  
encoder.outputFormatting = .sortedKeys  

Swift concurrency beginner’s error

Don’t put Tasks everywhere. Try to stay structured

(swift, stringify without using codable)

private func stringify(_ args: [String: Any]) -> Data? {  
    if JSONSerialization.isValidJSONObject(args) {  
        return try? JSONSerialization.data(withJSONObject: args, options: [])  
    }  
    return nil  
}  

(swift, remove from dictionary)

var x = ["a": 1]  
x.removeValue(forKey: "a")  
x #=> [:]  

(swift, tuple destructuring)

 var x = (1, "hello")  
 var (a, b) = x  
 a #=> 1  
 b #=> "hello"  

(swift, special case for simulator)

#if targetEnvironment(simulator)  
    // Do something special  
#endif  

How to conditionally compile for macOS

#if os(macOS)  
print("mac")  
#else  
print("not mac")  
#endif  

(swift, dictionary, increment key, ruby ||=)
var x = String: Int
x[“a”, default: 0] += 1 // a maps to 1
x[“a”, default: 0] += 1 // a maps to 2

(swift async streams, continuations)
- AsyncStream conforms to AsyncSequence
- See the docstring on AsyncThrowingStream for modifying an existing
closure-based callback earthquake monitor into an async/await-compatible interface
- See continuation reference in wwdc/modern_crash_course_takeaways.txt
- Sendable is “A type whose values can safely be passed across concurrency domains by copying.”
- See ~/dev/ContinuationExperiment

(swift get type of instance)
type(of: myInstance)

(swift regex, repl)
Start the repl with:

swift repl -enable-bare-slash-regex  
> var a = "a"  
> let re = /a/  
> a.replace(re) { match -> String in "b" }  
> a  
// Outputs "b"  

What most languages call ‘lazy’ (i.e. ? after a pattern), swift calls ‘reluctant’:
See Swift Regex: Beyond the basics, 12:35

(swift regex, SPM)
Modify the target sections of Package.swift to look like this:

.target(  
    name: "AIProxySwift",  
    swiftSettings: [  
        .unsafeFlags(["-Xfrontend", "-enable-bare-slash-regex"])  
    ]  
),  
.testTarget(  
    name: "AIProxySwiftTests",  
    dependencies: ["AIProxySwift"],  
    swiftSettings: [  
        .unsafeFlags(["-Xfrontend", "-enable-bare-slash-regex"])  
    ]  
),  

New questions

How to use globalActor to annotate functions

@globalActor actor MyStickerActor {  
    static let shared = MyStickerActor()  
}  
// Then...  
@MyStickerActor  
func createSticker(_ prompt: String) async throws -> UIImage  

(gcd notes, libdispatch notes, use it right, serial queue)
https://gist.github.com/tclementdev/6af616354912b0347cdf6db159c37057

(swift data)
How to create a model container outside of SwiftUI context:
https://developer.apple.com/documentation/swiftdata/preserving-your-apps-model-data-across-launches

References to organize:
// Meet SwiftData: https://developer.apple.com/videos/play/wwdc2023/10187/
// Build an App with Swift Data: https://developer.apple.com/videos/play/wwdc2023/10154
// https://developer.apple.com/xcode/swiftdata/
// bug: https://developer.apple.com/forums/thread/732788
//
// Swipe to delete: https://developer.apple.com/documentation/swiftdata/deleting-persistent-data-from-your-app
//

(swift, start repl)
swift repl

(swift, string interpolation, concatentation, floats)

// Interpolation
let a = “a”
let a_ = “(a)”
a == a_ # => true

// Concatenation
a + “b” == “ab” # => true

// Printing multiple strings
print(a, “b”) # => prints “a b”

// Printing floats
import Foundation
let a = 1.2345
String(format: “%.2f”, a) # => 1.23

// Separating string variables from the string template:
import Foundation
String(format: “%@ %@”, “hello”, “world”)

(property wrappers)

Minute 27 of “modern swift API design”

(smells, protocol, overuse, protocols aren’t mixins)
Add to my talk: minute 13 of wwdc “modern swift API design”.
If conformer calls protocol definitions, you’re using it wrong.

(swift add convenience initializer to struct, keep memberwise initializer)
Add the initializer in an extension to avoid losing the default memberwise initializer

(swift demangle, stack trace, demangle)
xcrun swift-demangle

(assembly, swift)
For anyone curious how to look at assembly for snippets of swift, this is what
I ran: xcrun -sdk iphoneos swiftc -target arm64-darwin-ios11 -O -S -o - input.swift | xcrun swift-demangle | less

(repl, swift, lookup, type)
$ swift repl
> :type lookup String

Use this to search the api with fuzzy search (ctrl+6 once open):
printf “import Foundation:type lookup String” | swift > /tmp/foo.swift && open -a /Applications/Xcode.app /tmp/foo.swift

(repl, spm, swift, package, import module)
Start repl with:
$ swift build && swift -I.build/debug -L.build/debug -lBluetoothService
> import BluetoothService

(swift compiler, swiftc)
Additional help:
swiftc -help-hidden

(switch swift version)
$ sudo xcode-select -switch /Applications/Xcode-beta.app
$ xcrun swift –version

(swift, get type)
“foo”.dynamicType

(swift, initializers)
http://stackoverflow.com/questions/29956195/idiomatic-pattern-to-initialize-uiviews-in-swift

Will be able to find *-Swift.h in:
~/Library/Developer/Xcode/DerivedData/

Repl

Run with:
xcrun swift
or yosemite:
swift
or:
lldb –repl

When modifying previously entered input: insert newline with opt+enter

Type :help to get list of commands
:quit to quit

To set a breakpoint from within repl, create a function called go, then set a
breakpoint in the body with:
:breakpoint set –line
Then call go()

LLDB - Debugging (script, lldb, swift, debugging, dsym)

Emit debug information:
$ swiftc filename.swift -g
Run program with lldb:
$ lldb -f filename
Set breakpoint:
(lldb) breakpoint set –file filename.swift –line 1
Run:
(lldb) run

Print lots of information:
(lldb) fr v -R

Change the variable to nil:
(lldb) p x = nil
Dump it again:
(lldb) fr v -R x

(lldb) expression -l objc -O – (id) 0xaddressofobject