Description
I am seeing a consistent crash in a NEDNSProxyProvider on iOS when migrating from completion handlers to the new Swift Concurrency async/await variants of readDatagrams() and writeDatagrams() on NEAppProxyUDPFlow.
The crash occurs inside the Swift Concurrency runtime during task resumption. Specifically, it seems the Task attempts to return to the flow’s internal serial executor (NEFlow queue) after a suspension point, but fails if the flow was invalidated or deallocated by the kernel while the task was suspended.
Error Signature
Thread 4: EXC_BAD_ACCESS (code=1, address=0x28)
Thread 4 Queue : NEFlow queue (serial)
#0 0x000000018fe919cc in swift::AsyncTask::flagAsAndEnqueueOnExecutor ()
#9 0x00000001ee25c3b8 in _pthread_wqthread ()
Steps
The crash is highly timing-dependent. To reproduce it reliably:
Use an iOS device with Developer Settings enabled.
Go to Developer > Network Link Conditioner -> High Latency DNS.
Intercept a DNS query and perform a DoH (DNS-over-HTTPS) request using URLSession.
The first few network requests should trigger the crash
Minimum Working Example (MWE)
class DNSProxyProvider: NEDNSProxyProvider {
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
guard let udpFlow = flow as? NEAppProxyUDPFlow else { return false }
Task(priority: .userInitiated) {
await handleUDPFlow(udpFlow)
}
return true
}
func handleUDPFlow(_ flow: NEAppProxyUDPFlow) async {
do {
try await flow.open(withLocalFlowEndpoint: nil)
while !Task.isCancelled {
// Suspension point 1: Waiting for datagrams
let (flowData, error) = await flow.readDatagrams()
if let error { throw error }
guard let flowData, !flowData.isEmpty else { return }
var responses: [(Data, Network.NWEndpoint)] = []
for (data, endpoint) in flowData {
// Suspension point 2: External DoH resolution
let response = try await resolveViaDoH(data)
responses.append((response, endpoint))
}
// Suspension point 3: Writing back to the flow
// Extension will crash here on task resumption
try await flow.writeDatagrams(responses)
}
} catch {
flow.closeReadWithError(error)
flow.closeWriteWithError(error)
}
}
private func handleFlowData(_ packet: Data, endpoint: Network.NWEndpoint, using parameters: NWParameters) async throws -> Data {
let url = URL(string: "https://dns.google/dns-query")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = packet
request.setValue("application/dns-message", forHTTPHeaderField: "Content-Type")
let (data, _) = try await URLSession.shared.data(for: request)
return data
}
}
Crash Details & Analysis
The disassembly at the crash point indicates a null dereference of an internal executor pointer (Voucher context):
ldr x20, [TPIDRRO_EL0 + 0x340]
ldr x0, [x20, #0x28] // x20 is NULL/0x0 here, resulting in address 0x28
It appears that NEAppProxyUDPFlow’s async methods bind the Task to a specific internal executor. When the kernel reclaims the flow memory, the pointer in x20 becomes invalid. Because the Swift runtime is unaware that the NEFlow queue executor has vanished, it attempts to resume on non-existing flow and then crashes.
Checking !Task.isCancelled does not prevent this, as the crash happens during the transition into the task body before the cancellation check can even run.
Questions
Is this a known issue of the NetworkExtension async bridge?
Why does Task.isCancelled not reflect the deallocation of the underlying NEAppProxyFlow?
Is the only safe workaround?
Please feel free to correct me if I misunderstood anything here. I'll be happy to hear any insights or suggestions :) Thank you!
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi, we are developing a screen time management app. The app locks the device after it was used for specified amount of time.
After updating to iOS 26.2, we noticed a huge issue: the events started to fire (reach the threshold) in the DeviceActivityMonitorExtension prematurely, almost immediately after scheduling. The only solution we've found is to delete the app and reboot the device, but the effect is not lasting long and this does not always help.
Before updating to iOS 26, events also used to sometimes fire prematurely, but rescheduling the event often helped. Now the rescheduling happens almost every second and the events keep reaching the threshold prematurely.
Can you suggest any workarounds for this issue?
Based on https://developer.apple.com/documentation/networkextension/nednssettings/searchdomains , we expect the values mentioned in searchDomains to be appended to a single label DNS query. However, we are not seeing this behavior.
We have a packetTunnelProvider VPN, where we set searchDomains to a dns suffix (for ex: test.com) and we set matchDomains to applications and suffix (for ex: abc.com and test.com) . When a user tries to access https://myapp , we expect to see a DNS query packet for myapp.test.com . However, this is not happening when matchDomainsNoSearch is set to true. https://developer.apple.com/documentation/networkextension/nednssettings/matchdomainsnosearch
When matchDomainsNoSearch is set to false, we see dns queries for myapp.test.com and myapp.abc.com.
What is the expected behavior of searchDomains?
What works
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.hidesSharedBackground = true
self.navigationItem.rightBarButtonItem = backButton
// or
self.navigationItem.leftBarButtonItem = backButton
What doesn't work
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.hidesSharedBackground = true
self.navigationItem.backBarButtonItem = backButton
I've tried setting this property on all possible permutations and combinations e.g. Inside navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) and pushViewController(_ viewController: UIViewController, animated: Bool) of a custom UINavigationController to make sure.
Expected vs Actual behavior
Setting hidesSharedBackground = true should remove the glass background from both regular bar button items and back bar button items but it has no effect on backBarButtonItem.
Additional context
I’m aware of the UIDesignRequiresCompatibility Info.plist key, but I’m looking for a programmatic solution if there is one. The goal is to remove the glass background from back buttons.
FB21772424
On any iPhone or iPad running 26.3 beta 3 with UIFileSharingEnabled enabled via Xcode, a file cannot be manually copied to/from macOS or manually deleted from Finder but 26.3 beta 2 works fine running on any iPhone or iPad.
The version of macOS is irrelevant as both macOS 26.2.1 and macOS 26.3 beta 3 are unable to affect file changes via macOS Finder on iPhone or iPad running 26.3 beta 3 but can affect file changes via macOS Finder on iPhone or iPad running 26.2.1
Thank you.
Hello, Developers!
While writing custom view modifier I ran into unexpected behavior of .strokeBorder modifier. The underlying content seem to be “bleeding” outside of the stroke border edges, even though they share the exact same shape for their layout.
This issue relevant for both Xcode Previews and on-device testing.
Maybe someone has experienced this issue before, I'd be glad to see your opinion on this matter.
Hello everyone,
I’m stuck with an App Store Connect issue and would really appreciate any insight from the community.
I am unable to submit my app for review due to the following persistent error:
“Unable to Add for Review – There are still preview uploads in progress.”
What makes this particularly confusing is that there are no previews currently uploading.
Here is everything I have already tried:
Deleted all App Preview videos and all screenshots
Confirmed Media Manager shows no active uploads
Re-uploaded App Preview videos fully compliant with Apple specs:
H.264
AAC stereo audio
Constant 30 FPS
Correct resolution
Uploaded a new build with a higher build number (Build 3)
Waited more than 24 hours after upload
Logged out / logged in, refreshed, tried multiple browsers and sessions
Confirmed TestFlight build upload completed successfully
Despite all of this, the error persists and also prevents:
Adding the app for review
Creating a new app version (the “Add Version” button does not appear)
Apple Developer Support has suggested submitting a higher build number, which I have done, but the issue remains.
At this point, it seems like a stuck / ghost App Preview upload job on the App Store Connect backend.
Has anyone experienced a similar issue?
If so:
How was it resolved?
Did Apple need to manually clear or reset something on their side?
Any advice would be greatly appreciated.
Thank you in advance.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
iOS
Xcode
App Store Connect
Environment
iOS 26 (23A343)
Xcode 26
Reproduces on device and Simulator
Description
When presenting a SwiftUI WebView (native iOS 26 component) or a WKWebView/UIWebView via UIViewRepresentable, focusing a text field inside the web view and then dismissing it breaks the keyboard layout behavior.
After returning to the main app, tapping any TextField causes the keyboard to cover bottom controls (e.g. buttons). Expected safe area insets are not applied.
The issue is only resolved after closing and reopening the keyboard once.
Steps to Reproduce
Open a SwiftUI screen with WebView (via .sheet or NavigationLink).
Inside the web view, tap a text field to show the keyboard.
Dismiss the web view.
Tap a TextField in the main app.
Expected Result
Layout should adjust correctly.
Bottom controls stay visible above the keyboard.
Actual Result
Keyboard covers bottom controls.
Insets are ignored until the keyboard is dismissed and reopened.
Notes
Reproduces with:
Native SwiftUI WebView (iOS 26)
WKWebView and UIWebView via UIViewRepresentable
Presentation style (.sheet or navigation push) does not matter.
Example video: https://youtu.be/Epgoz1vETKU
FB: FB20386257
Sample Code
import SwiftUI
import WebKit
struct ContentView: View {
@State var url: URL?
@FocusState private var isFocused: Bool
var body: some View {
VStack {
TextField("TextField", text: .constant(""))
.focused($isFocused)
Button("HIDE KEYBOARD") { isFocused = false }
Spacer()
Button("ACTION") {
url = URL(string: "https://google.com")
}
}
.sheet(item: $url) { value in
NavigationStack {
WebView(url: value)
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("CLOSE") { url = nil }
}
}
}
}
}
}
extension URL: Identifiable {
public var id: String { absoluteString }
}
Platform
UIKit
iOS
UIActivityViewController
Environment
Device (issue reported): iPhone 16
iOS Version: 26.2
App Type: UIKit / Swift (standard modal presentation of UIActivityViewController)
Summary
When presenting UIActivityViewController to share a CSV file, the share sheet does not allow vertical scrolling, making lower actions (including Save to Files) unreachable.
The same flow works correctly when sharing a PDF, and the issue cannot be reproduced on other test devices.
Steps to Reproduce
Launch the app and log in
Navigate to More → Reports
Tap Export Report
Choose Export Report (CSV)
Observe the share sheet
Expected Result
The user should be able to vertically scroll the share sheet
All share actions (including Save to Files) should be reachable
Actual Result
Share sheet opens but vertical scrolling is disabled
Lower options (including Save to Files) are not reachable
No crash or console errors
During Apple Pay in-app provisioning (EV_ECC_v2), our iOS app successfully obtains the issuer provisioning certificates and generates cryptographic material. The flow fails when Apple posts the card blob to Apple’s broker (card creation step), returning HTTP 500 from .../broker/v4/devices/{SEID}/cards.
Steps:
Call issuerProvisioningCertificates?encryptionVersion=EV_ECC_v2
→ 200 OK; returns ECC leaf + Apple Root CA chain; nonce=2a831be4.
2. Build {encryptedCardData, activationData, ephemeralPublicKey}
3. POST /broker/v4/devices/{SEID}/cards
Expected: 200 OK on /broker/v4/devices/{SEID}/cards, or 5xx with a descriptive error if payload/cryptography is invalid.
Observed: 500 Internal Server Error from Apple broker on /cards (labeled “eligibility” in PassKit logs), causing a terminal failure in Wallet UI.
Hello,
I am developing an internal phone application using CallKit.
I am experiencing an issue with the behavior of remoteHandle settings in iOS 26 and would appreciate any insights you can provide towards a solution.
1. Problem Description
When an iPhone running iOS 26 is in a sleep state and receives a VoIP incoming call where remoteHandle is set to nil or an empty string (@""), we are unable to transition to our application (the UIExtension provided by the provider) from the CallKit UI's "More" (…) button after answering the call.
2. Conditions and Symptoms
OS Version: iOS 26
Initial State: iPhone is in a sleep state
Call Type: An unsolicited(unknown number) VoIP incoming call where the CXCallUpdate's remoteHandle is set to either nil or [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:@""]
Symptoms: After answering the VoIP call by sliding the button, selecting the "More" (…) button displayed on the CallKit screen does not launch our application's UIExtension (custom UI), and the iPhone instead stay to the CallKit screen.
3. Previous Behavior (Up to iOS 18)
Up to iOS 18, even when remoteHandle was set to an empty string using the following code, the application would transition normally from "More" after answering an incoming call from a sleep state.
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:@""];
[provider reportNewIncomingCallWithUUID:uuid update:update completion:completion];
4. Unsuccessful Attempts to Resolve
The issue remained unresolved after changing the handling for unsolicited(unknown number) incoming calls as follows:
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = nil; // Set remoteHandle to nil
[provider reportNewIncomingCallWithUUID:uuid update:update completion:completion];
5. Workaround (Temporary)
The problem can be resolved, and the application can transition successfully, by setting a dummy numerical value (e.g., "0") for the value in remoteHandle using the following code:
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:@"0"]; // Set a dummy numerical value
[provider reportNewIncomingCallWithUUID:uuid update:update completion:completion];
6. Additional Information
If remoteHandle is correctly set with the caller's number (i.e., not an unsolicited(unknown number) call; e.g., value:@"1234567890"), the application transitions normally from the "More" button after answering an incoming call from a sleep state, even in iOS 26.
The above issue does not occur when answering incoming calls while the iPhone is in an active state (not sleeping).
7. Questions
Have there been any other reports of similar behavior?
Should this be considered a bug in CallKit for iOS 26? Should I make file a new Feedback report?
Is there a suitable method to resolve this issue when the caller ID is unsolicited (nil or an empty string)?
This problem significantly impacts user operations as end-users are unable to perform essential in-app actions such as hold or transfer after answering an unsolicited(unknown number) call from a sleep state. We are eager to find an urgent solution and would appreciate any information or advice you can provide.
Thank you for your assistance.
Our project using UITabBarController and set a custom tabbar using below code:
let customTabBar = CustomTabBar(with: dataSource)
setValue(customTabBar, forKey: "tabBar")
But when using Xcode 26 build app in iOS 26, the tabbar does not show:
above code works well in iOS 18:
below is the demo code:
AppDelegate.swift:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let window: UIWindow = UIWindow()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window.rootViewController = TabBarViewController()
window.makeKeyAndVisible()
return true
}
}
CustomTabBar.swift:
import UIKit
class CustomTabBar: UITabBar {
class TabBarModel {
let title: String
let icon: UIImage?
init(title: String, icon: UIImage?) {
self.title = title
self.icon = icon
}
}
class TabBarItemView: UIView {
lazy var titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = .systemFont(ofSize: 14)
titleLabel.textColor = .black
titleLabel.textAlignment = .center
return titleLabel
}()
lazy var iconView: UIImageView = {
let iconView = UIImageView()
iconView.translatesAutoresizingMaskIntoConstraints = false
iconView.contentMode = .center
return iconView
}()
private var model: TabBarModel
init(model: TabBarModel) {
self.model = model
super.init(frame: .zero)
setupSubViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupSubViews() {
addSubview(iconView)
iconView.topAnchor.constraint(equalTo: topAnchor).isActive = true
iconView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
iconView.widthAnchor.constraint(equalToConstant: 34).isActive = true
iconView.heightAnchor.constraint(equalToConstant: 34).isActive = true
iconView.image = model.icon
addSubview(titleLabel)
titleLabel.topAnchor.constraint(equalTo: iconView.bottomAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
titleLabel.heightAnchor.constraint(equalToConstant: 16).isActive = true
titleLabel.text = model.title
}
}
private var dataSource: [TabBarModel]
init(with dataSource: [TabBarModel]) {
self.dataSource = dataSource
super.init(frame: .zero)
setupTabBars()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
var sizeThatFits = super.sizeThatFits(size)
let safeAreaBottomHeight: CGFloat = safeAreaInsets.bottom
sizeThatFits.height = 52 + safeAreaBottomHeight
return sizeThatFits
}
private func setupTabBars() {
backgroundColor = .orange
let multiplier = 1.0 / Double(dataSource.count)
var lastItemView: TabBarItemView?
for model in dataSource {
let tabBarItemView = TabBarItemView(model: model)
addSubview(tabBarItemView)
tabBarItemView.translatesAutoresizingMaskIntoConstraints = false
tabBarItemView.topAnchor.constraint(equalTo: topAnchor).isActive = true
tabBarItemView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
if let lastItemView = lastItemView {
tabBarItemView.leadingAnchor.constraint(equalTo: lastItemView.trailingAnchor).isActive = true
} else {
tabBarItemView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
tabBarItemView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: multiplier).isActive = true
lastItemView = tabBarItemView
}
}
}
TabBarViewController.swift:
import UIKit
class NavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
navigationItem.title = "Home"
}
}
class PhoneViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .purple
navigationItem.title = "Phone"
}
}
class PhotoViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
navigationItem.title = "Photo"
}
}
class SettingViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
navigationItem.title = "Setting"
}
}
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let homeVC = HomeViewController()
let homeNav = NavigationController(rootViewController: homeVC)
let phoneVC = PhoneViewController()
let phoneNav = NavigationController(rootViewController: phoneVC)
let photoVC = PhotoViewController()
let photoNav = NavigationController(rootViewController: photoVC)
let settingVC = SettingViewController()
let settingNav = NavigationController(rootViewController: settingVC)
viewControllers = [homeNav, phoneNav, photoNav, settingNav]
let dataSource = [
CustomTabBar.TabBarModel(title: "Home", icon: UIImage(systemName: "house")),
CustomTabBar.TabBarModel(title: "Phone", icon: UIImage(systemName: "phone")),
CustomTabBar.TabBarModel(title: "Photo", icon: UIImage(systemName: "photo")),
CustomTabBar.TabBarModel(title: "Setting", icon: UIImage(systemName: "gear"))
]
let customTabBar = CustomTabBar(with: dataSource)
setValue(customTabBar, forKey: "tabBar")
}
}
And I have post a feedback in Feedback Assistant(id: FB18141909), the demo project code can be found there.
How are we going to solve this problem? Thank you.
For our research study, it is essential that the app can advertise BLE packets even when the app is no longer in the foreground (for example, when it is in the app switcher / recents state).
Is it supported to advertise BLE packets while the app is in the background or recents state?
If so, what are the specific requirements or limitations we should be aware of (background modes, payload size, timing, etc.)?
Are there any constraints that would prevent consistent BLE advertising for research use cases?
Our app supports UIScene. As a result, launchOptions in application(_:didFinishLaunchingWithOptions:) is always nil.
However, the documentation mentions that UIApplication.LaunchOptionsKey.location should be present when the app is launched due to a location event.
Given that our app is scene-based:
How can we reliably determine whether the app was launched due to a location update, geofence, or significant location change?
Is there a recommended pattern or API to detect this scenario in a Scene-based app lifecycle?
This information is critical for us to correctly initialize location-related logic on launch.
Relevant documentation:
https://developer.apple.com/documentation/corelocation/cllocationmanager/startmonitoringsignificantlocationchanges()
Hi,
I’m developing an iOS app that needs to list the nearby wifi list so User can tap and send via Tag.
Is there any supported public iOS API or entitlement that allows listing nearby Wi-Fi networks in iOS app?
Thank you.
Overview
In iOS 26, a List embedded in a NavigationStack inside a TabView exhibits a visual glitch when switching tabs.
When the list is scrolled such that some rows are partially obscured by the navigation bar, the system correctly applies a fade/opacity effect to those rows. However, if the user switches to another tab while rows are in this partially obscured (faded) state, those rows briefly flash at full opacity during the tab transition before disappearing.
This flash is visually distracting and appears to be inconsistent with the intended scroll-edge opacity behavior.
The issue occurs only for rows partially obscured by the navigation bar.
Rows partially obscured by the tab bar do not exhibit this flashing behavior.
Steps to Reproduce:
Run the attached minimal reproduction on iOS 26.
Open the first tab.
Scroll the list so that some rows are partially hidden behind the navigation bar (showing the native faded appearance).
While rows are in this partially faded state, switch to the second tab.
Observe that the faded rows briefly render fully opaque during the tab switch.
Expected Behavior:
Rows that are partially obscured by the navigation bar should maintain consistent opacity behavior during tab transitions, without flashing to full opacity.
import SwiftUI
@main
struct NavBarReproApp: App {
/// Minimal repro for iOS 26:
/// - TabView with two tabs
/// - First tab: NavigationStack + List
/// - Scroll so some rows are partially behind the nav bar (faded)
/// - Switch tabs: those partially-faded rows briefly flash fully opaque. Partially faded rows under the tab bar do not flash
private let items = Array(0..<200).map { "Row \($0)" }
var body: some Scene {
WindowGroup {
TabView {
NavigationStack {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
}
.navigationTitle("One")
.navigationBarTitleDisplayMode(.inline)
}
.tabItem { Label("One", systemImage: "1.circle") }
NavigationStack {
Text("Second tab")
.navigationTitle("Two")
.navigationBarTitleDisplayMode(.inline)
}
.tabItem { Label("Two", systemImage: "2.circle") }
}
}
}
}
On iOS 26.01 & 26.2, the system keyboard shows uneven horizontal padding:
Leftmost key column touches the screen edge
Right side has visible padding
This behavior is reproducible:
In existing apps In a brand-new demo app In both UIKit and SwiftUI
Xcode: 26.0.1 & 26.2
iOS: 26.0.1 & 26.2 Simulator
Devices tested: iPhone 15 / iPhone 15 Pro
Keyboard types: .numberPad, .decimalPad
Frameworks: UIKit, SwiftUI
At which point in the image processing pipeline does iOS apply the white balance gains which can be set via AVCaptureDevice.setWhiteBalanceModeLocked(with:completionHandler:)?
Are those gains applied in the analog part of the camera pipeline, before the pixel voltage gets converted via the ADC to digital values? Or does the camera first convert the pixel voltages to digital values and then the gains are applied to the digital values?
Is this consistent across devices or can the behavior vary from device to device?
Hi Apple engineers!
We are making an iOS browser and are planing to deliver a feature that allows enterprise customers to use a MAM key to set a PAC file for proxy. It's designed to support unmanaged device so the MDM based solutions like 'Global HTTP Proxy MDM payload' or 'Per-App VPN' simply don't work.
After doing some research we found that with WKWebView, the only framework allowed on iOS for web browsing, there's no API for programmatically setting proxy. The closes API is the WKURLSchemeHandler, but it's for data management not network request interception, in other word it can not be used to handle HTTP/HTTPS request well.
When we go from the web-view level to the app level, it seems there's no API to let an app set proxy for itself at an app-level, the closest API is Per-App VPN but as mentioned above, Per-App VPN is only available for managed device so we can't use that as well.
Eventually we go to the system level, and try to use Network Extension, but there's still obstacles. It seems Network Extension doesn't directly provide a way to write system proxy. In order to archive that, we may have to use Packet Tunnel Provider in destination IP mode and create a local VPN server to loop back the network traffic and do the proxy stuff in that server. In other word, the custom VPN protocol is 'forward directly without encryption'. This approach looks viable as we see some of the network analysis tools use this approach, but still I'd like to ask is this against App Store Review Guidelines?
If the above approach with Network Extension is not against App Store Review Guidelines, I have a further question that, what is the NEProxySettings of NETunnelNetworkSettings for? Is it the proxy which proxies the VPN traffic (in order to hide source IP from VPN provider) or it is the proxy to use after network traffic goes into the virtual private network?
If none of the above is considered recommended, what is the recommended way to programmatically set proxy on WKWebView on an unmanaged device (regardless of where the proxy runs, web-view/app/system)?
When you use .navigationTransition(.zoom(sourceID: "placeholder", in: placehoder)) for navigation animation, going back using the swipe gesture is still very buggy on IOS26. I know it has been mentioned in other places like here: https://developer.apple.com/forums/thread/796805?answerId=856846022#856846022 but nothing seems to have been done to fix this issue.
Here is a video showing the bug comparing when the back button is used vs swipe to go back: https://imgur.com/a/JgEusRH
I wish there was a way to at least disable the swipe back gesture until this bug is fixed.