We are facing a serious issues with in app purchases in our app.
We offer 3 IAP: auto-renewable subscription 1W, auto-renewable subscription 1Y, non-consumable one-time purchase (LifeTime access)
In our case 90-95% of transactions fail and we mostly get SKError code=2 .
Sometime purchase fails several times for the same user so it’s very hard to believe that user intentionally cancels transaction for the same product 4 or even 5 times in a row.
It happens regardless iOS version, device model, our app version.
We've checked multiple threads with the same issue but coudn't find any solution.
We do not offer any promotions, product identifiers are valid... Some users are able to make a purchases without any issues.
Posts under iOS tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I have been trying for almost a week to get my app approved. It is like the Submission team doesn't even read my notes. The first complaint is that my app was for a specific business and shouldn't be for the general public. This is true, so I put in the notes that I had requested private distribution and I filled out the request for the app to be distributed privately. The review notes say that I need to distribute my app privately. This is very frustrating.
Also, they say the login button doesn't work. It works for everyone that uses it in the Test Flight. One nuance we have is that our servers will not respond to IP addresses that orginate outside of the US. I have this in caps in the notes. They still say that the Login button doesn't work. The app was written for iPhones, yet they keep testing it on an iPad.
There doesn't seem to be any way to communicate with the submission team other than through the test notes and they don't seem to be reading these. Can anyone direct me to where I can get some help on this?
Thanks,
Jim
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
App Store
iOS
App Review
An issue with the CallKit UI, specifically regarding the functionality of the speaker button.
When a user initiates a video call with CallKit and then, using the existing CallKit session, initiates an audio call, there are no issues with CallKit or the audio.
However, if the user terminates the video call from the CallKit UI, the active CallKit session ends. To resume the ongoing audio call, we report a new CallKit call upon the end call trigger. While there are no issues with this reporting, the CallKit UI does not provide an audio route for the built-in receiver, and the speaker button remains unresponsive.
IPA was build on SDK 18 and running on iOS beta 26.
Issue is NOT seen with SDK18 and running iOS 18.x or lower devices.
Feedback - FB18855566
I have discovered a gap in my understanding of user selected URLs in iOS, and I would be grateful if someone can put me right please.
My understanding is that a URL selected by a user can be accessed by calling url.startAccessingSecurityScopedResource() call. Subsequently a call to stopAccessingSecurityScopedResource() is made to avoid sandbox memory leaks.
Furthermore, the URL can be saved as a bookmark and reconstituted when the app is run again to avoid re-asking permission from the user.
So far so good.
However, I have discovered that a URL retrieved from a bookmark can be accessed without the call to url.startAccessingSecurityScopedResource(). This seems contrary to what the documentation says here
So my question is (assuming this is not a bug) why not save and retrieve the URL immediately in order to avoid having to make any additional calls to url.startAccessingSecurityScopedResource?
Bill Aylward
You can copy and paste the code below into a new iOS project to illustrate this. Having chosen a folder, the 'Summarise folder without permission' button fails as expected, but once the 'Retrieve URL from bookmark' has been pressed, it works fine.
import SwiftUI
import UniformTypeIdentifiers
struct ContentView: View {
@AppStorage("bookmarkData") private var bookmarkData: Data?
@State private var showFolderPicker = false
@State private var folderUrl: URL?
@State private var folderReport: String?
var body: some View {
VStack(spacing: 20) {
Text("Selected folder: \(folderUrl?.lastPathComponent ?? "None")")
Text("Contents: \(folderReport ?? "Unknown")")
Button("Select folder") {
showFolderPicker.toggle()
}
Button("Deselect folder") {
folderUrl = nil
folderReport = nil
bookmarkData = nil
}
.disabled(folderUrl == nil)
Button("Retrieve URL from bookmark") {
retrieveFolderURL()
}
.disabled(bookmarkData == nil)
Button("Summarise folder with permission") {
summariseFolderWithPermission(true)
}
.disabled(folderUrl == nil)
Button("Summarise folder without permission") {
summariseFolderWithPermission(false)
}
.disabled(folderUrl == nil)
}
.padding()
.fileImporter(
isPresented: $showFolderPicker,
allowedContentTypes: [UTType.init("public.folder")!],
allowsMultipleSelection: false
) { result in
switch result {
case .success(let urls):
if let selectedUrl = urls.first {
print("Processing folder: \(selectedUrl)")
processFolderURL(selectedUrl)
}
case .failure(let error):
print("\(error.localizedDescription)")
}
}
.onAppear() {
guard folderUrl == nil else { return }
retrieveFolderURL()
}
}
func processFolderURL(_ selectedUrl: URL?) {
guard selectedUrl != nil else { return }
// Create and save a security scoped bookmark in AppStorage
do {
guard selectedUrl!.startAccessingSecurityScopedResource() else { print("Unable to access \(selectedUrl!)"); return }
// Save bookmark
bookmarkData = try selectedUrl!.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
selectedUrl!.stopAccessingSecurityScopedResource()
} catch {
print("Unable to save security scoped bookmark")
}
folderUrl = selectedUrl!
}
func retrieveFolderURL() {
guard let bookmarkData = bookmarkData else {
print("No bookmark data available")
return
}
do {
var isStale = false
let url = try URL(
resolvingBookmarkData: bookmarkData,
options: .withoutUI,
relativeTo: nil,
bookmarkDataIsStale: &isStale
)
folderUrl = url
} catch {
print("Error accessing URL: \(error.localizedDescription)")
}
}
func summariseFolderWithPermission(_ permission: Bool) {
folderReport = nil
print(String(describing: folderUrl))
guard folderUrl != nil else { return }
if permission { print("Result of access requrest is \(folderUrl!.startAccessingSecurityScopedResource())") }
do {
let contents = try FileManager.default.contentsOfDirectory(atPath: folderUrl!.path)
folderReport = "\(contents.count) files, the first is: \(contents.first!)"
} catch {
print(error.localizedDescription)
}
if permission { folderUrl!.stopAccessingSecurityScopedResource() }
}
}
I'm encountering an issue with our legacy Objective-C codebase that uses UIApplicationDelegate.
Here are the steps to reproduce the issue:
Uninstall the application from the device.
Install and launch the application.
As part of the launch event, the client requests notification permission.
The permission prompt is still displayed, even though the client receives a remote notification token (which appears to be a cached one).
I followed the same steps with a sample app built with Swift (SwiftUI), and this issue did not occur. In the Swift app, I consistently received a delegate<didRegisterForRemoteNotificationsWithDeviceToken> call after the user allowed the notification permission.
Could you please provide some insights into why this might be happening with only our client?
Topic:
App & System Services
SubTopic:
Notifications
Tags:
APNS
iOS
Notification Center
User Notifications
In TabView, when I open a view in a Tab, and I switch to another Tab, but the View lifecycle of the view in the old Tab is still not over, and the threads of some functions are still in the background. I want to completely end the View lifecycle of the View in the previously opened tab when switching Tab. How can I do it? Thank you!
When attempting to open sysdiagnose logs collected from an iPhone running iOS 26 beta 3 on macOS Console, the application consistently crashes.
Crash report has been added for reference.
Apple Feedback- FB18834450
Before I file a bug report I wanted to verify that I'm not missing something.
If I setup a view controller in a navigation controller and I add a view with a constraint that lines it up with the view controller's view's layoutMarginsGuide (leadingAnchor or trailingAnchor), in several cases the view will not line up with buttons added in the navigation bar. Under iOS 18 everything lines up as expected.
To demonstrate, create a new iOS project based on Swift/Storyboard. Setup the storyboard to show a UINavigationController with one UIViewController. Then in ViewController.swift (the one embedded in the navigation controller), use the following code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
title = "Layout Margins"
let leftCancel = UIBarButtonItem(systemItem: .cancel)
navigationItem.leftBarButtonItem = leftCancel
let rightCancel = UIBarButtonItem(systemItem: .cancel)
navigationItem.rightBarButtonItem = rightCancel
let leftView = UIView()
leftView.backgroundColor = .blue
leftView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(leftView)
let rightView = UIView()
rightView.backgroundColor = .red
rightView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(rightView)
NSLayoutConstraint.activate([
leftView.widthAnchor.constraint(equalToConstant: 80),
leftView.heightAnchor.constraint(equalToConstant: 80),
leftView.leadingAnchor.constraint(equalTo: self.view.layoutMarginsGuide.leadingAnchor),
leftView.topAnchor.constraint(equalTo: self.view.layoutMarginsGuide.topAnchor),
rightView.widthAnchor.constraint(equalToConstant: 80),
rightView.heightAnchor.constraint(equalToConstant: 80),
rightView.trailingAnchor.constraint(equalTo: self.view.layoutMarginsGuide.trailingAnchor),
rightView.topAnchor.constraint(equalTo: self.view.layoutMarginsGuide.topAnchor),
])
}
}
This adds a "Cancel" button to both ends of the navigation bar and it adds two little square views lined up with the leading and trailing layout margins.
Here's the results:
iPad running iPadOS 26 beta 3 (note the misalignment). This is really jarring when trying to align another glass button below the cancel button:
iPad running iPadOS 18.5 (aligned just fine):
iPhone in portrait running iOS 26 beta (aligned just fine):
iPhone in landscape running iOS 26 beta (no alignment at all):
iPhone in portrait running iOS 18.5 (aligned just fine):
iPhone in landscape running iOS 18.5 (aligned just fine):
Under iOS 26 on an iPhone (simulator at least) in portrait, the cancel buttons line up with the colored squares. That's good. In landscape, the colored squares have much larger margins as expected (due to the larger safe areas caused by the notch), but the cancel buttons in the navigation bar are not using the same margins. This one is debatable. Under iOS 18 the cancel buttons use larger margins to match the larger safe area. But I can see why under iOS 26 they changed this since the navigation bar doesn't interfere with the notch. But it's inconsistent.
Under iOS 26 on an iPad (simulator at least), it's wrong in any orientation. Despite the lack of any notch or need for a larger safe area, the colored squares are indented just a bit more than the buttons in the navigation bar. I see no reason for this. Under iOS 18 everything lines up as expected.
My real question at this point: Is the mismatched margins on an iPad under iOS 26 between the buttons in the navigation bar and other views added to the view controller a likely bug or am I missing something?
I installed the third beta of Xcode 26 with Xcode 16.4 installed on my machine. Once Xcode 26 was installed, all of my previous simulators were wiped out, leaving only the default iOS 26 simulators. I cannot create new simulators for iOS versions below 26. Here are my failed attempts to fix the issue:
Restarted Xcode 16.4 and my machine
Reinstalled the iOS 18.5 runtime
Uninstalled Xcode 26 and iOS 26 runtime
Reinstalled Xcode 16.4
Now, I literally cannot use a simulator in Xcode 16.4. Here is what I see when I try to create a new simulator in Xcode 16.4:
According to Xcode, the iOS 18.5 runtime is installed, so I have no idea what is going on. Is this a known issue? And how do I get Xcode 16.4 working with the iOS simulator?
I need a layout where I have a ScrollView with some content, and ScrollView has full screen background image. Screen is pushed as detail on stack.
When my screen is pushed we display navigation bar. We want a new scrollEdgeEffectStyle .soft style work. But when we scroll the gradient blur effect bellow bars is fixed to top and bottom part of the scroll view background image and is not transparent. However when content underneath navigation bar is darker and navigation bar changes automatically to adapt content underneath the final effect looks as expected doesn't use background image.
Expected bahaviour for us is that the effect under the navigation bar would not use background image but would be transparent based on content underneath.
This is how it is intialy when user didn't interact with the screen:
This is how it looks when user scrolls down:
This is how it looks when navigation bar adapts to dark content underneath:
Minimal code to reproduce this behaviour:
import SwiftUI
@main
struct SwiftUIByExampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
NavigationStack {
ScrollView(.vertical) {
VStack(spacing: 0.0) {
ForEach(1 ..< 101, id: \.self) { i in
HStack {
Text("Row \(i)")
Spacer()
}
.frame(height: 50)
.background(Color.random)
}
}
}
.scrollEdgeEffectStyle(.soft, for: .all)
.scrollContentBackground(.hidden)
.toolbar {
ToolbarItem(placement: .title) {
Label("My Awesome App", systemImage: "sparkles")
.labelStyle(.titleAndIcon)
}
}
.toolbarRole(.navigationStack)
.background(
ZStack {
Color.white
.ignoresSafeArea()
Image(.sea)
.resizable()
.ignoresSafeArea()
.scaledToFill()
}
)
}
}
}
extension Color {
static var random: Color {
Color(
red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1)
)
}
}
We've also tried using ZStack instead of .background modifier but we observed the same results.
We want to basically achieve the same effect as showcased here, but with the static background image:
https://youtu.be/3MugGCtm26A?si=ALG29NqX1jAMacM5&t=634
I recently update version 26 Beta 2 , 3 can't working screenshot & Dont have split screen iphones
Topic:
Developer Tools & Services
SubTopic:
Apple Developer Program
Tags:
Developer Tools
iOS
iPhone
Beta
Hi I recently installed iOS 26 but did not make a backup, how can I get iOS 18 without losing any data?
I’m using the new preferredTransition = .zoom(...) API introduced in iOS 18.
Here’s a simplified version of what I do on app startup:
let listVC = CollectionViewController(collectionViewLayout: layout)
let detailVC = DetailViewController()
detailVC.preferredTransition = .zoom(sourceViewProvider: { context in
let indexPath = IndexPath(row: 0, section: 0)
let cell = listVC.collectionView.cellForItem(at: indexPath)
return cell
})
let nav = UINavigationController()
nav.setViewControllers([listVC, detailVC], animated: false)
window?.rootViewController = nav
window?.makeKeyAndVisible()
This is meant to restore the UI state from a previous session — the app should launch directly into the DetailViewController.
The Problem
When I launch the app with setViewControllers([listVC, detailVC], animated: false), the transition from listVC to detailVC appears correctly (i.e., no animation, as intended), but the drag-to-dismiss gesture does not work. The back button appears, and tapping it correctly triggers the zoom-out transition back to the cell, so the preferredTransition = .zoom(...) itself is properly configured.
Interestingly, if I delay the push with a DispatchQueue.main.async and instead do:
nav.setViewControllers([listVC], animated: false)
DispatchQueue.main.async {
nav.pushViewController(detailVC, animated: true)
}
…then everything works perfectly — including the interactive swipe-to-dismiss gesture — but that introduces an unwanted visual artifact: the user briefly sees the listVC, and then it pushes to detailVC, which I’m trying to avoid.
My Question
Is there a way to enable the swipe-to-dismiss gesture when using setViewControllers([listVC, detailVC], animated: false)
It can be very confusing for users if swipe-to-dismiss only works in certain cases inconsistently.
Thanks
On iPhone, I would like to have a more button at the top right of the navigation bar, a search field in the bottom toolbar, and a plus button to the right of the search field. I've achieved this via the code below.
But on iPad they should be in the navigation bar at the trailing edge from left to right: plus, more, search field. Just like the Shortcuts app, if there's not enough horizontal space, the search field should collapse into a button, and with even smaller space the search bar should become full-width under the navigation bar.
Right now on iPad the search bar is full width under the navigation bar, more at top right, plus at bottom middle, no matter how big the window is.
How can I achieve that? Any way to specify them for the system to more automatically do the right thing, or would I need to check specifically for iPhone vs iPad UIDevice to change the code?
struct ContentView: View {
@State private var searchText = ""
var body: some View {
NavigationStack {
VStack {
Text("Hello, world!")
}
.navigationTitle("Test App")
.searchable(text: $searchText)
.toolbar {
ToolbarItem {
Menu {
//...
} label: {
Label("More", systemImage: "ellipsis")
}
}
DefaultToolbarItem(kind: .search, placement: .bottomBar)
ToolbarSpacer(.fixed, placement: .bottomBar)
ToolbarItem(placement: .bottomBar) {
Button {
print("Add tapped")
} label: {
Label("Add", systemImage: "plus")
}
}
}
}
}
}
I present a view in a sheet that consists of a navigation stack and a scroll view which has a photo pushed to the top by setting .ignoresSafeArea(edges: .top). The problem is the top of the photo is blurry due to the scroll edge effect. I would like to hide the scroll edge effect so the photo is fully visible when scrolled to the top but let the effect become visible upon scrolling down. Is that possible?
struct ContentView: View {
@State private var showingSheet = false
var body: some View {
VStack {
Button("Present Sheet") {
showingSheet = true
}
}
.sheet(isPresented: $showingSheet) {
SheetView()
}
}
}
struct SheetView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
NavigationStack {
ScrollView {
VStack {
Image("Photo")
.resizable()
.scaledToFill()
}
}
.ignoresSafeArea(edges: .top)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(role: .close) {
dismiss()
}
}
ToolbarItem {
EditButton()
}
}
}
}
}
When using UIPageViewController inside a UITabBarController on iOS 26 with Liquid Glass adoption, visiting the PageViewController tab applies a blur effect to the navigation bar and tab bar even though the current child view controller of the pageView is not scrollable and does not reach behind these bars.
Questions:
Is this the expected behavior that the pageview's internal scroll view causes the bars to blur regardless of the page view's child content’s scrollability?
If so, is there an official way to make the blur effect appear only when the pageview's current child view controller actually scrolls behind the navigation bar or tab bar, and not in static cases?
Tried the same in SwiftUI using TabView and TabView with page style. Facing the same issue there as well.
Sample screenshots for reference,
Sample SwiftUI code,
struct TabContentView: View {
var body: some View {
TabView {
// First Tab: Paging View
PagingView()
.tabItem {
Label("Pages", systemImage: "square.fill.on.square.fill")
}
// Second Tab: Normal View
NavigationStack {
ListView()
}
.tabItem {
Label("Second", systemImage: "star.fill")
}
// Third Tab: Normal View
PageView(color: .blue, text: "Page 3")
.tabItem {
Label("Third", systemImage: "gearshape.fill")
}
}
.ignoresSafeArea()
}
}
struct PagingView: View {
var body: some View {
TabView {
PageView(color: .red, text: "Page 1")
PageView(color: .green, text: "Page 2")
PageView(color: .blue, text: "Page 3")
}
.tabViewStyle(.page) // Enables swipe paging
.indexViewStyle(.page(backgroundDisplayMode: .always))
.ignoresSafeArea()// Dots indicator
}
}
Hello Developer Forums Team,
I’ve seen that some banking apps prevent screenshots on certain sensitive screens. I’m working on a similar feature in my SDK and want to confirm if my implementation complies with App Store guidelines.
Since there’s no public API to block screenshots, I’m using a workaround based on the secure rendering behavior of UITextField (isSecureTextEntry = true). I embed my custom content (e.g., a UITableView) inside the internal secure container of a UITextField, which results in blank content being captured during screenshots—similar to what some banking apps do.
Approach Summary
I create a UITextField
I detect its internal secure container by matching UIKit internal class names as strings
I embed my real UI content into that container
I do not use or call any private APIs, just match view class names via strings.
ScreenshotPreventingView.swift
final class ScreenshotPreventingView: UIView {
private let textField = UITextField()
private let recognizer = HiddenContainerRecognizer()
private var contentView: UIView?
public var preventScreenCapture = true {
didSet {
textField.isSecureTextEntry = preventScreenCapture
}
}
public init(contentView: UIView? = nil) {
super.init(frame: .zero)
self.contentView = contentView
setupUI()
}
private func setupUI() {
guard let container = try? recognizer.getHiddenContainer(from: textField) else { return }
addSubview(container)
NSLayoutConstraint.activate([
container.topAnchor.constraint(equalTo: topAnchor),
container.bottomAnchor.constraint(equalTo: bottomAnchor),
container.leadingAnchor.constraint(equalTo: leadingAnchor),
container.trailingAnchor.constraint(equalTo: trailingAnchor)
])
if let contentView = contentView {
setup(contentView: contentView, in: container)
}
DispatchQueue.main.async {
self.preventScreenCapture = true
}
}
private func setup(contentView: UIView) {
self.contentView?.removeFromSuperview()
self.contentView = contentView
guard let container = hiddenContentContainer else { return }
container.addSubview(contentView)
container.isUserInteractionEnabled = isUserInteractionEnabled
contentView.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: container.bottomAnchor)
bottomConstraint.priority = .required - 1
NSLayoutConstraint.activate([
contentView.leadingAnchor.constraint(equalTo: container.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: container.trailingAnchor),
contentView.topAnchor.constraint(equalTo: container.topAnchor),
bottomConstraint
])
}
}
HiddenContainerRecognizer.swift
struct HiddenContainerRecognizer {
private enum Error: Swift.Error {
case unsupportedOSVersion(version: Float)
case desiredContainerNotFound(_ containerName: String)
}
func getHiddenContainer(from view: UIView) throws -> UIView {
let containerName = try getHiddenContainerTypeInStringRepresentation()
let containers = view.subviews.filter { subview in
type(of: subview).description() == containerName
}
guard let container = containers.first else {
throw Error.desiredContainerNotFound(containerName)
}
return container
}
private func getHiddenContainerTypeInStringRepresentation() throws -> String {
if #available(iOS 15, *) {
return "_UITextLayoutCanvasView"
}
if #available(iOS 14, *) {
return "_UITextFieldCanvasView"
}
if #available(iOS 13, *) {
return "_UITextFieldCanvasView"
}
if #available(iOS 12, *) {
return "_UITextFieldContentView"
}
let currentIOSVersion = (UIDevice.current.systemVersion as NSString).floatValue
throw Error.unsupportedOSVersion(version: currentIOSVersion)
}
}
How I use it in my Screen
let container = ScreenshotPreventingView()
override func viewDidLoad() {
super.viewDidLoad()
container.preventScreenCapture = true
container.setup(contentView: viewContainer) //viewContainer is UIView in storyboard, in which all other UI elements are placed in e.g. UITableView
self.view.addSubview(container)
container.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
container.topAnchor.constraint(equalTo: self.view.topAnchor),
container.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
container.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
container.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
])
}
What I’d Like to Confirm
Is this approach acceptable for App Store submission?
Is there a more Apple-recommended approach to prevent screen capture of arbitrary UI?
Thank you for your help in ensuring compliance.
This happens when trying to connect to my development web server. The app works fine when connecting to my production server.
The production server has a certificate purchased from a CA.
My development web server has a locally generated certificate (from mkcert).
I have dragged and dropped the rootCA.pem onto the Simulator, although it doesn't indicate it has been loaded the certificate does appear in the Settings app and is checked to be trusted.
I have enabled "App Sandbox" and "Outgoing connections (Client)".
I have tested the URL from my local browser which is working fine.
What am I missing?
I know there are several existing threads on this topic but things keep changing.
The release notes for Xcode 26 beta 3 have the following statements for a couple of resolved issues:
Asset Catalog
Fixed: Unable to set Icon Composer icon as alternate iOS icon (153305178) (FB18025356)
Icon Composer
Fixed: Icon Composer icons back deploy to older versions of iOS, macOS, and watchOS with inconsistent rendering. (152258860)
I had a working solution under beta 1 and beta 2 for both of these. But under beta 3, I am now seeing the new glass icons for my app when running on a simulated iOS 18 device. This is happening for both the main app icon and any alternates. This contradicts the statement that beta 3 fixes this issue.
There is no documentation (that I can find) describing how you are supposed to support old icons for iOS 18 and new glass icons for iOS 26. There is no documentation for how to support alternate glass icons for iOS 26.
What I'm doing at the moment (that worked before beta 3) was to have the normal iOS 18 app icons in the Asset catalog and to have the new glass icons added to the project. The filenames for the glass .icon files have the same name as the app icons in the Assets catalog. This worked under beta 1 and beta 2. And despite the Xcode 26 beta 3 release notes stating that Icon Composer icons no longer back deploy to iOS 18, I'm seeing the opposite. Beta 3 now does the opposite of that statement.
Does anyone have a working solution that supports old iOS 18 app icons and new iOS 26 glass icons using Xcode 26 beta 3?
Note, all of my testing is with simulated iOS devices and I'm running Xcode 26 beta 3 under macOS 15.5. Maybe that's an issue?
I have a More button in my nav bar that contains a Delete action, and when you tap that I want to show a confirmation dialog before performing the deletion. In order words, I have a toolbar containing a toolbar item containing a menu containing a button that when tapped needs to show a confirmation dialog.
In iOS 26, you're supposed to add the confirmationDialog on the view that presents the action sheet so that it can point to the source view or morph out of it if it's liquid glass. But when I do that, the confirmation dialog does not appear. Is that a bug or am I doing something wrong?
struct ContentView: View {
@State private var showingDeleteConfirmation = false
var body: some View {
NavigationStack {
Text("👋, 🌎!")
.toolbar {
ToolbarItem {
Menu {
Button(role: .destructive) {
showingDeleteConfirmation.toggle()
} label: {
Label("Delete", systemImage: "trash")
}
.confirmationDialog("Are you sure?", isPresented: $showingDeleteConfirmation) {
Button(role: .destructive) {
print("Delete it")
} label: {
Text("Delete")
}
Button(role: .cancel, action: {})
}
} label: {
Label("More", systemImage: "ellipsis")
}
}
}
}
}
}