Repository navigation
1.14.0
Native ads: migration required
MHPlatform 1.14.0 adopts GoogleMobileAdsWrapper 2.0.0 and replaces the old native-ad size API with layout choices. This is an explicitly documented breaking transition within a minor release. There are no compatibility aliases.
| Previous API | Replacement |
|---|---|
MHNativeAdSize.small |
MHNativeAdLayout.compact |
MHNativeAdSize.medium |
MHNativeAdLayout.media |
runtime.nativeAdView(size:) |
runtime.nativeAdView(layout:) |
MHRuntimeNativeAdViewFactory.makeView(size:) |
MHRuntimeNativeAdViewFactory.makeView(layout:) |
// Before
runtime.nativeAdView(size: .small)
runtime.nativeAdView(size: .medium)
// After
runtime.nativeAdView(layout: .compact)
runtime.nativeAdView(layout: .media)Custom native-ad factory closures now receive MHNativeAdLayout and are @MainActor. Call makeView(layout:) on the main actor as well, matching SwiftUI view creation. Update stored selection properties, picker tags, and switches accordingly. Consumers do not need to import Google SDK types.
If an app persists the old enum raw values, migrate "small" to "compact" and "medium" to "media" before decoding MHNativeAdLayout. MHPlatform does not automatically rewrite app-owned preferences.
The adapter waits for shared SDK initialization before requesting ads. The code-built views use the available width and natural height, with compact text and media-forward layouts. Apps retain ownership of backgrounds, padding, placement, and optional frame constraints. Recheck any fixed heights chosen for the previous Small or Medium layouts.
Consent orchestration and Privacy Options integration are not enabled automatically by this update. Complete applicable consent and audience configuration before starting the runtime or displaying ads. Shared orchestration remains tracked in #14; per-app integration remains separate work.
Preferences and startup
This release also includes the preference improvements accumulated since 1.13:
- Add
MHPreferenceRegistryand synchronous startup migration, with async-only step rejection before migration or cleanup begins. - Add explicit defaults-selection initializers for preference and deep-link stores.
- Include domain cleanup allowlists in diagnostics.
- Document descriptor-first migration, external raw-key preservation, startup ordering, and enum-backed
AppStorageshorthand.
Read the preference migration guide before enabling migration or whole-domain cleanup. Existing destination values remain protected; callers own the complete storage allowlist and serialization of migration runs.
Dependencies
| Dependency | Resolved version |
|---|---|
| GoogleMobileAdsWrapper | 2.0.0 (updated) |
| Google Mobile Ads SDK | 13.10.0 (updated) |
| SwiftLintPlugins | 0.65.1 (updated) |
| StoreKitWrapper | 1.4.0 (already current) |
| LicenseList | 2.5.0 (minimum raised to refresh older consumer resolutions) |
| Google User Messaging Platform | 3.1.0 (already current) |
Versioning
Releases now use MAJOR.MINOR.PATCH. Automatic releases increment the minor number and reset patch to zero; the next automatic release after this one is 1.15.0. Manual workflow dispatch supports explicit major or patch releases. Legacy two-component tags are normalized for version selection, and rerunning an already tagged commit does not publish a second release.
Following the 1.14.0 transition exception above, incompatible public API changes require a major release.
Verification
- iOS package tests: 342 passed, zero failures; one non-iOS-only test is not applicable to the iOS run.
- Package build including test targets, macOS umbrella build, and watchOS Simulator umbrella build passed.
- SwiftLint, model-directory rules, and all five consumer fixture checks passed.
- Eight isolated Git-based release-version tests passed.
- Example Simulator smoke: actual Google test ad displayed through Compact → Media → Compact with natural List sizing; final Example build passed with current dependencies and no actor-isolation warning.
The final iOS package test used official xcodebuild after the Xcode integration timed out and disconnected. Real-device, purchase/restore, production consent, and full ad-policy validation are outside this release's targeted verification. An adjacent unavailable-subscription row appeared blank in the Example Simulator; this was recorded separately from the successful ad layout check.