Skip to content

onPreferenceChange #210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

dfabulich
Copy link
Contributor

@dfabulich dfabulich commented May 21, 2025

Fixes #133

This PR is weird in several ways.

First, it appears that SKIP DECLARE won't let me disregard the complex where clause of the declaration of this function. If I uncomment the K.Value : Equatable part, Skip will complain, "Skip does not support the referenced type as a generic constraint." I would have expected SKIP DECLARE to tell Skip to disregard that problem, but it doesn't. (Relaxing that constraint should be harmless in practice, because the Xcode build will reject it if someone tries to make a PreferenceKey of a non-Equatable value.) I've filed this as a bug on the transpiler. skiptools/skip#432

Second, I'm using snapshotFlow; I have no idea how I'd port that to Swift, so I just didn't; I'm heavily using SKIP INSERT for this.

Third, you can't just build out an ordinary PreferenceKey and use it with preference. I had to declare my PreferenceKey like this:

struct TestPreferenceKey: PreferenceKey {
    typealias Value = String
    
    #if SKIP
    // SKIP DECLARE: companion object: PreferenceKeyCompanion<String>
    final class Companion: PreferenceKeyCompanion {
        let defaultValue = ""
        func reduce(value: inout String, nextValue: () -> String) {
            value = nextValue()
        }
    }
    #else
    static var defaultValue: String = ""

    static func reduce(value: inout String, nextValue: () -> String) {
        value = nextValue()
    }
    #endif
}

That is, in SwiftUI, I could just declare a couple of static methods, but in SkipUI, I had to explicitly declare a companion object so I could declare it a PreferenceKeyCompanion.

This is all quite strange, but it does work. (And isn't that really what Skip is all about? 😉)

Skip Pull Request Checklist:

  • REQUIRED: I have signed the Contributor Agreement
  • REQUIRED: I have tested my change locally with swift test
  • OPTIONAL: I have tested my change on an iOS simulator or device
  • OPTIONAL: I have tested my change on an Android emulator or device

dfabulich added 2 commits May 20, 2025 21:04
This was surprisingly tricky. The SwiftUI declaration says:

```swift
public func onPreferenceChange<K>(_ key: K.Type = K.self, perform action: @escaping (K.Value) -> Void) -> some View where K : PreferenceKey, K.Value : Equatable
```

But the Skip transpiler doesn't like that. "Skip does not support the referenced type as a generic constraint"

To my surprise, the Skip transpiler refuses to like it even when I add a `//SKIP DECLARE` directive.

So, I commented out the K.Value : Equatable constraint. (Xcode's compiler will enforce it anyway.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement .onPreferenceChange...
1 participant