Skip to content

Integration branch for ably_pubsub_device_flutter v2 package - #606

Merged
ttypic merged 14 commits into
mainfrom
integration/v2
Nov 2, 2026
Merged

ttypic merged 14 commits into
mainfrom
integration/v2

Conversation

@ttypic

@ttypic ttypic commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Integration branch contains packages split, renaming and deletion of deprecated methods

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too 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.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0a8f3cab-3ed3-4d3f-9327-e1ed120ab5f0
Commits

Reviewing files that changed from the base of the PR and between 3a10ee9 and f385ea6.

Files ignored due to path filters: 10
  • android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java is excluded by !**/generated/**
  • example/ios/Podfile.lock is excluded by !**/*.lock
  • example/pubspec.lock is excluded by !**/*.lock
  • lib/src/generated/platform_constants.dart is excluded by !**/generated/**
  • pubspec.lock is excluded by !**/*.lock
  • test_integration/ios/Podfile.lock is excluded by !**/*.lock
  • test_integration/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved is excluded by !**/Package.resolved
  • test_integration/ios/Runner.xcworkspace/contents.xcworkspacedata is excluded by !**/*.xcworkspace/contents.xcworkspacedata
  • test_integration/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved is excluded by !**/Package.resolved
  • test_integration/pubspec.lock is excluded by !**/*.lock
Files selected for processing: 286
  • .claude/skills/release/SKILL.md
  • .github/workflows/check.yaml
  • .github/workflows/docs.yml
  • .github/workflows/flutter_example_app.yaml
  • .github/workflows/flutter_integration.yaml
  • .github/workflows/ios_unit_tests.yml
  • .pubignore
  • .tool-versions
  • API_REF_INTRO_BLURB.md
  • CONTRIBUTING.md
  • PushNotifications.md
  • README.md
  • UPDATING.md
  • analysis_options.yaml
  • android/build.gradle
  • android/settings.gradle
  • android/src/main/java/io/ably/flutter/plugin/AblyEventStreamHandler.java
  • android/src/main/java/io/ably/flutter/plugin/AblyFlutter.java
  • android/src/main/java/io/ably/flutter/plugin/AblyInstanceStore.java
  • android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java
  • android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java
  • android/src/main/java/io/ably/flutter/plugin/AuthMethodHandler.java
  • android/src/main/java/io/ably/flutter/plugin/BackgroundMethodCallHandler.java
  • android/src/main/java/io/ably/flutter/plugin/MainThreadMethodResult.java
  • android/src/main/java/io/ably/flutter/plugin/StreamsChannel.java
  • android/src/main/java/io/ably/flutter/plugin/dto/EnrichedConnectionStateChange.java
  • android/src/main/java/io/ably/flutter/plugin/push/FirebaseMessagingReceiver.java
  • android/src/main/java/io/ably/flutter/plugin/push/ManualFlutterApplicationRunner.java
  • android/src/main/java/io/ably/flutter/plugin/push/PushActivationEventHandlers.java
  • android/src/main/java/io/ably/flutter/plugin/push/PushActivationReceiver.java
  • android/src/main/java/io/ably/flutter/plugin/push/PushMessagingEventHandlers.java
  • android/src/main/java/io/ably/flutter/plugin/push/PushMessagingService.java
  • android/src/main/java/io/ably/flutter/plugin/types/PlatformClientOptions.java
  • android/src/main/java/io/ably/flutter/plugin/util/CipherParamsStorage.java
  • bin/README.md
  • bin/codegen.dart
  • bin/codegen_context.dart
  • bin/templates/platformconstants.dart.dart
  • bin/templates/platformconstants.h.dart
  • bin/templates/platformconstants.java.dart
  • bin/templates/platformconstants.m.dart
  • example/README.md
  • example/android/gradle.properties
  • example/android/gradle/wrapper/gradle-wrapper.properties
  • example/android/settings.gradle
  • example/example.md
  • example/ios/.gitignore
  • example/ios/Flutter/AppFrameworkInfo.plist
  • example/ios/Podfile
  • example/ios/Runner.xcodeproj/project.pbxproj
  • example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • example/ios/Runner/AppDelegate.swift
  • example/ios/Runner/Info.plist
  • example/lib/app_provisioning.dart
  • example/lib/constants.dart
  • example/lib/main.dart
  • example/lib/nested_realtime_events.dart
  • example/lib/op_state.dart
  • example/lib/push_notifications/android_push_notification_configuration.dart
  • example/lib/push_notifications/push_notification_handlers.dart
  • example/lib/push_notifications/push_notification_message_examples.dart
  • example/lib/push_notifications/push_notification_service.dart
  • example/lib/ui/ably_service.dart
  • example/lib/ui/api_key_service.dart
  • example/lib/ui/auth.dart
  • example/lib/ui/bool_stream_button.dart
  • example/lib/ui/paginated_result_viewer.dart
  • example/lib/ui/push_notifications/push_notifications_activation_sliver.dart
  • example/lib/ui/push_notifications/push_notifications_device_information.dart
  • example/lib/ui/push_notifications/push_notifications_ios_permissions_sliver.dart
  • example/lib/ui/push_notifications/push_notifications_publishing_sliver.dart
  • example/lib/ui/push_notifications/push_notifications_received_sliver.dart
  • example/lib/ui/push_notifications/push_notifications_sliver.dart
  • example/lib/ui/push_notifications/push_notifications_subscriptions_sliver.dart
  • example/lib/ui/push_notifications/push_realtime_client_received_sliver.dart
  • example/lib/ui/realtime_presence_sliver.dart
  • example/lib/ui/realtime_sliver.dart
  • example/lib/ui/rest_sliver.dart
  • example/lib/ui/system_details_sliver.dart
  • example/lib/ui/text_row.dart
  • example/lib/ui/utilities.dart
  • example/pubspec.yaml
  • ios/.gitignore
  • ios/Assets/.gitkeep
  • ios/Classes/handlers/AuthHandlers.swift
  • ios/Classes/handlers/FlutterHandler.swift
  • ios/ably_flutter.podspec
  • ios/ably_pubsub_device_flutter/Package.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/AblyFlutterClientOptions.m
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/AblyFlutterMessage.m
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/AblyInstanceStore.m
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/AblyPlatformConstants.m
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/AblyStreamsChannel.m
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/include/AblyFlutterCommon/AblyFlutterClientOptions.h
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/include/AblyFlutterCommon/AblyFlutterMessage.h
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/include/AblyFlutterCommon/AblyFlutterPluginContext.h
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/include/AblyFlutterCommon/AblyInstanceStore.h
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/include/AblyFlutterCommon/AblyPlatformConstants.h
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterCommon/include/AblyFlutterCommon/AblyStreamsChannel.h
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/Notification.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/PushNotificationEventHandlers.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/RemoteMessage.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/codec/CryptoCodec.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/codec/encoders/ErrorInfo.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/codec/encoders/PushNotificationEncoders.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/handlers/AuthHandlers.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/handlers/CryptoHandlers.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/handlers/FlutterHandler.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/handlers/PushActivationEventHandlers.swift
  • ios/ably_pubsub_device_flutter/Sources/AblyFlutterSwift/handlers/PushHandlers.swift
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/AblyFlutter.m
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/AblyFlutterStreamHandler.h
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/AblyFlutterStreamHandler.m
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/PrivacyInfo.xcprivacy
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterReader.h
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterReader.m
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterReaderWriter.h
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterReaderWriter.m
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterVersion.h
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterWriter.h
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/codec/AblyFlutterWriter.m
  • ios/ably_pubsub_device_flutter/Sources/ably_pubsub_device_flutter/include/ably_pubsub_device_flutter/AblyFlutter.h
  • ios/ably_pubsub_device_flutter/Tests/AblyFlutterCommonTests/AblyStreamsChannelTests.m
  • ios/run_unit_tests.sh
  • lib/ably_pubsub_device_flutter.dart
  • lib/src/authentication/src/auth.dart
  • lib/src/authentication/src/auth_options.dart
  • lib/src/authentication/src/client_options.dart
  • lib/src/authentication/src/token_details.dart
  • lib/src/authentication/src/token_params.dart
  • lib/src/authentication/src/token_request.dart
  • lib/src/common/src/channels.dart
  • lib/src/common/src/http_paginated_response.dart
  • lib/src/crypto/src/cipher_params.dart
  • lib/src/crypto/src/crypto.dart
  • lib/src/error/src/ably_exception.dart
  • lib/src/error/src/error_info.dart
  • lib/src/logging/logging.dart
  • lib/src/logging/src/log_handler.dart
  • lib/src/logging/src/log_level.dart
  • lib/src/message/src/delta_extras.dart
  • lib/src/message/src/message.dart
  • lib/src/message/src/message_data.dart
  • lib/src/message/src/message_extras.dart
  • lib/src/message/src/presence_message.dart
  • lib/src/platform/platform.dart
  • lib/src/platform/platform_internal.dart
  • lib/src/platform/src/ably_event_message.dart
  • lib/src/platform/src/ably_message.dart
  • lib/src/platform/src/background_android_isolate_platform.dart
  • lib/src/platform/src/cipher_params_internal.dart
  • lib/src/platform/src/codec.dart
  • lib/src/platform/src/info.dart
  • lib/src/platform/src/method_call_handler.dart
  • lib/src/platform/src/paginated_result.dart
  • lib/src/platform/src/platform.dart
  • lib/src/platform/src/platform_object.dart
  • lib/src/platform/src/push_activation_events_internal.dart
  • lib/src/platform/src/push_notification_events_internal.dart
  • lib/src/platform/src/realtime/connection.dart
  • lib/src/platform/src/realtime/presence.dart
  • lib/src/platform/src/realtime/pub_sub_client.dart
  • lib/src/platform/src/realtime/realtime_channel.dart
  • lib/src/platform/src/realtime/realtime_channels.dart
  • lib/src/platform/src/rest/rest.dart
  • lib/src/platform/src/rest/rest_channel.dart
  • lib/src/platform/src/rest/rest_channels.dart
  • lib/src/platform/src/rest/rest_presence.dart
  • lib/src/platform/src/streams_channel.dart
  • lib/src/push_notifications/src/admin/push_admin.dart
  • lib/src/push_notifications/src/admin/push_device_registrations.dart
  • lib/src/push_notifications/src/device_details.dart
  • lib/src/push_notifications/src/device_push_details.dart
  • lib/src/push_notifications/src/device_push_state.dart
  • lib/src/push_notifications/src/device_registration_params.dart
  • lib/src/push_notifications/src/ios_notification_settings.dart
  • lib/src/push_notifications/src/local_device.dart
  • lib/src/push_notifications/src/notification.dart
  • lib/src/push_notifications/src/push.dart
  • lib/src/push_notifications/src/push_activation_events.dart
  • lib/src/push_notifications/src/push_channel.dart
  • lib/src/push_notifications/src/push_channel_params.dart
  • lib/src/push_notifications/src/push_channel_subscription_params.dart
  • lib/src/push_notifications/src/push_channel_subscriptions.dart
  • lib/src/push_notifications/src/push_notification_events.dart
  • lib/src/push_notifications/src/remote_message.dart
  • lib/src/realtime/src/channel_event.dart
  • lib/src/realtime/src/channel_mode.dart
  • lib/src/realtime/src/channel_state.dart
  • lib/src/realtime/src/channel_state_event.dart
  • lib/src/realtime/src/connection_event.dart
  • lib/src/realtime/src/connection_state.dart
  • lib/src/realtime/src/connection_state_change.dart
  • lib/src/realtime/src/realtime_auth.dart
  • lib/src/realtime/src/realtime_channel_options.dart
  • lib/src/realtime/src/realtime_history_params.dart
  • lib/src/realtime/src/realtime_presence_params.dart
  • lib/src/rest/rest.dart
  • lib/src/rest/src/rest_auth.dart
  • lib/src/rest/src/rest_channel_options.dart
  • lib/src/rest/src/rest_history_params.dart
  • lib/src/rest/src/rest_presence_params.dart
  • lib/src/stats/src/stats.dart
  • lib/src/stats/src/stats_connection_types.dart
  • lib/src/stats/src/stats_message_traffic.dart
  • lib/src/stats/src/stats_message_types.dart
  • pubspec.yaml
  • test/ably_event_listener_test.dart
  • test/ably_flutter_plugin_test.dart
  • test/ably_pubsub_device_flutter_plugin_test.dart
  • test/ios_plugin_version_test.dart
  • test/mock_method_call_manager.dart
  • test/models/client_options.dart
  • test/models/message_test.dart
  • test/models/presence_message_test.dart
  • test/platform/info_test.dart
  • test/push_notifications/push_channel_test.dart
  • test/realtime/channel_test.dart
  • test/realtime/channels_test.dart
  • test/rest/channel_test.dart
  • test/stable_id_generator_test.dart
  • test_integration/android/gradle.properties
  • test_integration/android/gradle/wrapper/gradle-wrapper.properties
  • test_integration/android/settings.gradle
  • test_integration/ios/.gitignore
  • test_integration/ios/Flutter/AppFrameworkInfo.plist
  • test_integration/ios/Flutter/Debug.xcconfig
  • test_integration/ios/Flutter/Release.xcconfig
  • test_integration/ios/Podfile
  • test_integration/ios/Runner.xcodeproj/project.pbxproj
  • test_integration/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • test_integration/ios/Runner/AppDelegate.swift
  • test_integration/ios/Runner/Info.plist
  • test_integration/lib/app_provisioning.dart
  • test_integration/lib/config/test_factory.dart
  • test_integration/lib/config/test_names.dart
  • test_integration/lib/driver_data_handler.dart
  • test_integration/lib/factory/error_handler.dart
  • test_integration/lib/factory/reporter.dart
  • test_integration/lib/test/basic_test.dart
  • test_integration/lib/test/crypto/crypto_ensure_supported_key_length_test.dart
  • test_integration/lib/test/crypto/crypto_generate_random_key_test.dart
  • test_integration/lib/test/crypto/crypto_get_default_params.dart
  • test_integration/lib/test/realtime/realtime_auth_client_id_test.dart
  • test_integration/lib/test/realtime/realtime_auth_url_test.dart
  • test_integration/lib/test/realtime/realtime_authorize_test.dart
  • test_integration/lib/test/realtime/realtime_encrypted_publish_test.dart
  • test_integration/lib/test/realtime/realtime_events_test.dart
  • test_integration/lib/test/realtime/realtime_history_test.dart
  • test_integration/lib/test/realtime/realtime_history_with_auth_callback_test.dart
  • test_integration/lib/test/realtime/realtime_presence_enter_update_leave.dart
  • test_integration/lib/test/realtime/realtime_presence_get.dart
  • test_integration/lib/test/realtime/realtime_presence_history_test.dart
  • test_integration/lib/test/realtime/realtime_presence_subscribe.dart
  • test_integration/lib/test/realtime/realtime_publish_test.dart
  • test_integration/lib/test/realtime/realtime_publish_with_auth_callback_test.dart
  • test_integration/lib/test/realtime/realtime_subscribe.dart
  • test_integration/lib/test/realtime/realtime_time_test.dart
  • test_integration/lib/test/rest/rest_auth_client_id_test.dart
  • test_integration/lib/test/rest/rest_authorize_test.dart
  • test_integration/lib/test/rest/rest_capability_test.dart
  • test_integration/lib/test/rest/rest_create_token_request_test.dart
  • test_integration/lib/test/rest/rest_encrypted_publish_test.dart
  • test_integration/lib/test/rest/rest_history_test.dart
  • test_integration/lib/test/rest/rest_history_with_auth_callback_test.dart
  • test_integration/lib/test/rest/rest_presence_get_test.dart
  • test_integration/lib/test/rest/rest_presence_history_test.dart
  • test_integration/lib/test/rest/rest_publish_test.dart
  • test_integration/lib/test/rest/rest_publish_with_auth_callback_test.dart
  • test_integration/lib/test/rest/rest_request_token_test.dart
  • test_integration/lib/test/rest/rest_time_test.dart
  • test_integration/lib/test_dispatcher.dart
  • test_integration/lib/utils/data.dart
  • test_integration/lib/utils/encoders.dart
  • test_integration/lib/utils/realtime.dart
  • test_integration/lib/utils/rest.dart
  • test_integration/pubspec.yaml
  • test_integration/test_driver/runner.dart
  • test_integration/test_driver/test_implementation/basic_platform_tests.dart
  • test_integration/test_driver/test_implementation/crypto_tests.dart
  • test_integration/test_driver/test_implementation/helper_tests.dart
  • test_integration/test_driver/test_implementation/realtime_tests.dart
  • test_integration/test_driver/test_implementation/rest_tests.dart
  • test_integration/test_driver/test_implementation/utils.dart
  • test_integration/test_driver/tests_abstract.dart
  • test_integration/test_driver/tests_config.dart

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@sacOO7

sacOO7 commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Tracking the native bump (RTS4c-e release errors, endpoint), the agent identifiers and a few 2.0 doc/API polish items for this release in #611.

@maratal maratal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some merge conflicts

ttypic and others added 13 commits November 2, 2026 09:38
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>
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>
@ttypic
ttypic merged commit d73f376 into main Nov 2, 2026
9 of 10 checks passed
@ttypic
ttypic deleted the integration/v2 branch November 2, 2026 10:24

This branch was successfully deployed

2 active deployments
staging/pull/606/features — f385ea65 Deployed Nov 2, 2026 by github-actions[bot]
staging/pull/606/dartdoc — f385ea65 Deployed Nov 2, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants