Skip to content

[pigeon] Support Swift 6 at FlutterStandardMessageCodec #147127

@yuukiw00w

Description

@yuukiw00w

Use case

I set Strict Concurrency Checking to complete in Xcode 15's Build Settings.
With this setting, warnings will be displayed where errors occur in Swift 6.
Currently, when I try to generate an class SampleApi with pigeon, the following warning occurs.

Static property 'shared' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6

class SampleApiCodec: FlutterStandardMessageCodec {
  static let shared = SampleApiCodec(readerWriter: SampleApiCodecReaderWriter())
}

Proposal

There are 4 ways to fix this warning.

pattern 1

Add Sendable (in objc: NS_SWIFT_SENDABLE ) to FlutterStandardMessageCodec.

@interface FlutterStandardMessageCodec : NSObject <FlutterMessageCodec>

This can be adopted by looking at the internal implementation of FlutterStandardMessageCodec and if it can be adapted to Sendable.

pattern 2

Add MainActor or other global actor to FlutterStandardMessageCodec.
This is a more restrictive option than pattern 1.
It can be adopted if FlutterStandardMessageCodec can be adapted to some global actor.
However, if adopted, this is the most desirable pattern as it can be handled properly by Swift Concurrency.

pattern 3

Add @unchecked Sendable to generated ApiCodec class.
If FlutterStandardMessageCodec is difficult to modify but can be adapted to Sendable, can adopt this pattern.

// in generated file via pigeon
class SampleApiCodec: FlutterStandardMessageCodec, @unchecked Sendable {
  static let shared = SampleApiCodec(readerWriter: SampleApiCodecReaderWriter())
}

pattern 4

Remove SampleApiCodec.shared and modify SampleApiSetup.codec.

// in generated file via pigeon
class SampleApiCodec: FlutterStandardMessageCodec, @unchecked Sendable {
  // remove this line
//  static let shared = SampleApiCodec(readerWriter: SampleApiCodecReaderWriter())
}

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class SampleApiSetup {
  /// The codec used by SampleApi.
//  static var codec: FlutterStandardMessageCodec { SampleApiCodec.shared }
  // add next line
  static var codec: FlutterStandardMessageCodec { SampleApiCodec(readerWriter: SampleApiCodecReaderWriter()) }

codec is used only in the setUp function and is called only once, so there is no need to keep it in a static variable, and can initialize it each time.
If this idea is correct, you can adopt this pattern.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listp: pigeonrelated to pigeon messaging codegen toolpackageflutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions