knock_flutter 1.1.0
knock_flutter: ^1.1.0 copied to clipboard
A client-side Flutter library to interact with user-facing Knock features, such as feeds.
1.1.0 #
A stabilization release: bug fixes, current Flutter stable tooling, and a working example app. No new features.
Behavior changes #
- New enum values:
KnockMessageDeliveryStatus.bouncedandKnockMessageEngagementStatus.linkClickedwere added so messages with these API values decode. Exhaustiveswitchstatements over these enums need the new cases. - Shared realtime subscriptions:
FeedClients for the same feed channel and user now share one realtime channel. It is joined with the options of the first client that subscribes; each client still fetches its own items with its own options when a realtime update arrives. - Feeds are disposed on user switch: calling
knock.authenticate()with a different user disposes the current API client, its socket and everyFeedClientcreated for the previous user. Create new feeds after switching users. Re-authenticating the same user only updates the token, which is used for subsequent requests and on socket reconnect. FeedClient.feedreturns an empty stream afterdispose()(previously it reconnected and refetched).KnockApiClient.statusevents are delivered synchronously.
Fixed #
- fix:
PreferencesClient.getAll()threw aTypeErroron every response - fix: a feed response that failed to decode left the feed in
NetworkStatus.loadingforever and blocked all later fetches; it now moves toNetworkStatus.error - fix: feed items with content block types this SDK does not know yet no longer fail the whole feed; unknown blocks are skipped
- fix:
markAllAsSeen/markAllAsRead/markAllAsArchivedon a filtered feed no longer reset the feed toNetworkStatus.initial - fix: a failed feed fetch no longer reverts optimistic updates made while it was in flight
- fix: a realtime update that arrives while another feed request is in flight is replayed instead of dropped
- fix: a second
FeedClientfor the same feed channel hit a Phoenix!_joinedOnceassertion, and disposing either client stopped realtime updates for both (see shared realtime subscriptions above) - fix:
FeedClient.dispose()right afterknock.logout()threw, and right afterknock.dispose()opened a new websocket - fix: the socket kept using a stale user token after
authenticate()was called again; the token is now read on every reconnect - fix:
KnockMessagefailed to decode thebounceddelivery status and thelink_clickedengagement status (see new enum values above); unknown engagement statuses are now ignored - fix: ids used in request paths (user, channel, message, preference set) are URL-encoded, and request URLs no longer end with an empty
?# - fix:
KnockApiResponse.decodeResponse()throwsKnockApiExceptionfor an empty body instead of aFormatException - fix: unknown preference channel types are skipped instead of throwing
StateError - fix:
KnockApiClient.dispose()can be called more than once - fix:
json_annotationfloor kept at^4.9.0so the package resolves on the minimum supported Flutter (3.32)
Changed #
- chore: regenerate all generated code with freezed 4 (the checked-in code was stale freezed v2 output and
build_runnerfailed to compile); upgrade dev tooling (build_runner, json_serializable, mockito, very_good_analysis 11) - chore: example app builds on current Flutter stable (Gradle 9.3.1 / AGP 9.1.0 / Kotlin 2.4.0 / Java 17, firebase_core 4, firebase_messaging 16, iOS 15.0);
flutter_htmlremoved from the example; the google-services plugin is only applied whengoogle-services.jsonis present - ci: pin Flutter, scope workflow permissions, and add format, generated-code, publish dry-run, minimum-Flutter and example build checks
- docs: 1.0.0 described the package as "pure Dart"; it has no native code of its own but still depends on Flutter and the
flutter_timezoneplugin
1.0.0 #
Breaking #
- refactor: remove Pigeon and native plugin code (Android/iOS), convert to pure Dart package.
Push token retrieval is now the consumer's responsibility via
firebase_messagingor similar. - refactor: rename
ApiClienttoKnockApiClient,ApiResponsetoKnockApiResponse,ApiClientStatustoKnockApiClientStatus,ApiErrortoKnockApiException - refactor:
ApiErrorextendeddart:core'sError;KnockApiException implements Exception. This is both a rename and a semantic migration:try/catch/rethrow/Future.onErrorcode that depended onError/ApiErrorwill not behave the same unless updated toKnockApiException(or a broadExceptioncatch). - refactor:
Feed.initialState()now starts withNetworkStatus.initialinstead ofready, so UIs must not infer “already loaded successfully” solely fromNetworkStatusbefore the first HTTP response. Preferfeed.requestInFlight/ explicit handling forinitial,loading,fetchMore,error, andready. - chore: Dart SDK
>=3.8.0, Flutter>=3.32.0(seepubspec.yaml).
Added #
- feat: add
NetworkStatus.initialand use it fromFeed.initialState()before the first fetch - feat: add public
FeedClient.dispose()for deterministic resource cleanup (subscriptions, Phoenix listeners, event stream). Call when abandoning a feed (e.g. route dispose);knock.dispose()handles theKnockinstance broadly.
Fixed #
- fix: cache
PhoenixSocketinstance in socket getter (every access previously created a new connection) - fix: prevent
StateErrorcrash on closed_eventControllerinFeedClient - fix: trigger initial HTTP fetch in
onListenwithout relying onopenStreamBehaviorSubject replay - fix: close connected socket before dispose for clean WebSocket disconnect
- fix: close
_statusStreamControlleron dispose to prevent resource leak - fix: prevent channel join assertion crash (
!_joinedOnce) on quick unsubscribe/re-subscribe - fix: add defensive cancel before re-subscribing to channel messages
- fix: guard
_onNewMessageReceivedagainst post-disposal processing
Changed #
- chore: upgrade dependencies (freezed v3, phoenix_socket ^0.8.0, json_serializable ^6.13, SDK >=3.8.0)
- test: remove duplicate User tests from channel_test.dart
0.1.8 #
- fix: Replace deprecated
flutter_native_timezonewith maintainedflutter_timezonefork to resolve Android build failures - fix: Use
toLanguageTag()instead oftoString()for locale formatting to fix iOS 422 invalid_request_error (e.g.,it-ITinstead ofit_IT)
0.1.7 #
- feat: Update AppDelegate.swift to request push permissions
- feat(KNO-10078): replace tokens array with devices array containing token, locale, and timezone
0.1.6 #
- fix: Adding
ApiResponsetoApiErrorto provide more context
0.1.5 #
- fix: add
renderedproperty toTextContentBlock
0.1.4 #
- fix: ensure preferences can handle both conditions and channel types
0.1.3 #
- feat: add new ContentBlock types to FeedItem
0.1.2 #
- feat: add new methods for registering and deregistering channel data
0.1.1 #
- fix: Feed correctly observes new messages from the Knock API.
0.1.0 #
- Initial release of the Knock Flutter SDK.