Hi! While working on my Swift Student Challenge submission it seems that I found a race condition (TOCTOU) bug in SwiftUI when using sheets, and I'm not sure if this is expected behaviour or not.
Here's an example code:
import SwiftUI
struct ContentView: View {
@State var myVar: Int?
@State private var presentSheet: Bool = false
var body: some View {
VStack {
// Uncommenting the following Text() view will "fix" the bug (kind of, see a better workaround below).
// Text("The value is \(myVar == nil ? "nil" : "not nil")")
Button {
myVar = nil
} label: {
Text("Set value to nil.")
}
Button {
myVar = 1
presentSheet.toggle()
} label: {
Text("Set value to 1 and open sheet.")
}
}
.sheet(isPresented: $presentSheet, content: {
if myVar == nil {
Text("The value is nil")
.onAppear {
print(myVar) // prints Optional(1)
}
} else {
Text("The value is not nil")
}
})
}
}
When opening the app and pressing the open sheet button, the sheet shows "The value is nil", even though the button sets myVar to 1 before the presentSheet Bool is toggled.
Thankfully, as a workaround to this bug, I found out you can change the sheet's view to this:
.sheet(isPresented: $presentSheet, content: {
if myVar == nil {
Text("The value is nil")
.onAppear {
if myVar != nil {
print("Resetting View (TOCTOU found)")
let mySwap = myVar
myVar = nil
myVar = mySwap
}
}
} else {
Text("The value is not nil")
}
})
This triggers a view refresh by setting the variable to nil and then to its non-nil value again if the TOCTOU is found.
Do you think this is expected behaivor? Should I report a bug for this? This bug also affects .fullScreenCover() and .popover().
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
In my visionOS app, I'm seeing this error in the console dozens of times. Anyone know what it means, or how to troubleshoot it?
Searching these forums and the usual other places hasn't come up with anything that seems relevant.
Hi everyone,
I'm currently facing an issue with AVAudioPlayer in my SwiftUI project. Despite ensuring that the sound file "buttonsound.mp3" is properly added to the project's resources (I dragged and dropped it into Xcode), the application is still unable to locate the file when attempting to play it.
Here's the simplified version of the code I'm using:
import SwiftUI
import AVFoundation
struct ContentView: View {
var body: some View {
VStack {
Button("Play sound") {
playSound(named: "buttonsound", ofType: "mp3")
}
}
}
}
func playSound(named name: String, ofType type: String) {
guard let soundURL = Bundle.main.url(forResource: name, withExtension: type) else {
print("Sound file not found")
return
}
do {
let audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch let error {
print("Error playing sound: \(error.localizedDescription)")
}
}
Hello, I can't seem to set any breakpoint in didSet for all properties inside Observable.
Is this a bug?
XcodeVersion 15.2
(15C500b)
Thanks!
I am trying to build a text editor that shrinks to its content size. The closest I have been able to get has been to add the .scrollDisabled(true) and .fixedSize(horizontal: false, vertical: true) modifiers.
This almost achieves what I need. There are two problems though:
long single line text gets cut off at the end
creating line breaks causes the text editor to grow vertically as expected (uncovering the cut off text in point 1 above). However, when you delete the line breaks, the TextEditor does not shrink again.
I have had a radar open for some time: FB13292506. Hopefully opening a thread here will get more visibility.
And here is some sample code to easily reproduce the issue:
import SwiftUI
struct ContentView: View {
@State var text = "[This is some long text that will be cut off at the end of the text editor]"
var body: some View {
TextEditor(text: $text)
.scrollDisabled(true)
.fixedSize(horizontal: false, vertical: true)
}
}
#Preview {
ContentView()
}
Here is a gif of the behavior:
Background
I have a SwiftUI app that uses OSLog and the new Logger framework. In my SwiftUI views, I would like to use something like Self._logChanges() to help debug issues.
After some trial and error, I can see the messages appear in the System console log for the app I am debugging using the com.apple.SwiftUI subsystem.
Problem
I'd like to see those same messages directly in Xcode's console window so I can filter them as needed. How do I do that?
Thanks! -Patrick
I have a view, and in this view I bind Axis class values — lowerBound which is a regular property and at – computed one which comes from protocol HasPositionProtocol associated with Axis.
struct AxisPropertiesView<Axis>: View
where Axis: StyledAxisProtocol,
Axis: HasPositionProtocol,
Axis: Observable
{
@Bindable var axis: Axis
var body: some View {
HStack {
TextField("", text: $axis.shortName)
.frame(width: 40)
TextField("",
value: $axis.lowerBound,
format: .number)
.frame(width: 45)
//Problem is here:
Slider(value: $axis.at,
in: axis.bounds)
...
Unfortunately I got en error Failed to produce diagnostic for expression; ... for whole View.
But if I remove Slider from View, error disappeared.
What could cause this strange behaviour?
Value of .at comes from:
public extension HasPositionProtocol {
///Absolut position on Axis
var at: Double {
get {
switch position {
case .max:
return bounds.upperBound
case .min:
return bounds.lowerBound
case .number(let number):
return number
}
}
set {
switch newValue {
case bounds.lowerBound:
position = .min
case bounds.upperBound:
position = .max
default:
position = .number(newValue)
}
}
}
}
Using a button that is placed in the bottom ornament to set focus on a text field will not display the keyboard properly while a button embedded in the view will behave as expected.
To demonstrate the issue, simply run the attached project on Vision Pro with visionOS 1.1 and tap the Toggle 2 button in the bottom ornament. You’ll see that the field does have focus but the keyboard is now visible.
Run the same test with Toggle 1 and the field will get focus and the keyboard will show as expected.
import SwiftUI
import RealityKit
import RealityKitContent
struct ContentView: View {
@State private var text = ""
@State private var showKeyboard = false
@FocusState private var focusedField: FocusField?
private enum FocusField: Hashable {
case username
case password
}
var body: some View {
VStack {
TextField("Test", text: $text)
.focused($focusedField, equals: .username)
Text("Entered Text: \(text)")
.padding()
Button("Toggle 1") { // This button will work and show the keyboard
if focusedField != nil {
focusedField = nil
} else {
focusedField = .username
}
}
Spacer()
}
.padding()
.toolbar {
ToolbarItem(placement: .bottomOrnament) {
Button("Toggle 2") { // This button will set focus properly but not show the keyboard
if focusedField != nil {
focusedField = nil
} else {
focusedField = .username
}
}
}
}
}
}
Is there a way to work around this?
FB13641609
Our app was just rejected by Apple because they say the subscription management sheet never loads. It just spins indefinitely.
We're using StoreKit's manageSubscriptionsSheet view modifier to present the sheet, and it's always worked for us when testing in SandBox.
Has anyone else had this problem?
Given that it's Apple's own code that got us rejected, what's our path forward?
Is there any way to get dock size?
I got Dock Window using CGWindowListCopyWindowInfo.
But I found its frame covers my entire screen.
Same promble as Notification Center.
Any way to get their size?
We have developed an iOS app using three fonts: PingFangSC Regular, PingFangSC Medium, and DINAlternate-Bold. Do all three fonts require commercial authorization to be used in the app?
Hi,
I have few questions regarding the widgets.
I would like to know whether widget and app extensions are same ? This link(https://developer.apple.com/app-extensions/) says widget is type of app extension but I am not quite sure as few link in web says they are different. so need to confirm here :)
Can a widget share same bundle id as the main app ? so basically can we use the same provisioning profile as the main app?
If we use the same bundle id and provisioning profile, will there be any issue during the app store submission process.?
I Implement a 'SubscriptionStoreView' using 'groupID' into a project (iOS is targeting 17.2 and macOS is targeting 14.1).Build/run the application locally (both production and development environments will work fine), however once the application is live on the AppStore in AppStoreConnect, SubscriptionStoreView no longer shows products and only shows 'Subscription Unavailable' and 'The subscription is unavailable in the current storefront.' - this message is shown live in production for both iOS and macOS targets. There is no log messages shown in the Console that indicate anything going wrong with StoreKit 2, but I haven't made any changes to my code and noticed this first start appearing about 5 days ago.
I expect the subscription store to be visible to all users and for my products to display. My application is live on both the iOS and macOS AppStores, it passed App Review and I have users who have previously been able to subscribe and use my application, I have not pushed any new changes, so something has changed in StoreKit2 which is causing unexpected behaviour and for this error message to display. As 'SubscriptionStoreView' is a view provided by Apple, I'm really not sure on the pathway forward other than going back to StoreKit1 which I really don't want to do.
Is there any further error information that can be provided on what might be causing this and how I can fix it? (I have created a feedback ticket FB13658521)
Xcode 15.2, iOS 17.2
I have a piece of code that displays videos. It has been working for at least 6 months. Suddenly only the first video played. The following videos would only play audio with the video being frozen at the first frame. I noticed that SwiftUI would start to instantiate multiple instances of my player observable class instead of just one.
After chasing the problem for most of a day I found that if I completely removed every piece of code referencing AuthenticationServices then everything would work fine again.
Even if I add the following piece of code which is not used or called in any way. Then SwiftUI will start to act weird.
func configure(_ request: ASAuthorizationAppleIDRequest) {
request.requestedScopes = [.fullName, .email]
}
If I comment out request.requestedScopes = [.fullName, .email] everything works fine.
The SignInWithApple is configured and works fine if I enable the code.
Any suggestions on how to solve or any work arounds would be highly appreciated.
Hi! We added Spanish to the String Catalog. Turned out there are a lot of changes we should make to already localized text. How can we temporarily turn off / disable this language to fix all issues and then turn on Spanish support again?
Thank you!
Hi there,
I have a TabView in page style. Inside that TabView I have a number of views, each view is populated with a model object from an array. The array is iterated to provide the chart data.
Here is the code:
TabView(selection: $displayedChartIndex) {
ForEach((0..<data.count), id: \.self) { index in
ZStack {
AccuracyLineView(graphData: tabSelectorModel.lineChartModels[index])
.padding(5)
}
.tag((index))
}
}
.tabViewStyle(.page)
.indexViewStyle(.page(backgroundDisplayMode: .always))
I am seeing odd behaviour, as I swipe left and right, occasionally the chart area shows the chart from another page in the TabView. I know the correct view is being shown as there are text elements.
See the screenshot below. The screen on the right is running iOS 17.2 and this works correctly. The screen on the left is running iOS 17.4 and the date at the top is correct which tells me that the data object is correct. However the graph is showing a chart from a different page. When I click on the chart on the left (I have interaction enabled) then it immediately draws the correct chart. If I disable the interaction then I still get the behaviour albeit the chart never corrects itself because there is no interaction!
I can reproduce this in the 17.4 simulator and it is happening in my live app on iOS17.4. This has only started happening since iOS 17.4 dropped and works perfectly in iOS 17.2 simulator and I didn't notice it in the live app when I was running 17.3.
Is this a bug and/or is there a workaround?
For info this is the chart view code, it is not doing anything clever:
struct AccuracyLineView: View {
@State private var selectedIndex: Int?
let graphData: LineChartModel
func calcHourMarkers (maxTime: Int) -> [Int] {
let secondsInDay = 86400 // 60 * 60 * 24
var marks: [Int] = []
var counter = 0
while counter <= maxTime {
if (counter > 0) {
marks.append(counter)
}
counter += secondsInDay
}
return marks
}
var selectedGraphMark: GraphMark? {
var returnMark: GraphMark? = nil
var prevPoint = graphData.points.first
for point in graphData.points {
if let prevPoint {
if let selectedIndex, let lastPoint = graphData.points.last, ((point.interval + prevPoint.interval) / 2 > selectedIndex || point == lastPoint) {
if point == graphData.points.last {
if selectedIndex > (point.interval + prevPoint.interval) / 2 {
returnMark = point
} else {
returnMark = prevPoint
}
} else {
returnMark = prevPoint
break
}
}
}
prevPoint = point
}
return returnMark
}
var body: some View {
let lineColour:Color = Color(AppTheme.globalAccentColour)
VStack {
HStack {
Image(systemName: "clock")
Text(graphData.getStartDate() + " - " + graphData.getEndDate()) // 19-29 Sept
.font(.caption)
.fontWeight(.light)
Spacer()
}
Spacer()
Chart {
// Lines
ForEach(graphData.points) { item in
LineMark(
x: .value("Interval", item.interval),
y: .value("Offset", item.timeOffset),
series: .value("A", "A")
)
.interpolationMethod(.catmullRom)
.foregroundStyle(lineColour)
.symbol {
Circle()
.stroke(Color(Color(UIColor.secondarySystemGroupedBackground)), lineWidth: 4)
.fill(AppTheme.globalAccentColour)
.frame(width: 10)
}
}
ForEach(graphData.trend) { item in
LineMark (
x: .value("Interval", item.interval),
y: .value("Offset", item.timeOffset)
)
.foregroundStyle(Color(UIColor.systemGray2))
}
if let selectedGraphMark {
RuleMark(x: .value("Offset", selectedGraphMark.interval))
.foregroundStyle(Color(UIColor.systemGray4))
}
}
.chartXSelection(value: $selectedIndex)
.chartXScale(domain: [0, graphData.getMaxTime()])
}
}
}
Hello guys,
In a macOS app developed with SwiftUI and swift, the NSAccessibility key has been added to the Info.plist file to explain why the app requires Accessibility permissions, and also the AXIsProcessTrustedWithOptions function has been called, but the app is not seen in the system's Accessibility list.
I thought, it will show up in the system's Accessibility list like following
Some of my code
import SwiftUI
@available(macOS 13.0, *)
@main
struct LOKIApp: App {
@State private var activeWindow: NSWindow? = nil
@State private var accessibilityGranted = false
var body: some Scene {
MenuBarExtra("App Menu Bar Extra", image: "trayicon") {
Button("Settings") {}
.keyboardShortcut("s")
Divider()
Button("Quit") {
NSApplication.shared.terminate(nil)
}
.keyboardShortcut("q")
}.menuBarExtraStyle(.menu)
}
init() {
let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true]
let accessibilityEnabled = AXIsProcessTrustedWithOptions(options)
if accessibilityEnabled == true {
print("Accessibility is enabled")
} else {
print("Accessibility is not enabled. Please enable it in System Preferences")
}
}
}
I didn't do any other configuration, and test this app by using the command Command+R, need I set provisioning profile? Please help, thank you.
I'm trying to do something so seemingly basic, yet I can't get it to work and I'm flummoxed.
In a basic, vanilla SwiftUI app for tvOS, embed a single Text element with a very long string (hundreds of lines) in it:
struct ContentView: View {
var body: some View {
ScrollView(.vertical) {
Text(veryLargeString)
.focusable()
}
}
}
Then fire up the app on tvOS, and it will not scroll. No matter what I do. Pressing arrow keys, swiping fast with my thumb, and nothing. It will not move. Ironically, in the Xcode SwiftUI Preview window—it does scroll, so that's always a fun tease.
What I do know is that the focus engine is throwing a few errors, so it's leading me to believe the issue is with how I have the focusable element attached. I'm using a combination of -UIFocusLoggingEnabled YES as well as listening for UIFocusSystem.movementDidFailNotification.
Unfortunately since this is SwiftUI, the notification failure and debugging logs aren't really all that actionable. Help appreciated!
in this great talk https://developer.apple.com/videos/play/wwdc2023/10111/ the code references usdz models to replace hands. e.g assets/gloves/LeftGlove_v001.usdz. Are these models available to download to explain rigging and how to make hand models (ideally in Blender )
I see viewIsAppearing is available on iOS 13 and above, but when I use it, found that the function not be called below iOS 16
https://developer.apple.com/documentation/uikit/uiviewcontroller/4195485-viewisappearing
environment: Macos 14.4.1, Xcode 15.3
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let sub = SubViewController()
addChild(sub)
view.addSubview(sub.view)
}
@available(iOS 13.0, *)
override func viewIsAppearing(_ animated: Bool) {
super.viewIsAppearing(animated)
print("ViewController viewIsAppearing")
}
}
class SubViewController: UIViewController {
@available(iOS 13.0, *)
override func viewIsAppearing(_ animated: Bool) {
super.viewIsAppearing(animated)
print("SubViewController viewIsAppearing")
}
}
In iOS 15 devcice console log:
ViewController viewIsAppearing
iOS 16, 17:
ViewController viewIsAppearing
SubViewController viewIsAppearing