Stability Audit
Crash & Error Handling
- Review crash-free rate trends in crash reporting (Xcode Organizer) and triage top crashers
- Audit force-unwraps (!), try!, and as! casts in recently-changed and high-traffic code paths
- Verify error paths in async throws data controller methods surface gracefully (no silent failures / no fatal errors)
- Check Core Data save/fetch error handling in WMFCoreDataStore and its callers
- Review notification (WMFNSNotification) observers for stale / dangling references
Concurrency & Memory
- Audit for Swift 6 strict-concurrency violations and data races (especially mutable state on non-isolated classes)
- Check for retain cycles — Task { } capturing self strongly in view models without [weak self]
- Verify Task cancellation on deinit / onDisappear for in-flight requests
- Run with Address Sanitizer / Thread Sanitizer / Main Thread Checker enabled
- Look for main-thread blocking (synchronous network / disk on the UI thread)
- Run app with Core Data Concurrency launch argument, see if Xcode complains while running.
Lifecycle & Edge Cases
- Test offline / flaky-network behavior across major flows
- Test low-storage and low-memory (memory warning) scenarios
- Test app backgrounding / foregrounding mid-operation, deep-link cold starts
- Verify behavior across language variants and RTL languages
Performance Audit
- Expand on database population, create large database of article tabs, saved articles and see if performance lags.
Launch & Responsiveness
- Measure cold / warm launch time; profile with Instruments (App Launch template)
- Identify expensive work on the main thread during startup
- Audit scroll performance (hitches / jank) in key List / UICollectionView screens
Memory & Resources
- Profile for memory leaks and abandoned memory (Instruments — Leaks / Allocations)
- Audit image loading / caching (WMFImageDataController) for oversized images and cache growth
- Check Core Data fetch sizes — batch limits, faulting, unnecessary full-table loads
Network & Data
- Audit redundant API calls; confirm in-memory caching on shared data controllers is used (.shared)
- Verify summary / image fetches are lazy (triggered on row appearance, not all upfront)
- Check payload sizes and unnecessary refetches on navigation (make sure we cancel in-flight network tasks when needed upon navigation)
Binary Size
- Investigate app binary / download size; review App Store Connect app size report and the .ipa App Thinning size report
- Break down size by module/target and asset catalogs to identify the largest contributors
- Audit for unused assets, duplicate resources, and oversized bundled images
- Review third-party dependencies for size impact and removal/replacement opportunities
- Verify build settings (dead code stripping, asset symbol/On-Demand Resources, optimization level)
Battery Drain & Overheating Investigation
Tracking T425655: high battery consumption + device overheating, consistent across features.
- Reproduce with Instruments — Energy Log and the Xcode Energy gauge during a typical browse session
- Capture CPU usage over time (Instruments — Time Profiler / CPU Profiler) while idle on an article and while searching
- Check Metrics in Xcode Organizer (Energy, Disk, Hangs)
- Measure thermal state transitions (ProcessInfo.thermalStateDidChangeNotification) during a debug session
Deliverables
- Prioritized findings list (severity × effort)
- Before / after metrics for any fixes (launch time, crash-free %, memory ceiling)
- Follow-up tickets for items out of scope
Specific things to try
- Hangs - Rewrite toasts into UIKit. (We think the SwiftUI content of toasts clash with system keyboard focus, causing a main thread deadlock) PR
- Hangs - Replace Mantle with Codable (should fix a lot of old Explore hangs) PR
- Hangs - Run database housekeeping task upon launch, so we aren't dependent on BackgroundTasks for cleanup (large local databases can cause hangs for every fetch, which we do extensively across the app) PR
- Crashes - xcode://organizer/crashes/downloadPoint?adamId=324715238&platformId=iOS&installPlatformId=iOS&analyticsPointId=B-f7tQSOUIhUXqtI99HiQS&bundleId=org.wikimedia.wikipedia - If legacy core database setup errors out, delete old database files and run setup again so user creates a new database from scratch.
- Crashes - xcode://organizer/crashes/downloadPoint?adamId=324715238&platformId=iOS&installPlatformId=iOS&analyticsPointId=jsNYLUDvrzzrpSI0dnZQT&bundleId=org.wikimedia.wikipedia - old face detection method seems to start crashing when we went out on Liquid Glass. We should rewrite to image saliency API T229534: iOS13 [Feature] - Look into new image saliency API for better cropping...rewrite into WMFComponents so we can use it on newer screens too. PR
- Crashes - xcode://organizer/crashes/downloadPoint?adamId=324715238&platformId=iOS&installPlatformId=iOS&analyticsPointId=IlhOPmXgL3w27mrDpvg0g&bundleId=org.wikimedia.wikipedia - started crashing when we moved to system navigation bar, ages ago. But maybe it's gotten worse on Xcode 26. Consider removing gesture recognizer customizations in WMFComponentNavigationController
Tech Debt
Unfortunately it seems like a lot of our old list screens, which were stable for a long time, became unstable with Xcode 26. Fixing that would involve rewrites on:
- Explore to SwiftUI (in progress)
- Places list views to SwiftUI
- Saved to SwiftUI (done partially, but we need to rewrite reading lists list view and reading list detail view)
- Search to SwiftUI (already kindof in an old draft PR...but we'l need fix 1-billion conflicts).