Skip to content

Instantly share code, notes, and snippets.

View mbrandonw's full-sized avatar

Brandon Williams mbrandonw

View GitHub Profile
@mbrandonw
mbrandonw / FB10492871.md
Created June 28, 2022 16:03
FB10492871: TextField writes to binding twice

TextField writes to binding twice

FB10492871

The binding provided to a TextField is written to twice for each keystroke.

Run the following code in a SwiftUI application and type into the text field to reproduce:

import SwiftUI

NotificationCenter.Notifications does not cooperatively cancel

FB10473067

When the following code is run in a playground or in an application:

let task = Task {
  for await _ in await NotificationCenter.default.notifications(named: UIApplication.userDidTakeScreenshotNotification) {
  }
 print(#line, "Sequence finished")

Implicitly opened existentials do not work in playgrounds

FB10447228

Running the following code in Swift playgrounds (in Xcode):

func open<A: Equatable>(_ a: A) {}

func existentialFun(_ value: Any) {
 guard let value = value as? any Equatable

Add primary associated types to Publisher protocol

FB10233455

Sometimes it's necessary to construct a large, complex publisher and return it from a function. Currently you either need to explicitly return that type from the function, which is difficult and breaks compilation with any change to the publisher:

func onAppearEffects() -> Publishers.Zip<...> {
  fetchUser()
    .zip(with: fetchRespositories())
 .zip(with: fetchFavorites())

Incorrect indentation when using prefix / operator

FB10162408

If you define a prefix / operator and use it inside parentheses, the indentation is incorrect when starting a new line:

prefix operator /
prefix func / (a: Int) -> Int { a }
func f(_ int: Int) -> Int { int }
let y: Int = f(/1)
@mbrandonw
mbrandonw / FB10144005.md
Last active June 11, 2024 07:32
iOS 16 Navigation API feedbacks

How to execute logic when NavigationLink is tapped?

FB10144005

Currently it doesn't seem possible to execute additional logic when a navigation link is tapped with the new NavigationLink(value:) initializer. When the link is tapped it updates path state all the way back at the root NavigationStack to drive navigation, but there are many times where we need to perform logic after the tap and before the drill down.

For example, after tapping a link we may want to pre-emptively load some data to show on the drill down screen. Or we may want to perform some form validation. Or we may want to track some analytics. This does not seem possible with the current link API.

A workaround is to use Buttons instead of NavigationLinks, but then you lose all of the styling and affordances given to links, such as chevrons when used in List.

If the API for NavigationLink cannot be changed to accomodate for this, perhaps a new ButtonStyle could be introduced that allows regular buttons to take on the sty

extension Binding {
func didSet(_ perform: @escaping (Value) -> Void) -> Self {
.init(
get: { self.wrappedValue },
set: { newValue, transaction in
self.transaction(transaction).wrappedValue = newValue
perform(newValue)
}
)
}
struct Foo: Identifiable {
let id = 42
}
let kp1: KeyPath<Foo, Int> = idKeyPath()
let kp2: KeyPath<Foo, Int> = idKeyPath()
kp1 == kp2 // ✅ true
kp1 == \.id // ❌ false
kp2 == \.id // ❌ false

FB9627501

In previous betas of Xcode 13 a purple runtime warning would appear when using the alert/confirmationDialog APIs incorrectly. For example, this:

struct ContentView: View {
  var body: some View {
    Text("Hi")
      .alert(
 "Alert",
// See this Swift bug for more info: https://bugs.swift.org/browse/SR-9323
import Benchmark
struct User {
var name = "Blob"
var age = 42
}
@dynamicMemberLookup