Repository navigation
Integration branch for ably_pubsub_device_flutter v2 package - #606
Conversation
|
Important Review skippedToo many files! This PR contains 286 files, which is 186 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
4845f48 to
ea51456
Compare
|
Tracking the native bump (RTS4c-e release errors, |
maratal
left a comment
There was a problem hiding this comment.
There are some merge conflicts
The SDK now offers a realtime interface only. `Rest`, `RestChannel`, `RestChannels`, `RestPresence`, `RestAuth` and the `Rest*` option and param types are gone, along with their platform methods, codec types and Android/iOS handlers. `Push` and `PushChannel` now require a `realtime` client, and `Message`/`PresenceMessage.fromEncoded` take `RealtimeChannelOptions`. UPDATING.md documents the migration. Two pieces of pre-existing drift had to be fixed to regenerate the platform constants: - The codegen templates used `_` as a lambda parameter, which is a wildcard in current Dart, so `bin/codegen.dart` no longer ran. - The generated constants had been hand-edited with entries missing from the codegen context (`connectionRecoveryKey`, the `ConnectionStateChange` connection id/key, and three Java-only `ClientOptions` timeout keys); these are now in the context so regeneration reproduces them on all three platforms. Tests: the rest unit and integration tests are deleted; the shared `Channels` test moves to `RealtimeChannels`, the plugin test covers client creation over `Realtime`, and the realtime auth tests bootstrap their tokens from a non-auto-connecting `Realtime` client. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Following the rename of this SDK to Ably Pub/Sub, rename the published Dart package from `ably_flutter` to `ably_pubsub_device_flutter`, so the package name matches the product. The rename reaches further than `pubspec.yaml` because several names are derived from the package name: - The library entry point moves to `lib/ably_pubsub_device_flutter.dart`, and every `package:ably_flutter/…` import follows. Import blocks are re-sorted where the new name changes their alphabetical order. - Flutter resolves a plugin's podspec by package name, so the podspec is renamed too. That in turn renames the Swift module, so the ObjC sources now import `<ably_pubsub_device_flutter/…-Swift.h>`, and the iOS CI job builds the `ably_pubsub_device_flutter-Unit-Tests` scheme CocoaPods generates from it. - `android/settings.gradle` names the Gradle project, and the example's Xcode project names the framework it embeds. Both `Podfile.lock`s are regenerated with `pod install` so their spec checksums are real, and the three `pubspec.lock`s with `flutter pub get`. Method channel names and the `io.ably.ably_flutter.PUSH_*` broadcast actions keep their current values, as wire identifiers shared with the platform side. The example, integration test and test harness packages keep their own names. `UPDATING.md` gains a migration note covering the dependency, the import path and the iOS module. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Following the rename of this SDK to Ably Pub/Sub, and the removal of the REST client, the single remaining client is renamed from `Realtime` to `PubSubClient` to match the product name. The declaring file moves to `pub_sub_client.dart` accordingly. Only the class is renamed. The `realtime` properties on `Connection`, `RealtimeChannel`, `RealtimeChannels`, `Push` and `PushChannel`, the `realtimeInstances` getter, and the platform channel method names all keep their current names. Unit and integration tests are updated to construct `PubSubClient`; they cover the same behaviour as before. `UPDATING.md` gains a migration note for the new name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Make `PubSubClient`'s constructor private and expose a single top-level
`createClient({required ClientOptions options})` function as the only way
to obtain a client. A factory function keeps the construction path open
for future changes — validation, caching, returning a subtype — without
another breaking change to the public surface.
This also removes the two key shorthands, `PubSubClient.fromKey(key)` and
the `key` parameter. They duplicated `ClientOptions(key: ...)`, which
`fromKey` delegated to anyway, and the either/or `options`/`key`
signature was only enforced by an assert. Callers now pass the key
through `ClientOptions`, so behaviour is unchanged. The four call sites
that passed both `options` and `key` keep only `options`, which is what
took effect before.
`options` becomes a final field, as it is now always set at construction.
Unit and integration tests construct clients through `createClient` and
cover the same behaviour as before.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clear out the API that earlier versions marked deprecated, now that a major release allows it: - `Connection.recoveryKey`, superseded by `createRecoveryKey()`. - `ClientOptions.logHandler` and the `LogHandler` typedef. These never did anything — the codec carried a `TODO handle logHandler` where the encoding would have gone, and log output is handled by the underlying native SDK. - `ClientOptions.fallbackHostsUseDefault`, which had no replacement. - `ClientOptions.fromKey()` and `AuthOptions.fromKey()`, superseded by the constructors' named `key` parameter. `fallbackHostsUseDefault` was plumbed over the platform channel, so it also goes from `bin/codegen_context.dart` — regenerating the Dart, Java and Obj-C constants — from the Dart codec, and from the Java and Obj-C readers. Dropping the Obj-C read removes the deprecation warning ably-cocoa emitted for that property. Three doc comments referred to members this commit deletes, and are rewritten to describe what replaces them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Spec 6.3.0 replaces RTS4a, under which release() detaches a channel that is not already INITIALIZED, DETACHED or FAILED before removing it, with RTS4c-e: release() of a channel in any other state must fail with error 90011 and leave the channel in place. That check is done by the platform SDKs (ably-java, ably-cocoa) in their next major versions. release() previously fired the platform call without awaiting it and dropped the Dart-side channel unconditionally, so a platform error would have been lost as an unhandled async error while the Dart and platform collections diverged. It now returns a Future that completes with the platform's AblyException, and only removes the Dart-side channel once the platform release has succeeded. The state check is deliberately left to the platform SDK, because RealtimeChannel.state is updated asynchronously from platform events and so can lag behind the platform channel's state. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Two floors land in the same bump. The UIScene plugin APIs this SDK is about to adopt -- the `FlutterSceneLifeCycleDelegate` protocol and `FlutterPluginRegistrar.addSceneDelegate:` -- first shipped in Flutter 3.38, and `UIScene` itself is iOS 13+. Flutter 3.44 then made Swift Package Manager the default dependency manager rather than the opt-in experiment it had been since 3.24, and that is the floor the upcoming CocoaPods -> SwiftPM migration needs: below it a consumer would have to turn on an experimental feature by hand just to build this plugin. So raise the Flutter floor straight to 3.44 (Dart 3.12) rather than 3.38, and pull the toolchain and CI up to 3.47.3, the current stable. Because 3.44+ migrates an Xcode project to SwiftPM the first time it builds, the example and test_integration apps pin `enable-swift-package-manager: false` in their pubspecs for now. That keeps this commit a version bump and lets the migration land as its own reviewable change, which drops those pins along with the Podfiles. Alongside the version bumps: - Drop two lints the newer analyzer rejects: `package_api_docs`, which was removed, and `avoid_null_checks_in_equality_operators`, now deprecated. Drop the two redundant `!` assertions in `codec.dart` it also flags. - Silence `prefer_initializing_formals`. Dart 3.13 extended it to private fields initialised from a named parameter, but `this._field` in a named parameter list is only legal under the off-by-default `private-named-parameters` experiment, so its seven reports have no fix. - Silence `experimental_member_use` on the example app's deliberate use of the experimental `Push.reset`. - Take the `build/`, `android/` and `ios/` analyzer excludes that `flutter pub get` now writes into `analysis_options.yaml` itself, rather than have the file churn on every fetch. - Gitignore `ios/Flutter/ephemeral/`, which Flutter generates in both example projects. - Regenerating the CocoaPods projects also drops stale Firebase, Toast and nanopb framework entries from the example's `project.pbxproj`; those pods are no longer in its Podfile. Groundwork for #592 and #602. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…aPod Flutter 3.44 made Swift Package Manager the default, and the previous commit raised the floor to it, so the plugin can now ship a `Package.swift` and drop its podspec. SwiftPM does not allow Objective-C and Swift in the same target, and this plugin's two languages call into each other: the Objective-C plugin class registers Swift handlers, and those handlers take the plugin class. The package breaks the cycle with three targets: - AblyFlutterCommon (Objective-C): the shared types -- instance store, message wrappers, platform constants, streams channel -- plus a new `AblyFlutterPluginContext` protocol carrying the instance store and method channel that the handlers need. - AblyFlutterSwift: the existing Swift handlers, encoders and push glue, now taking `AblyFlutterPluginContext` instead of `AblyFlutter` and importing their dependencies explicitly. - ably_pubsub_device_flutter (Objective-C): the `AblyFlutter` plugin class, which conforms to the protocol, and the codec. `ably-cocoa` stays pinned at exactly 1.2.53, now resolved through SwiftPM. SwiftPM cannot read `pubspec.yaml` the way the podspec did, so the plugin version reported in the `ably-flutter` agent moves into `AblyFlutterVersion.h`. A Dart test fails if it drifts from `pubspec.yaml`, and the release skill and CONTRIBUTING.md now bump it. `getVersion` now reports "ably-cocoa <version>" rather than "CocoaPod <version>". The example and test_integration apps drop their `enable-swift-package-manager: false` pins and are migrated by Flutter. test_integration no longer uses CocoaPods at all; the example keeps its Podfile for flutter_local_notifications, fluttertoast and device_info_plus, which only support CocoaPods at their pinned versions. When Flutter migrates a plugin's own example app, it references the package both directly, giving it the identity `ably_pubsub_device_flutter`, and through a symlink named after the repository's checkout directory, and resolution fails if the two differ. The iOS example CI job therefore checks out into `ably_pubsub_device_flutter`, and CONTRIBUTING.md asks contributors to clone into a directory of that name. Apps consuming the plugin from pub.dev are unaffected. The XCTest suite moves into the package as a test target. Standalone, the package's `../FlutterFramework` dependency does not exist, so the new `ios/run_unit_tests.sh` generates one wrapping the SDK's engine and runs the tests; the iOS unit test workflow now calls it in place of `pod lib lint`. BREAKING CHANGE: apps that have turned Swift Package Manager off can no longer install the plugin, as there is no podspec. See UPDATING.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dpoint The iOS plugin now depends on ably-pubsub-cocoa 2.0.0 (AblyPubSubDevice) and the Android plugin on io.ably.pubsub:device 2.0.0, following both SDKs' v2 migration guides. Breaking changes: - ClientOptions.environment, restHost and realtimeHost are replaced by endpoint, which is all the v2 SDKs support. - Minimum iOS version is 15 and minimum Android API level is 24; building for iOS needs Xcode 26. - Releasing a channel that cannot be released returns error 90011 to Dart on both platforms. Also: - List push subscriptions with exactly one of deviceId or clientId, which the new iOS SDK otherwise raises an exception for. - Report failed push registration updates through didUpdateAblyPush. - Raise the example and test apps to Gradle 8.14.3 and AGP 8.12.1. - Use the nonprod:sandbox endpoint in the example and integration tests. - Run the iOS CI jobs on macos-26. - Document the migration in UPDATING.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The plugin registers as a scene delegate as well as an application delegate, following the pattern firebase_messaging adopted: - Launch setup (registering for remote notifications) runs once, from didFinishLaunching, scene:willConnectToSession:, or plugin registration when a scene is already connected. - A notification tap that launches the app is read from the scene's connection options, so notificationTapLaunchedAppFromTerminated keeps working. - scene:willConnectToSession: returns NO so Flutter's cold-start deep link handling still runs. The example and integration test apps are migrated to UIScene, and PushNotifications.md documents it and refers to the Swift AppDelegate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- iOS: call the auth callback once when the Dart authCallback returns null, instead of reporting an error and then an empty token. - iOS: always complete notificationTapLaunchedAppFromTerminated, with nil when there was no launch tap, and clear the tap once returned, as Android does. - iOS: only treat a notification tap as launching the app from the first scene connection; later scenes belong to an already running app. - Require exactly one of deviceId or clientId in listSubscriptions on both platforms, since ably-pubsub-cocoa supports no other filter. - Return a clear error when releasing a channel on an unknown client handle, instead of an empty error on iOS and a crash on Android. - Document why launch setup registers for remote notifications even when AblyFlutterHandlePushNotifications is NO. - Drop production fallback hosts from the sandbox auth URL test. - Make run_unit_tests.sh fail clearly when no iPhone simulator exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run `flutter pub publish --dry-run` in the check workflow, so problems that would block the release workflow's publish to pub.dev fail on pull requests first. Also repeat the root .gitignore entries in .pubignore. pub reads .pubignore instead of .gitignore, so a publish from a local checkout included the gitignored build/ directory, taking the archive to 93 MB against pub.dev's 100 MB limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Raising the SDK constraint to >=3.12.0 switched dart format to the tall style, so the check workflow's formatting step failed. This is the output of `dart format .` with no other changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d7cc2ec to
fc02ea1
Compare
Flutter 3.47 reports 32-bit x86 Android devices as unsupported, so `flutter drive` filtered out the x86 emulator the jobs started and found no device to run on. Use the x86_64 system image instead. This, not memory pressure, was why the emulator was missing, so restore test_integration's Gradle heap to the 8G it had before 9428448. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9428448 to
f385ea6
Compare
Integration branch contains packages split, renaming and deletion of deprecated methods