Skip to content
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

Swift 6 compatibility #908

Open
2 of 7 tasks
defagos opened this issue Jun 11, 2024 · 3 comments
Open
2 of 7 tasks

Swift 6 compatibility #908

defagos opened this issue Jun 11, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@defagos
Copy link
Member

defagos commented Jun 11, 2024

As a developer I would like to benefit from improvements made with Swift 6.

Acceptance criteria

  • Swift 6 support has been enabled (not to be delivered before Xcode 16 is officially available).

Tasks

  • Update version in package manifest.
  • Fix issues.
  • Update Swift version in the demo.
  • Fix issues.
  • Enable explicit modules in the demo target.
  • Report issues found to Apple, if any.
  • Think about publishers and guarantees (e.g. should publishers provided by Player always publish on the main thread? Offer no such guarantee?)
@defagos
Copy link
Member Author

defagos commented Jun 11, 2024

There is an issue with structs and strict concurrency checking:

public struct Flags {
    public static let none = Self(isEnabled: false)       // Static property 'none' is not concurrency-safe because non-'Sendable' type 'Flags' may have shared mutable state
    public let isEnabled: Bool
}

struct Flags2 {
    public static let none = Self(isEnabled: false)       // No issue
    public let isEnabled: Bool
}

struct Flags3 {
    static let none = Self(isEnabled: false)              // No issue
    let isEnabled: Bool
}

I am not really understanding why this happens with a constant and since global instantiation is guaranteed to be safe. But this might be worth a deeper look and possibly a bug report if appropriate.

@defagos defagos added the enhancement New feature or request label Jun 13, 2024
@defagos
Copy link
Member Author

defagos commented Jul 6, 2024

I investigated further how we could implement Swift 6 concurrency checking in Pillarbox, especially in the PillarboxPlayer package.

Current thoughts:

  • I am not sure we should blindly adopt @MainActor everywhere. AVPlayer is marked as @MainActor but almost all its public API is marked as nonisolated since iOS / tvOS 16, which means that most of the API can be used off the main thread.
  • Instead we should probably focus in making Player (and other types) simply @Observable. It namely seems that no additional work is required for SwiftUI updates to be read from the main thread. This would also make Player more flexible and would avoid @MainActor spreading through the codebase like a disease. More information might be available on the Swift forums, in the revised pitch or in the evolution proposal itself. Of course this does not make the Player implementation thread-safe, e.g. with the use of a recursive lock.
  • We can use weakAssign(to:on:) to plug publishers to properties of the observable object. Of course the assigning / reading such properties should be made safe with locks.

I wrote a small prototype to evaluate the feasibility of this approach.

If adopting @Observable is the best way to adopt Swift 6 without littering our code with @MainActor in an unnecessarily restrictive way, we should pause Swift 6 concurrency adoption and make the move to Observable when we can drop support for iOS / tvOS 16.

@defagos defagos mentioned this issue Jul 6, 2024
2 tasks
@defagos
Copy link
Member Author

defagos commented Jul 7, 2024

I opened an issue #931 for thread-safety. Player should likely not be annotated as @MainActor unnecessarily, we should rather document that in the meantime it is safe to be used on the main thread only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: 🚧 In Progress
Development

When branches are created from issues, their pull requests are automatically linked.

1 participant