Skip to content

feat(ios): Implement automatic app restart handling for KDF fatal errors#270

Closed
CharlVS wants to merge 3 commits intodevfrom
feat/ios-crash-restart
Closed

feat(ios): Implement automatic app restart handling for KDF fatal errors#270
CharlVS wants to merge 3 commits intodevfrom
feat/ios-crash-restart

Conversation

@CharlVS
Copy link
Copy Markdown
Collaborator

@CharlVS CharlVS commented Oct 29, 2025

Overview

This PR implements an automatic app restart mechanism for iOS when the Komodo DeFi Framework (KDF) encounters fatal transport errors or receives a shutdown signal. This resolves a critical issue where the app becomes unresponsive after KDF terminates unexpectedly, particularly after backgrounding on iOS.

Problem Statement

On iOS, when KDF terminates unexpectedly (e.g., due to memory pressure during backgrounding), the app often experiences:

  • Broken pipe errors (errno 32) when attempting RPC communication
  • Unresponsive UI with no way to recover without force-quitting
  • Failed authentication attempts due to a non-responsive KDF instance

Solution

Implement native iOS restart handling with intelligent error detection:

  1. Native iOS Plugin (KdfRestartHandler.swift)

    • Handles restart requests via Flutter method channel
    • Gracefully exits app using exit(0) (requires manual user reopen due to iOS limitations)
    • Logs restart reason for debugging
  2. Dart Platform Interface (ios_restart_handler.dart)

    • Singleton pattern for centralised restart handling
    • Platform channel communication with iOS native code
    • Separate methods for broken pipe vs. shutdown signal scenarios
  3. Error Detection in KDF Framework

    • Detects fatal socket errors: EPIPE (32), ECONNRESET (54), ETIMEDOUT (60), ECONNREFUSED (61)
    • Automatically triggers iOS restart on broken pipe detection
    • Resets HTTP client to drop stale keep-alive connections
  4. Shutdown Signal Handling

    • Auth service subscribes to shutdown signal events
    • Triggers restart when shutdown signals received on iOS
    • Ensures clean recovery from KDF termination
  5. Enhanced Event Streaming

    • Configurable debug logging for event processing
    • Performance metrics (event types, processing durations)
    • Better error diagnostics for streaming issues

Technical Details

  • Platform-specific: Only activates on iOS (web and other platforms unaffected)
  • Graceful degradation: Falls back to error logging if restart fails
  • Async/fire-and-forget: Restart requests don't block app execution
  • Retry logic: Auth service retries enabling shutdown stream after KDF startup
  • Single-flight pattern: Health checks prevent concurrent duplicate checks

Testing Notes

  • Tested with app backgrounding scenarios on iOS
  • Verified broken pipe error detection and restart triggering
  • Confirmed shutdown signal handling and restart flow
  • Event streaming debug logging provides visibility into event processing

Related Issues

Fixes issues related to iOS app hangs after backgrounding and KDF termination.

Summary by CodeRabbit

  • New Features
    • Real-time event streaming for market data, including balance updates, orderbook changes, network status, transaction history, and swap/order status.
    • iOS app restart functionality with graceful shutdown signal handling.
    • Enhanced NFT activation with batch enablement and improved error handling.
    • Activated assets caching for improved performance and reduced RPC calls.

Note

Implements an iOS restart mechanism (native + Dart) triggered on fatal transport errors and shutdown signals, with improved streaming/logging and auth health-check handling.

  • iOS Restart Handling:
    • Add native KdfRestartHandler plugin and register via KomodoDefiFrameworkPlugin.
    • Add Dart IosRestartHandler (method channel com.komodoplatform.kdf/restart).
    • In KomodoDefiFramework, detect fatal socket errors (EPIPE/32, etc.), reset HTTP client, and on iOS request app restart; expose handleShutdownSignalForRestart.
  • Auth Service:
    • Subscribe to shutdownSignals; emit sign-out immediately and trigger iOS restart.
    • Retry enabling shutdown stream after KDF starts; refine health-check with single-flight/cooldown and force-restart flow.
  • Event Streaming:
    • Add structured logging and timings for IO (SSE) and Web (SharedWorker) implementations.
    • Improve Web worker: port cleanup on close and error logs; add disconnect logs and error handling.
    • KdfEventStreamingService: debug logging toggle, event processing timing, verbose payload logs, and dispose() wiring in framework.
  • Misc/Logging:
    • More detailed RPC/electrum logs and formatted messages; minor code tidying.

Written by Cursor Bugbot for commit 5e43e83. This will update automatically on new commits. Configure here.

Implement automatic app restart mechanism for iOS when KDF encounters
fatal transport errors or shutdown signals. This resolves issues where
the app becomes unresponsive after KDF terminates unexpectedly.

Changes:
- Add KdfRestartHandler Swift plugin for iOS app restart via exit(0)
- Add IosRestartHandler Dart wrapper with platform channel communication
- Detect broken pipe errors (errno 32) and trigger iOS restart in KDF framework
- Add shutdown signal handling to trigger restart via auth service
- Improve event streaming service with configurable debug logging
- Add retry logic for enabling shutdown stream after KDF startup
- Enhance HTTP client error detection for fatal transport errors

Technical Details:
- iOS restart uses exit(0) requiring manual app reopen (iOS limitation)
- Broken pipe detection covers errno 32, 54, 60, 61 socket errors
- Single-flight health check pattern prevents concurrent checks
- Event streaming service now logs event types and processing times

Fixes app hangs after backgrounding and KDF termination on iOS.
Copilot AI review requested due to automatic review settings October 29, 2025 17:03
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 29, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

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

Walkthrough

This PR introduces a comprehensive event streaming infrastructure for real-time updates across multiple domains (balances, transactions, orderbook, network, shutdown signals), adds iOS restart handling, implements resource lifecycle management (dispose patterns) for repositories and providers, integrates NFT activation services, and adds caching/persistence layers for activated assets and pubkeys.

Changes

Cohort / File(s) Summary
Repository and Provider Lifecycle Management
packages/komodo_cex_market_data/lib/src/cex_repository.dart, packages/komodo_cex_market_data/lib/src/binance/data/binance_repository.dart, packages/komodo_cex_market_data/lib/src/coingecko/data/coingecko_repository.dart, packages/komodo_cex_market_data/lib/src/coinpaprika/data/coinpaprika_cex_provider.dart, packages/komodo_cex_market_data/lib/src/coinpaprika/data/coinpaprika_repository.dart, packages/komodo_cex_market_data/lib/src/sparkline_repository.dart, packages/komodo_cex_market_data/lib/src/bootstrap/market_data_bootstrap.dart, packages/komodo_cex_market_data/test/repository_*.dart
Added explicit dispose() lifecycle methods across repositories and providers; introduced ownership tracking in CoinPaprika provider; wired dispose callbacks to GetIt singleton registrations in bootstrap.
Event Streaming Core Infrastructure
packages/komodo_defi_framework/lib/src/streaming/event_streaming_service.dart, packages/komodo_defi_framework/lib/src/streaming/event_streaming_platform_*.dart, packages/komodo_defi_framework/assets/web/event_streaming_worker.js
Implemented KdfEventStreamingService facade with platform-specific backends (IO, Web, Stub); added SharedWorker for cross-tab event broadcasting; integrated SSE-based real-time event streaming with error handling and logging.
Event Type Definitions
packages/komodo_defi_framework/lib/src/streaming/events/kdf_event.dart, packages/komodo_defi_framework/lib/src/streaming/events/*_event.dart
Introduced sealed KdfEvent base class with factory-based JSON parsing; defined nine concrete event types (Balance, Orderbook, Network, Heartbeat, SwapStatus, OrderStatus, Task, TxHistory, ShutdownSignal) with JSON deserialization and type routing.
RPC Streaming Methods
packages/komodo_defi_rpc_methods/lib/src/rpc_methods/streaming/*.dart, packages/komodo_defi_rpc_methods/lib/src/rpc_methods/rpc_methods.dart
Added streaming RPC request/response classes for enable/disable operations; implemented StreamingMethodsNamespace with enable/disable methods for all event types; integrated with streaming utilities and error handling.
Configuration & Framework Updates
packages/komodo_defi_framework/lib/src/config/event_streaming_config.dart, packages/komodo_defi_framework/lib/src/config/kdf_startup_config.dart, packages/komodo_defi_framework/lib/komodo_defi_framework.dart, packages/komodo_defi_framework/pubspec.yaml
Added EventStreamingConfiguration with asset path and CORS settings; integrated into KdfStartupConfig; exposed streaming service and dispose/restart APIs in main KDF facade; added flutter_client_sse dependency.
iOS Platform Integration
packages/komodo_defi_framework/ios/Classes/KdfRestartHandler.swift, packages/komodo_defi_framework/ios/Classes/KomodoDefiFrameworkPlugin.swift, packages/komodo_defi_framework/lib/src/platform/ios_restart_handler.dart
Introduced iOS app restart handler via MethodChannel; implemented graceful shutdown simulation with delayed process exit; wired platform channel for Dart-to-native restart requests.
Authentication & Health Checks
packages/komodo_defi_local_auth/lib/src/auth/auth_service*.dart
Enhanced KdfAuthService with user list caching (5-min TTL), shutdown signal subscription/handling, improved health check interval (5-min), added isImported metadata tracking, and restart delegation for shutdown signals.
Asset Activation & Caching
packages/komodo_defi_sdk/lib/src/activation/activation_manager.dart, packages/komodo_defi_sdk/lib/src/activation/activation_exceptions.dart, packages/komodo_defi_sdk/lib/src/assets/activated_assets_cache.dart, packages/komodo_defi_sdk/lib/src/assets/asset_manager.dart
Introduced ActivatedAssetsCache with TTL-based memoization; added activation exception hierarchy; integrated cache into ActivationManager/AssetManager for centralized active asset tracking; added forceRefresh parameter to asset activation checks.
NFT Activation Service
packages/komodo_defi_sdk/lib/src/activation/nft_activation_service.dart
Created NftActivationService for batch NFT activation with retry/backoff support, error aggregation, and cache invalidation on success.
Pubkey Storage & Persistence
packages/komodo_defi_sdk/lib/src/pubkeys/hive_pubkeys_adapters.dart, packages/komodo_defi_sdk/lib/src/pubkeys/pubkeys_storage.dart, packages/komodo_defi_sdk/lib/src/pubkeys/pubkey_manager.dart
Implemented Hive-backed pubkey persistence (HiveStoredPubkey, HiveAssetPubkeysRecord, adapters); added PubkeysStorage interface; integrated hydration and background refresh in PubkeyManager with in-flight deduplication.
Balance & Transaction History Streaming
packages/komodo_defi_sdk/lib/src/balances/balance_manager.dart, packages/komodo_defi_sdk/lib/src/transaction_history/transaction_history_manager.dart, packages/komodo_defi_sdk/lib/src/transaction_history/transaction_storage.dart
Integrated EventStreamingManager for real-time balance/tx updates with polling fallback; added AssetHistoryStorage for first-time asset tracking; improved transaction ordering and storage merging for consistent SplayTreeMap construction.
Protocol & Asset Type Support
packages/komodo_defi_types/lib/src/assets/asset.dart, packages/komodo_defi_types/lib/src/coin_classes/protocol_class.dart, packages/komodo_defi_types/lib/src/generic/sync_status.dart, packages/komodo_defi_types/lib/src/transactions/transaction_history_strategy.dart
Added streaming support checks (supportsBalanceStreaming, supportsTxHistoryStreaming) per asset/protocol; improved SyncStatusEnum parsing with backward compatibility; added requiresKdfTransactionHistory method to transaction history strategies.
Activation Strategies
packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/*.dart
Updated ETH/ZHTLC/UTXO strategies to compute txHistoryFlag based on streaming support and use Etherscan helper; implemented requiresKdfTransactionHistory override for Etherscan (false) and ZHTLC (true) strategies.
SDK Bootstrap & Configuration
packages/komodo_defi_sdk/lib/src/bootstrap.dart, packages/komodo_defi_sdk/lib/src/komodo_defi_sdk.dart, packages/komodo_defi_sdk/lib/src/sdk/komodo_defi_sdk_config.dart
Wired EventStreamingManager, ActivatedAssetsCache, NftActivationService into dependency injection; added streaming/cache accessors and waitForEnabledAssetsToPassThreshold methods; added activatedAssetsCacheTtl configuration parameter; integrated disposal cleanup.
Build Configuration & Utility Updates
packages/komodo_defi_framework/app_build/build_config.json, packages/komodo_coin_updates/lib/src/coins_config/_coins_config_index.dart, packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/rpc_task_shepherd.dart, packages/komodo_wallet_cli/bin/update_api_config.dart
Updated API checksums and commit hashes for all platforms; renamed coins_config library to named private variant; added documentation for event-based task watching; improved API config update logic for commit hash changes.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant KDF as KdfEventStreamingService
    participant Plat as Platform (Web/IO/Stub)
    participant RPC as KomodoDefiRpcMethods
    participant Worker as SharedWorker (Web)
    
    App->>KDF: initialize()
    KDF->>Plat: connectEventStream(onMessage)
    
    alt Web Platform
        Plat->>Worker: Create SharedWorker
        Worker-->>Plat: Port connected
        Plat->>Worker: port.start()
    else IO Platform
        Plat->>Plat: Establish SSE connection
    end
    
    RPC->>KDF: Enable stream (stream::balance::enable)
    RPC-->>KDF: streamerId
    
    loop Real-time events
        Worker->>Plat: Broadcast message to all ports
        Plat->>Plat: onMessage(eventData)
        Plat->>KDF: Forward event
        KDF->>KDF: Parse KdfEvent (fromJson)
        KDF->>KDF: Route to typed stream (balanceEvents)
        KDF-->>App: Emit BalanceEvent
    end
    
    App->>KDF: dispose()
    KDF->>Plat: unsubscribe()
    Plat->>RPC: stream::disable
Loading
sequenceDiagram
    participant SDK as KomodoDefiSdk
    participant Cache as ActivatedAssetsCache
    participant Auth as KomodoDefiLocalAuth
    participant RPC as ApiClient
    participant Act as ActivationManager
    
    SDK->>Cache: Create with TTL
    Cache->>Auth: Subscribe to auth changes
    
    loop Asset Activation Check
        SDK->>Act: isAssetActive(assetId, forceRefresh: true)
        Act->>Cache: getActivatedAssetIds(forceRefresh: true)
        
        alt Cache valid and not forced
            Cache-->>Act: Return cached assets
        else Cache expired or forced refresh
            Cache->>RPC: getEnabledCoins()
            RPC-->>Cache: Enabled coins list
            Cache->>Cache: Map to AssetId set
            Cache->>Cache: Update cache + timestamp
            Cache-->>Act: Return fresh assets
        end
        
        Act-->>SDK: true/false
    end
    
    Auth->>Cache: User signed out
    Cache->>Cache: invalidate()
Loading
sequenceDiagram
    participant App as Application
    participant BM as BalanceManager
    participant ESM as EventStreamingManager
    participant Stream as Event Stream (balance_events)
    participant Fallback as Polling
    
    App->>BM: watchBalance(asset)
    BM->>BM: Emit lastKnown balance (from cache)
    
    alt Supports Balance Streaming
        BM->>ESM: subscribeToBalance(coin)
        ESM->>Stream: Enable stream
        Stream->>Stream: Real-time updates
        Stream-->>ESM: balanceEvent
        ESM-->>BM: StreamSubscription
        BM->>BM: Cache + emit balance
    else Streaming unavailable
        BM->>Fallback: Start polling
        Fallback->>Fallback: Periodic RPC calls
    end
    
    App->>BM: dispose()
    BM->>ESM: Cancel subscription
    BM->>Fallback: Stop polling
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Areas requiring extra attention:

  • EventStreamingService & platform-specific implementations — New streaming infrastructure with multiple platform-specific backends (Web/IO/Stub), event parsing/routing logic, and error handling; verify platform detection, SharedWorker compatibility, and SSE connection lifecycle.
  • Event type hierarchy and JSON deserialization — Sealed KdfEvent base class with factory-based routing; verify all 9 event types parse correctly, handle malformed payloads gracefully, and route to appropriate typed streams without data loss.
  • ActivatedAssetsCache TTL & invalidation logic — Complex caching with generation-counter-based in-flight request invalidation, TTL expiry checks, and auth state subscription; verify cache coherency, no stale data leaks, and proper cleanup on auth changes.
  • BalanceManager & TransactionHistoryManager streaming integration — Both extensively refactored to support streaming with polling fallback, asset history storage, and multi-subscription management; verify subscription lifecycle, no resource leaks, error recovery paths, and consistent cache invalidation.
  • Pubkey persistence & hydration — New Hive adapters and storage layer; verify correct type serialization, async hydration flow, in-flight deduplication, and no concurrent access issues.
  • iOS restart handler implementation — New iOS native code with MethodChannel bridging and delayed process exit; verify platform channel setup, error handling on unsupported platforms, and restart signal propagation.
  • Bootstrap DI wiring — Significant changes to dependency injection graph with new EventStreamingManager, ActivatedAssetsCache, and NftActivationService; verify no circular dependencies, proper initialization order, and cleanup on disposal.
  • Transaction storage SplayTreeMap merging — Complex refactoring of transaction ordering logic to merge existing and new transactions before map construction; verify no stack overflow on large transactions, proper comparator behavior, and consistent ordering.

Possibly related issues

Possibly related PRs

Suggested labels

enhancement, streaming, lifecycle-management, caching, platform-integration

Poem

🐰 Streams now flow through the warren,
Events dance from dawn to dawn,
Caches hum with whispered grace,
Restarts bloom in iOS space—
Life and death in perfect time,
A choreography sublime!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The pull request title states "feat(ios): Implement automatic app restart handling for KDF fatal errors" and correctly references the iOS restart handler implementation that is present in the changeset. However, examining the raw summary reveals that the iOS restart functionality represents only a small fraction of the actual changes. The dominant portions of this changeset involve extensive event streaming infrastructure (multiple streaming event classes, platform implementations, RPC methods), balance and transaction history streaming integration throughout BalanceManager and TransactionHistoryManager, activated asset caching with ActivatedAssetsCache, NFT activation services, auth service enhancements with user caching and health checks, and lifecycle/disposal improvements across repositories. The title accurately describes a real component of the changeset but fails to capture or reflect the primary scope and complexity of the changes, which are substantially broader than iOS restart handling alone. Revise the title to reflect the dominant changes in the changeset. Consider a title such as "feat: Add event streaming infrastructure, asset caching, and iOS auto-restart" or "feat: Implement real-time streaming events and asset management improvements" to accurately represent the scope of event streaming, asset activation caching, and iOS restart handling that together constitute the main body of work in this PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@CharlVS CharlVS changed the base branch from main to dev October 29, 2025 17:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements real-time event streaming infrastructure for the Komodo DeFi Framework, significantly reducing RPC polling overhead and improving responsiveness across balance updates, transaction history, and other features.

Key changes:

  • Adds Server-Sent Events (SSE) streaming on native platforms and SharedWorker-based streaming on Web
  • Implements transaction history streaming with automatic fallback to polling when streaming is unavailable
  • Adds balance event streaming with intelligent fallback mechanisms
  • Introduces activated assets cache to reduce repeated get_enabled_coins RPC calls
  • Implements optimizations for new wallet creation to avoid unnecessary RPC spam
  • Adds iOS app restart handling for KDF fatal errors and shutdown signals

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/komodo_defi_framework/lib/src/streaming/* New SSE/SharedWorker streaming infrastructure with platform-specific implementations
packages/komodo_defi_sdk/lib/src/streaming/event_streaming_manager.dart High-level streaming manager with reference counting and lifecycle management
packages/komodo_defi_sdk/lib/src/transaction_history/transaction_history_manager.dart Updated to use streaming with fallback to polling
packages/komodo_defi_sdk/lib/src/balances/balance_manager.dart Updated to use balance streaming with stale-guard timers
packages/komodo_defi_sdk/lib/src/assets/activated_assets_cache.dart New TTL-based cache for activated assets list
packages/komodo_defi_local_auth/lib/src/auth/auth_service.dart Enhanced with shutdown signal streaming and improved health checks
packages/komodo_defi_sdk/lib/src/transaction_history/transaction_storage.dart Fixed SplayTreeMap comparison to prevent stack overflow
packages/komodo_wallet_cli/bin/update_api_config.dart Updated checksum replacement logic for API commit changes
Comments suppressed due to low confidence (3)

packages/komodo_defi_local_auth/lib/src/auth/auth_service_operations_extension.dart:19

  • The comment states 'Reduced from 5 minutes to 30 minutes' but the code shows Duration(minutes: 5). The duration should be 30 minutes to match the comment, or the comment should be updated to reflect the actual 5-minute interval.
      const Duration(minutes: 5),

packages/komodo_defi_local_auth/lib/src/auth/auth_service_operations_extension.dart:115

  • [nitpick] The comment on line 114 says 'Bypass cached user' but the method name _getActiveUser() is not visible in this diff. Consider adding a comment clarifying that this internal method bypasses the cache, or ensure the method name makes this clear.
      final currentUser = await _getActiveUser();

packages/komodo_defi_framework/lib/src/streaming/event_streaming_platform_io.dart:48

  • The RPC password is being passed in the HTTP header, but the comment on line 41-42 mentions KDF expects ?userpass= as a query parameter. This mismatch between comment and implementation could cause authentication issues if the header approach is incorrect.
              'userpass': cfg.rpcPassword,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

https://github.com/KomodoPlatform/komodo-defi-sdk-flutter/blob/67f6e5034f088c234065d4f2ff7c7feccb05793f/packages/komodo_defi_framework/lib/src/streaming/event_streaming_platform_io.dart#L88-L92
P0 Badge Return async unsubscribe from synchronous typedef

The IO implementation declares connectEventStream returns EventStreamUnsubscribe (a void Function()), but the callback it returns is () async { await sub?.cancel(); ... }. An async closure has type Future<void> Function(), which is incompatible with the synchronous typedef, so this file won’t compile. Either make EventStreamUnsubscribe return Future<void> or remove the async/await from the callback.


https://github.com/KomodoPlatform/komodo-defi-sdk-flutter/blob/67f6e5034f088c234065d4f2ff7c7feccb05793f/packages/komodo_defi_framework/lib/src/streaming/event_streaming_platform_io.dart#L12-L18
P1 Badge SSE connection omits required userpass query

The SSE URL produced in _buildEventsUrl never appends the userpass query parameter and the connection later only sends the password as a custom header, even though the comment notes that KDF exposes the credential via ?userpass=. The KDF event-stream endpoint authenticates through the query string, so this request will be rejected (401) and streaming never connects, meaning shutdown events are never delivered. Include the password in the URL’s query parameters (and drop the unused header) before subscribing.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Oct 29, 2025

Visit the preview URL for this PR (updated for commit 5e43e83):

https://komodo-playground--pr270-feat-ios-crash-resta-j0m0gunn.web.app

(expires Thu, 06 Nov 2025 15:13:32 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 2bfedd77fdea45b25ba7c784416e81f177aa5c47

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Oct 29, 2025

Visit the preview URL for this PR (updated for commit 5e43e83):

https://kdf-sdk--pr270-feat-ios-crash-resta-6kvskll4.web.app

(expires Thu, 06 Nov 2025 15:11:35 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 9c1b6e6c010cf0b965c455ba7a69c4aedafa8a1d

@CharlVS CharlVS requested a review from ca333 October 29, 2025 17:52
Move streaming logging to the main logger so that it shows in the log storage.
@CharlVS CharlVS closed this Oct 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants