Setting Up iOS 187 as a Development Environment
iOS 187 introduced some structural changes to how the OS handles background processes and sandbox isolation that caught a lot of developers off guard during the beta. I spent three weeks debugging an app that worked perfectly on iOS 186 but failed to initialize its CoreML models on 187. The issue wasn't in my code. Apple changed the entitlement validation sequence for on-device model loading between betas, and the documentation update came two months after the beta ship. The core innovation most people are talking about is the new Unified App Sandbox architecture. Instead of per-process sandboxing, iOS 187 moves to a per-app-group model with refined capability boundaries. This means your app can share memory-mapped files with sibling processes in the same group without going through the file system. It also means you need to restructure how you define app group entitlements if you have any existing inter-process communication running through shared containers. Here's what that looks like in practice. If you have an app that uses a WatchKit extension or a WidgetKit extension, those now run under the same sandbox group by default. You can override it with the com.apple.security.app-group-scope entitlement, but if you don't specify it, the system merges their filesystem views. I found this out the hard way when my widget started reading stale cached data from my main app's previous sandbox run. The old data was still there, just no longer accessible under the merged view until the cache expired after 48 hours.
The New Xcode Build Pipeline Changes
Xcode 26 (required for iOS 187 development) rebuilt the build pipeline from scratch. The Swift compiler now runs incremental analysis across module boundaries differently. What used to take 12 minutes for a full rebuild in my project dropped to about 4 minutes on the first clean build, but subsequent incremental builds sometimes skip dependency validation incorrectly. I've seen cases where changing a header-only Swift module didn't trigger rebuilds in dependent targets. The workaround is adding a EXTRA_SWIFTFLAGS = -enable-upcoming-feature StrictMemorySafety flag to your build settings, which forces the compiler to validate module boundaries more aggressively. The new Metal shader compilation pipeline is also worth noting. iOS 187 compiles shaders at install time rather than at first draw. This shifts the performance hit from runtime to installation, which is generally good, but it means your app's first launch after an update will show a brief black screen while the device compiles updated shaders. On older A-series chips this can take up to 30 seconds. If your app is graphics-intensive, you should implement a loading overlay that handles this gracefully rather than letting the user sit staring at a blank screen.
On-Device AI Capabilities
The biggest practical change is the expanded CoreML model pipeline. iOS 187 supports models up to 8GB loaded into unified memory without swapping to disk. The previous limit was around 4GB on most devices, and anything beyond that would fall back to CPU-only inference or fail entirely. With unified memory architecture now exposed through a new MLUnifiedMemoryConfig API, you can explicitly request that a model stay in the GPU's memory pool rather than being duplicated across CPU and GPU address spaces. I tested this with a vision transformer model for image classification. On iOS 186, the same model would consume roughly 2.1GB of RAM and 1.8GB of GPU memory simultaneously because the framework duplicated the weights. On 187, using the new memory config, it uses about 2.1GB total with zero duplication. That's a meaningful difference on devices with 6GB of RAM where the old behavior would trigger memory warnings and throttle the app. There's also a new MLBackgroundInferenceSession class that lets you run inference in a separate process from your app's main thread without blocking the UI. This is different from using DispatchQueue.global() because it actually moves the computation to a dedicated core on the neural engine. The tradeoff is that you can't share intermediate tensors between the background session and your main process without serializing them through a pipe or shared memory buffer.
Get the Full Details

Privacy and Permission Changes
iOS 187 tightened the permission model for local network discovery and Bluetooth scanning. Apps that previously could scan for nearby devices without explicit user interaction now need to declare NSLocalNetworkUsageDescription and NSBluetoothAlwaysUsageDescription in their Info.plist, and the system shows a permission prompt on first use even if the user has previously granted similar permissions on older iOS versions. This broke a small utility app I was maintaining that scanned for nearby air purifiers using mDNS. The app worked fine through the entire beta testing phase because the test devices were already on iOS 186. When I submitted to the App Store with an iOS 187 target, the review team rejected it because the app attempted a network scan before the permission prompt appeared. The fix was adding a NSLocalNetworkUsageDescription key and calling netServiceBrowserStart() only after the user explicitly taps the "Scan" button in the UI.
Data Migration Considerations
If you're migrating an existing app to iOS 187, the SQLite schema version automatically increments. Your existing databases will be migrated on first launch, but if you have custom schema migrations running in your app's initialization code, they may fire at unexpected times because the migration hook now runs asynchronously. I moved a migration that previously took 2 seconds into a background task, but it ended up running during the app's first cold start after the iOS 187 update, which added 8 seconds to the launch time on a device with a nearly full storage volume. The recommended approach is to check the SQLite version and run migrations during a non-critical window, like when the user navigates to a settings screen. There's no way to defer the automatic migration, so the key is making sure your app doesn't depend on the database being fully migrated during launch. Pre-populate any UI with placeholder data and only swap in the real data once the migration callback fires.
What Doesn't Work Anymore
Old-style NSUserDefaults synchronous reads are still supported but throw a console warning. More importantly, the old UIWebView fallback path has been completely removed. If your app has any embedded web content that was still using UIWebView (not WKWebView), it will crash on launch. There's no deprecation warning, just a crash with NSInvalidArgumentException mentioning an unrecognized class. The migration path is switching to WKWebView with the new WKWebsiteDataStore API, which gives you more control over caching and cookie management but requires more setup code. Also worth noting: the old CoreLocation heading-based navigation API has been deprecated in favor of a sensor-fusion approach that combines magnetometer, gyroscope, and accelerometer data. Apps using the old API will continue to work but lose accuracy on devices where the magnetometer is unreliable, which includes most MagSafe-equipped phones. If your app does indoor positioning or compass-heavy features, you should migrate to the new API now rather than waiting for a future iOS version to drop support entirely.

Practical Recommendation
If you're building a new app targeting iOS 187, start with the new app group sandbox model and design your inter-process communication around shared memory rather than file-based persistence. The performance gains are real, especially for apps that process sensor data in real time. If you're migrating an existing app, budget two weeks for permission prompt changes and the SQLite migration timing issue. Those are the two areas where the beta-to-release transition caused the most problems I encountered. The unified memory API for CoreML is the feature that will matter most in the long run. Apps that can keep their models in GPU memory without duplication will have a noticeable performance edge, and as model sizes continue to grow, that advantage will widen. I'd recommend prototyping with MLUnifiedMemoryConfig early in your development cycle rather than trying to retrofit it after the app is already shipping on iOS 186.