-
Notifications
You must be signed in to change notification settings - Fork 18
Release 2.14.2 #605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Release 2.14.2 #605
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…acks and states. New trim DB size if needed. (#594) * WMSDK-510: Remove fatal error through loadPersistentStores, add fallbacks and states. New trim DB size if needed.
* Bump SDK version from 2.14.0-rc to 2.14.0 * Bump SDK version from 2.14.0 to 2.14.1 * Squashed commit of the SwiftLint fix: commit d750caa Author: Sergei Semko <[email protected]> Date: Tue Sep 9 09:35:57 2025 +0300 Fix SwiftLint: rename deprecated rule, remove fixed TODO (#593) --------- Co-authored-by: Anka <[email protected]> Co-authored-by: Andrey Emtsov <[email protected]> Co-authored-by: Anka <runner@sjc22-bt152_f59a9438-c2d6-4ed9-a6dc-2dc678af9bac-4EBB0FD1AACF.local> Co-authored-by: Sergei Semko <[email protected]>
* WMSDK-518: Introduce `DataBaseLoading` protocol + in-memory fallback; refactor loader; add contract tests
- Add `DataBaseLoading` protocol (`loadPersistentContainer` / `makeInMemoryContainer` / `destroy`).
- Make `DataBaseLoader` conform to the protocol.
- Startup flow: on-disk load → destroy+retry → in-memory fallback; no fatalError on loader init.
- DI: register `DataBaseLoading`; use `StubLoader` on init failure (assertionFailure in DEBUG).
No Core Data model changes; no public API changes beyond introducing the protocol.
* WMSDK-518: Introduce DatabaseRepository protocol; wire DI; Noop fallback; remove fatalError in injection
- Add DatabaseRepository protocol:
- Lifecycle/limits: `limit`, `lifeLimitDate`, `deprecatedLimit`, `onObjectsDidChange`.
- Metadata: `infoUpdateVersion`, `installVersion`, `instanceId`.
- CRUD: `create(event:)`, `readEvent(by:)`, `update(event:)`, `delete(event:)`.
- Queries/maintenance: `query(fetchLimit:retryDeadline:)`, `removeDeprecatedEventsIfNeeded()`, `countDeprecatedEvents()`, `erase()`, `countEvents()`.
- Convenience default: `query(fetchLimit:)` uses `Constants.Database.retryDeadline`.
- Make the existing Core Data repository conform to DatabaseRepository.
- DI/Composition: depend on `DatabaseRepository` instead of a concrete class.
- On construction failure, inject a safe Noop `StubDatabaseRepository` (logs via MindboxLogger; `assertionFailure` in DEBUG).
- Remove `fatalError` from repository injection paths to avoid startup crashes and allow graceful degradation.
Notes
- No Core Data model changes.
- Public API impact limited to adding the DatabaseRepository protocol and conformances.
- DatabaseLoader changes and tests will follow in separate commits.
* WMSDK-518: Harden `DatabaseLoader`: low-disk guard, read-only metadata salvage, destroy+retry, in-memory fallback
- Add low-disk gate: compute free space via filesystem attributes and bail out to in-memory store if `freeSize < diskSpaceRepairThreshold` (300 MB) without touching on-disk store.
- Implement read-only metadata salvage (`NSReadOnlyPersistentStoreOption: true`) to preserve `install`, `infoUpdate`, `instanceId` before any destructive action; re-apply metadata to the new/retried store.
- Define clear startup flow:
1. try loadPersistentStores() → return on success;
2. on failure → salvage metadata;
3. if low disk → in-memory fallback (no destroy);
4. else destroy on-disk store and retry loading;
5. if retry fails → in-memory fallback.
- Centralize Core Data store options in `applyStandardOptions`: synchronous add, `NSFileProtectionNone`, automatic/inferred migration.
- `destroy()` uses `destroyPersistentStore` (iOS 15+ / legacy path for older OSes) and logs before/after states.
- Keep `StubLoader` for DI fallback; no `fatalError` paths in loader code.
* WMSDK-518[Test]: Refactor unit tests to `DatabaseRepository` protocol; add `NoopDatabaseRepository` & retry semantics coverage
- Migrate tests from concrete `MBDatabaseRepository` to the `DatabaseRepository` protocol
- Update test fixtures/factories to accept `DatabaseRepository` instead of `MBDatabaseRepository`
- Add a dedicated test suite for `NoopDatabaseRepository`
- Verify CRUD methods are no-ops and never throw
- Assert `countEvents()` and `countDeprecatedEvents()` return `0`
- Assert metadata getters return `nil` and setters are safe (no crash, no side effects)
- Ensure `erase()` is a no-op and safe to call repeatedly
- Update `Event` contract in tests to cover retry support
- Extend fixtures with `retryTimestamp: TimeInterval`
- Add computed `isRetry` and pin its behavior:
- `isRetry == false` when `retryTimestamp == 0` (new/default events)
- `isRetry == true` when `retryTimestamp != 0` (after update)
- Use a fixed clock/deterministic timestamps to avoid flakiness
- Notes
- Test-only changes; no production code or Core Data model changes
- Prepares the suite for the new loader/fallback flow by decoupling tests from the concrete repository
* WMSDK-518: Replace `fatalError` with `assertionFailure`; fall back to `UserDefaults.standard` when `UserDefaults(suiteName:)` returns `nil`
- Avoids a hard crash in production while still surfacing the problem in debug.
- Keeps the app functional if the App Group identifier is missing/misconfigured.
- Adds a guard around UserDefaults(suiteName:) and returns `.standard` on failure.
* WMSDK-518: Add DatabaseLoader flow tests; keep integration suite
- Add `DatabaseLoaderFlowTests` with Spy subclass to cover all branches:
- straight success (no salvage/destroy),
- load failure + low disk → in-memory + metadata applied,
- load failure + enough disk → destroy+retry + metadata applied,
- repair failure → in-memory fallback.
* WMSDK-518: Prune in-memory Core Data store on memory warnings; safe observer lifecycle and refactor `DatabaseRepository` injection
- Add memory-warning handling to `MBDatabaseRepository` that’s enabled **only** for the
`NSInMemoryStoreType` store.
- Subscribe to `UIApplication.didReceiveMemoryWarningNotification` (`queue: .main`) in `init`
and remove the observer in `deinit`.
- On warning:
- Create a background context and aggressively prune all `CDEvent` rows
(`includesPropertyValues = false`), then `save()` and `reset()` the context.
- Fire `onObjectsDidChange` on the **main** queue after pruning completes.
- Guard against re-entrancy with `isPruningOnWarning`; reset the flag on the main queue
once the prune finishes.
- No-op for SQLite-backed stores (warning is ignored there).
- Keep the main thread lightweight: the heavy work is performed on a background context;
main is used only to enqueue the job and deliver the callback.
Tests:
- Add `MBDatabaseRepositoryMemoryWarningTests` covering:
- `test_InMemory_PrunesAll_OnMemoryWarning` — in-memory store is fully pruned on warning.
- `test_SQLite_IgnoresMemoryWarning` — SQLite store ignores warning.
- `test_InMemory_PruneIsIdempotent_WhenWarningsBurst` — multiple warnings don’t double-prune.
Notes:
- No public API changes. Behavior is active only when the SDK runs with the in-memory fallback,
reducing OOM risk by shedding data under pressure.
* WMSDK-518: Correcting code review comments
* WMSDK-518: Add groups for database files
…amp` (#599) Previously we saved the current time (`Date().timeIntervalSince1970`). Now we persist the timestamp from `Event.enqueueTimeStamp` so the record reflects the actual enqueue time. Event model was not changed.
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
WMSDK-533: Add stopwatch use
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
… (UserDefaults) (#603) * WMSDK-543: feat(migration): migrate CoreData metadata to PersistenceStorage - Move metadata handling out of `DatabaseRepositoryProtocol` and into a dedicated `DatabaseMetadataMigration`. - Read/write metadata directly via `store.metadata` (through `MBDatabaseRepository persistentContainer`) inside the migration—no public getters/setters on the protocol. - Make the migration idempotent: - isNeeded checks that target PersistenceStorage fields are empty and source metadata keys exist. - Safely clears keys via metadata update (no-op if store is unavailable). - Document the repair & preservation flow with SwiftDoc: - `salvageMetadataFromOnDiskStore()`, `applyMetadata(_:to:)`. `loadPersistentContainer()`. `destroy()`. and `makeInMemoryContainer()`. - Naming: prefer suffix style for migrations; e.g. ShownInAppIDsMigration. * WMSDK-543: Refactor and adding unit tests * WMSDK-543: feat(migration): support cleanup-only run and refine `isNeeded` for CoreData → UserDefaults metadata - Add “cleanup-only” path to DatabaseMetadataMigration: - If destination (PersistenceStorage) already has values but Core Data metadata still contains keys, migration runs only to clear metadata on the store. - Refine `isNeeded`: - true if copy is needed (destination is nil and metadata exists), OR - true if cleanup is needed (destination is set and metadata still exists). - Make `run()` idempotent and safe: - Write to PersistenceStorage only when destination fields are nil. - Always clear both metadata keys to avoid future re-triggers. - Keep version = 3 (no change in migration ordering). - Tests: - Added coverage for cleanup-only, copy-only, partial-copy, idempotence, and no-op when nothing to migrate. - Minor: avoid accidentally storing Optional<T> into metadata dictionary. Why: - On first launch the app may fall back to InMemory and migrate there; a later on-disk launch could still carry stale metadata. Cleanup-only ensures the store is sanitized without overwriting destination values. * WMSDK-543: Fix comments Change `eraseApplicationInfoUpdateVersionAndInstanceId` to `eraseMetadata`, fix comments and add docs * WMSDK-543: MetadataMigration without `MBDatabaseRepository`
justSmK
approved these changes
Oct 9, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Updates the release version to 2.14.2. Automated PR: merge release/2.14.2 into master