Hi! I'm running into a warning from a SwiftUI.DynamicProperty on a 6.0 development build (swift-6.0-DEVELOPMENT-SNAPSHOT-2024-03-26-a).
I am attempting to build a type (conforming to DynamicProperty) that should also be MainActor. This type with also need a custom update function. Here is a simple custom wrapper (handwaving over the orthogonal missing pieces) that shows the warning:
import SwiftUI
@MainActor struct MainProperty: DynamicProperty {
// Main actor-isolated instance method 'update()' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode
@MainActor func update() {
}
}
Is there anything I can do about that warning? Does the warning correctly imply that this will be a legit compiler error when 6.0 ships?
I can find (at least) two examples of types adopting DynamicProperty from Apple that are also MainActor: FetchRequest and SectionedFetchRequest. What is confusing is that both FetchRequest^1 and SectionedFetchRequest^2 explicitly declare their update method to be MainActor. Is there anything missing from my Wrapper declaration that can get me what I'm looking for? Any more advice about that? Thanks!
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.
Post
Replies
Boosts
Views
Activity
I'm building a macOS app using SwiftUI and I recently updated to xcode 14.3. Since then I've been debugging why none of my animations were working, it turned out that the NavigationSplitView or NavigationStack are somehow interfering with all the animations from withAnimation to .transition() and everything in between.
Is anyone else experiencing this, knows a work around or knows why this is happening?
Environment:
Xcode16, iOS 18.1 official version
Background:
I created a control center widget using a custom sf symbol
Phenomenon:
When I first installed it, it displayed normally in the control gallery, but when I recompiled and installed it again, the icon disappeared when I looked at it again in the control gallery. I used Console to check the error log and found that its output was' No image named 'my_custom _symbol_name' found in asset catalog for/private/var/containers/Bundle/Application/F977FCFB-DA1C-4924-8613-50531CA2A364/MyDemoApp. app/PlugIns/MyDemoApp Extension. apex '. I found that this uuid was not consistent with the uuid I print during debugging, as if the control gallery had done some kind of caching;
Additionally, when I added my Control to the Control Center, it was able to display normally, and the only issue was with the Control Gallery
Attempted method:
-Using the system SF Symbol, it works fine and can be displayed normally in the control gallery after recompilation. However, once I switch another SF Symbols, the icons in the control gallery do not update after recompilation and installation
-Restarting the device, the same issue still persists
Is this a system bug or did I make a mistake? Looking forward to someone helping, thank you
My Code:
@available(iOSApplicationExtension 18.0, *)
struct MySearchControlWidget: ControlWidget {
let kind = "MySearchControlWidget"
let title = "My Title"
var body: some ControlWidgetConfiguration {
let intent = MyCommonButtonControlWidgetIntent()
StaticControlConfiguration(kind: kind) {
ControlWidgetButton(action: intent) {
Label("\(title)", image:"my_custom_symbol_name")
}
}
.displayName("\(title)")
}
}
Hey,
I know you can write @AppStorage("username") var username: String = "Anonymous" to access a Value, stored In the User Defaults, and you can also overwrite him by changing the value of username.
I was wondering if there is any workaround to use @AppStorage with Arrays.
Because I don't find anything, but I have a lot of situations where I would use it.
Thanks!
Max
I am using iphone 11 with ios version 18.1 and I found one issue in call recording during FT audio call. Call gets dropped as soon as call recording start. This bug is also reproducible on iphone 14 pro max having same ios version. I tried it 5/5 times and it is 100% reproducible. Can you please help to fix this issue. This is really a serious quality concern as per apple standards.
QLPreviewView was used in the app to display the file previews. But the following crash was happening.
Date/Time: 2024-09-13 22:03:59.056 +0530
OS Version: Mac OS X 10.13.6 (17G14042)
Report Version: 12
Anonymous UUID: 7CA3750A-2BDD-3FFF-5940-E5EEAE2E55F5
Time Awake Since Boot: 4300 seconds
System Integrity Protection: disabled
Notes: Translocated Process
Crashed Thread: 0
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: DYLD, [0x1] Library missing
Application Specific Information:
dyld: launch, loading dependent libraries
Dyld Error Message:
Library not loaded: /System/Library/Frameworks/QuickLookUI.framework/Versions/A/QuickLookUI
Referenced from: /private/var/folders/*/Notebook (Beta).app/Contents/MacOS/Notebook (Beta)
Reason: image not found
I've looked at lots of Grid examples. I've seen it documented that views within a GridRow are treated as if they were in an HStack. That's not happening for me. I have to explicitly put them into an HStack or they are treated as new rows.
Here's my code:
@State private var gridRows : Int = 4
@State private var gridCols : Int = 2
@State private var myItems : [Int] = Array(0...8)
var body: some View
{
Group
{
if myItems.count > 0
{
ScrollView([.vertical])
{
Grid(alignment: .leading)
{
ForEach(0..<gridRows, id: \.self)
{ rowNdx in
GridRow
{
HStack // <<---
{
ForEach(0..<gridCols, id: \.self)
{ colNdx in
Text("\(rowNdx) \(colNdx)")
}
}
}
}
}
}
}
}
}
With the HStack I get (as expected).
0 0 0 1
1 0 1 1
2 0 2 1
3 0 3 1
Without the HStack I get
0 0
0 1
1 0
1 1
...
What have I done wrong?
we are migrating our app to support Arabic language support but the requirement is we want the calendar/date object to display as missed. That is all the numbers in english digits and rest all the words like days, months should be in Arabic.
I tried few options but at the end its resulting everything is in Arabic or in English but not the mixed as expected. Attaching the expected behavior.
Development environment: Xcode 16.1, macOS 15.1 (24B83)
OS version: iOS iOS 17.5 and above
When NavigationStack is presented by a sheet, and navigationDestination API is being used for navigation within the stack, the sheet content is forced to be reevaluated when app is in background.
Sample Project
import SwiftUI
struct TestView: View {
var id: Int
@State private var isLoading = false
@State private var presentSheet = false
var body: some View {
let _ = Self._printChanges()
VStack {
if isLoading {
ProgressView()
} else {
VStack {
Text("View: \(id)")
Text("Not loading")
Button("Present Sheet in NavStack") {
presentSheet = true
}
NavigationLink("Show Link", value: id * 100)
}
}
}
.sheet(
isPresented: $presentSheet,
content: {
NavigationStack {
TestView(id: self.id + 1)
// Comment this block out and note the view no longer reloads when app is in background when there's > 1 sheet modals
.navigationDestination(for: Int.self, destination: { num in
TestView(id: num)
})
}
}
)
.task {
isLoading = true
defer {
isLoading = false
}
try? await Task.sleep(for: .seconds(1))
}
}
}
struct ContentView: View {
var body: some View {
let _ = Self._printChanges()
VStack {
content
.padding()
}
}
var content: some View {
VStack {
NavigationStack {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
TestView(id: 0)
}
.navigationDestination(for: Int.self, destination: { num in
TestView(id: num)
})
}
}
}
}
Steps to reproduce:
To reproduce the issue in the sample project:
Tap on present sheet in navstack button to invoke View #1 presented in sheet
Put the app into multitasking mode by tapping on the simulator home button twice
Observe that console does not emit debug messages on SwiftUI View change. Also observe that there was no loading in the view
Tap on present sheet in navstack button again to invoke View #2 presented in sheet
Repeat step #2, but this time observe that console does emit debug message that SwiftUI View were changed due to the following:
TestView: @self, @identity, _isLoading, _presentSheet changed.
TestView: _isLoading changed.
TestView: _isLoading changed.
To remove the issue:
7. Comment out the block on navigationDestination. Recompile the app and run it in simulator
8. Repeat step 2-5. Note this time the console does not emit debug message that SwiftUI View were changed.
We are having issues with implementing a List that has Views in it that contain a Textfield.
The criteria we are trying to achieve is
Select to edit the quantity of a product
Auto focus on the row with that textfield, with the textfield's contents selected
Display/Dismiss the keyboard
Mask other rows in the list while interacting with a qty field
We explored many routes and are looking for direction on what the designated approach is. This originally was a Tech Support Incident, and I was instructed to post here. There were 2 working project examples available if needed.
In an implementation that has the FocusState on the parent view, we see collisions in animation / weird jumpiness
// MARK: - Constant
enum Constant {
static let logTag = "AddReplenishmentProductView"
}
@Binding var state: ContentViewState
// MARK: - Private Properties
@State private var focusedLineItemId: String?
// MARK: - Life cycle
var body: some View {
VStack {
replenishmentProductList
}
.background(.tertiary)
.navigationTitle("Add Products")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
}
// MARK: - Private Computed properties
@ViewBuilder
private var replenishmentProductList: some View {
ScrollViewReader { proxy in
List {
let list = Array(state.lineItems.enumerated())
ForEach(list, id: \.1.product.id) { (index, lineItem) in
RowView(
lineItem: $state.lineItems[index],
focusedLineItemId: $focusedLineItemId
)
.id(lineItem.id.uuidString)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.alignmentGuide(.listRowSeparatorLeading) { _ in
return 0
}
// Blocks all the other rows that we are not focusing on.
.maskingOverlay(focusId: $focusedLineItemId, elementId: "\(lineItem.id)")
}
.listSectionSeparator(.hidden)
}
.listStyle(.plain)
.scrollDismissesKeyboard(.never)
.scrollContentBackground(.hidden)
/*
We are looking for a solution that doesn't require us to have this onChange modifier
whenever we want to change a focus.
*/
.onChange(of: focusedLineItemId) {
guard let lineItemId = focusedLineItemId else { return }
/*
We need to scroll to a whole RowView so we can see both done and cancel buttons.
Without this, the focus will auto-scroll only to the text field, due to updating FocusState.
We are experiencing weird jumping issues. It feels like the animations for focus on
text field and RowView are clashing between each other.
To fix this, we added a delay to the scroll so the focus animation completes first and then we
scroll to the RowView.
However, when we attempt to focus on a row that is partially shown, sometimes the RowView won't
update it's focus and won't focus ultimately on the TextField until we scroll.
*/
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
// We need to add the withAnimation call to animate the scroll to the whole row.
proxy.scrollTo(lineItemId, anchor: .top)
}
}
}
}
}
}
In an implementation where the FocusState is on the row views, we see issues with actually being able to focus. When quantity field we tap is located on a row near the top/bottom of the screen it does not look to be identified correctly, and the ability to scrollTo / the keyboard being presented are broken.
struct ContentView: View {
// MARK: - Constant
enum Constant {
static let logTag = "AddReplenishmentProductView"
}
@Binding var state: ContentViewState
// MARK: - Private Properties
@State private var focusedLineItemId: String?
@FocusState private var focus: String?
// MARK: - Life cycle
var body: some View {
VStack {
replenishmentProductList
}
.background(.tertiary)
.navigationTitle("Add Products")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
}
// MARK: - Private Computed properties
@ViewBuilder
private var replenishmentProductList: some View {
ScrollViewReader { proxy in
List {
let list = Array(state.lineItems.enumerated())
ForEach(list, id: \.1.product.id) { (index, lineItem) in
RowView(
lineItem: $state.lineItems[index],
focusedLineItemId: $focusedLineItemId,
focus: $focus
)
.id(lineItem.id.uuidString)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.alignmentGuide(.listRowSeparatorLeading) { _ in
return 0
}
// Blocks all the other rows that we are not focusing on.
.maskingOverlay(focusId: $focusedLineItemId, elementId: "\(lineItem.id)")
}
.listSectionSeparator(.hidden)
}
.listStyle(.plain)
.scrollDismissesKeyboard(.never)
.scrollContentBackground(.hidden)
/*
We are looking for a solution that doesn't require us to have this onChange modifier
whenever we want to change a focus.
*/
.onChange(of: focusedLineItemId) {
/*
We need to scroll to a whole RowView so we can see both done and cancel buttons.
Without this, the focus will auto-scroll only to the text field, due to updating FocusState.
However, we are experiencing weird jumping issues. It feels like the animations for focus on
text field and RowView are clashing between each other.
*/
focus = focusedLineItemId
guard let lineItemId = focusedLineItemId else { return }
withAnimation {
// We need to add the withAnimation call to animate the scroll to the whole row.
proxy.scrollTo(lineItemId, anchor: .top)
}
}
}
}
}
Hi
I have tried the code given on link https://developer.apple.com/documentation/appdistribution/fetching-and-displaying-managed-apps. This code is not compilable in Xcode 16.1.
After some fixes i am able to run the code but i am getting Error registering for message: [App catalog changed]: An unspecified, unrecoverable error occurred.
Kindly help me with this.
Running up Xcode 16.2 Beta 1, a lot of my code that used onPreferenceChange in Views to change @State properties of those views, such as some notion of a measured width is now complaining about mutating the @MainActor-isolated properties from Sendable closures.
Now I've got to hoop-jump to change @State properties from onPreferenceChange? OK, but seems a bit of extra churn.
Hi,
I'm trying to create a UICollectionView where the cell high is automatic. Cells contains a UILabel with all anchors to the contentView of the cell.
It seems to work but I have a strange behavior with longer text, on reload data and on device rotation: Cells do not display the whole text or they change row, both randomly.
To create my collection view I first create the collection view with a custom flow layout setting the automatic size on viewWillAppear:
let collectionViewFlowLayout = CustomFlowLayout()
collectionViewFlowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewFlowLayout)
and I have also overridden:
override func willAnimateRotation(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
collectionView.setNeedsLayout()
self.collectionView.layoutIfNeeded()
self.collectionView.collectionViewLayout.invalidateLayout()
//self.collectionView.reloadData()
}
Then, I created the custom layout as follow:
import UIKit
final class CustomFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributesObjects = super.layoutAttributesForElements(in: rect)?.map{ $0.copy() } as? [UICollectionViewLayoutAttributes]
layoutAttributesObjects?.forEach({ layoutAttributes in
if layoutAttributes.representedElementCategory == .cell {
if let newFrame = layoutAttributesForItem(at: layoutAttributes.indexPath)?.frame {
layoutAttributes.frame = newFrame
}
}
})
return layoutAttributesObjects
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let collectionView = collectionView else {
fatalError()
}
guard let layoutAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as? UICollectionViewLayoutAttributes else {
return nil
}
layoutAttributes.frame.origin.x = sectionInset.left
if(indexPath.section == 0){
layoutAttributes.frame.size.width = collectionView.safeAreaLayoutGuide.layoutFrame.width - sectionInset.left - sectionInset.right
} else if (indexPath.section == collectionView.numberOfSections - 1){
let width = ScreenUtility.getCollectionCellWidthForElement(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing, multiplier: 3)
layoutAttributes.frame.origin.x = ScreenUtility.getCollectionCellOriginForElement(in: collectionView, at: indexPath, forElementHavingWidth: width, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing, multiplier: 3)
layoutAttributes.frame.size.width = width
} else if (indexPath.section == collectionView.numberOfSections - 3) || (indexPath.section == collectionView.numberOfSections - 4){
let width = ScreenUtility.getCollectionCellWidthForElement(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing)
layoutAttributes.frame.origin.x = ScreenUtility.getCollectionCellOriginForElement(in: collectionView, at: indexPath, forElementHavingWidth: width, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing)
layoutAttributes.frame.size.width = width
} else {
let width = ScreenUtility.getCollectionCellSizeForElementFullRow(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right)
layoutAttributes.frame.origin.x = ScreenUtility.getCollectionCellOriginForElementFullRow(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right)
layoutAttributes.frame.size.width = width
}
return layoutAttributes
}
}
And finally on collection view cells:
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
setNeedsLayout()
layoutIfNeeded()
let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)
layoutAttributes.frame.size = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
return layoutAttributes
}
override func prepareForReuse() {
self.nameLabel.text = ""
self.idLabel.text = ""
self.contentView.setNeedsLayout()
self.contentView.layoutIfNeeded()
}
Let me show you an example on the iPad that is the worst.
First Time I open the collection view I have cells on wrong rows and not sized properly
Then I rotate the device portrait and the cells are fine
On landscape again it changes behavior:
This is just an example, things happens apparently randomly, and also sometimes cells disappear (I think the height is set to 0).
I really do not understand why, cells width seems to be computed correctly, and cell label is set via setter:
open var step: String = "" {
didSet {
nameLabel.text = step
nameLabel.sizeToFit()
self.contentView.setNeedsLayout()
self.contentView.layoutIfNeeded()
}
}
We're seeing sporadic crashes on devices running iOS 18.1 - both beta and release builds (22B83). The stack trace is always identical, a snippet of it below. As you can tell from the trace, it's happening in places we embed SwiftUI into UIKit via UIHostingController.
Anyone else seeing this?
4 libobjc.A.dylib 0xbe2c _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30
5 libobjc.A.dylib 0xb040 weak_register_no_lock + 396
6 libobjc.A.dylib 0xac50 objc_storeWeak + 472
7 libswiftCore.dylib 0x43ac34 swift_unknownObjectWeakAssign + 24
8 SwiftUI 0xeb74c8 _UIHostingView.base.getter + 160
9 SwiftUI 0x92124 _UIHostingView.layoutSubviews() + 112
10 SwiftUI 0x47860 @objc _UIHostingView.layoutSubviews() + 36
On iOS you can create a new Lock Screen that contains a bunch of emoji, and they'll get put on the screen in a repeating pattern, like this:
When you have two or more emoji they're placed in alternating patterns, like this:
How do I write something like that? I need to handle up to three emoji, and I need the canvas as large as the device's screen, and it needs to be saved as an image. Thanks!
(I've already written an emojiToImage() extension on String, but it just plonks one massive emoji in the middle of an image, so I'm doing something wrong there.)
In the Explore enhancements to App Intents WWDC video at the 11 minute mark I see this UI in the Widget configuration.
My question is, how do I configure my Widget to use this UI in the intent configuration? I tried using all different sorts of types and am unable to reproduce it in my app
Running an existing Xcode project in an iPad OS 18 simulator is automatically using the newly introduced tab bar view, moved from the bottom to the top.
Unfortunately, the isEnabled property on a tar bar item is no longer honored.
In Xcode's Storyboard builder, some tab bar items are initially disabled. (can't add a screenshot here, I will try to do that after posting)
The iPad OS 17 simulator shows them correctly as disabled and any user interaction is suppressed as expected.
The iPad OS 18 simulator shows them as active and they can be selected. Also setting them to disabled inside of the UITabBarViewController doesn't work:
for item in self.tabBar.items! {
if item.tag != 99 {
item.isEnabled = false
}
}
They stay enabled and selectable.
As a workaround, I implemented the UITabBarViewControllerDelegate and overrode this method:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if Global.shared.accessToken == nil {
if viewController is LoginViewController || viewController is SettingsViewController {
return true
} else {
return false
}
}
return true
}
The user can no longer select the tabs, however, there is no visual indicator that they are not selectable.
I cannot find any indication in the release notes or documentation, that this behavior is intentional. So I assume this is a bug.
Hi, after updating Xcode to Version 16.1, I started a new multiplatform project targeting macOS and iOS. Everything worked fine until I added Firebase SDK 11.4 (using Swift Package Manager). Now, I'm facing an issue where the preview is not possible with "My Mac" after adding Firebase SDK, even with a very simple view like:
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
However, previewing with iPhone or iPad works fine. This is really frustrating. When I run the app on a simulator (Mac, iPhone, or iPad), everything works perfectly.
The error shown is Cannot preview in this file: Failed to launch [AppName] with the following path: /Users/[myname]/Library/Developer/Xcode/DerivedData/[AppName-gemeoxpjlzrshfifmgmqrkcxdeiz/Build/Products/Debug/FirebaseFirestoreInternal.framework/FirebaseFirestoreInternal
Run Destination: macOS 15.1.
What I have tried so far:
Cleaned the build folder
Re-installed Firebase SDK
Any insights would be greatly appreciated! Thank you!
Hi,
I am trying out the new UITabBar stuff in iOS18, and I don't think it'll be a good fit for my app. Is there a way to revert to the old iPad UITabBar look and placement that we've been using before? I don't want to make such a big change like this just yet, but I would need to make other changes to the app as well and I don't want to use the new UITabBar just yet. Is there a way to achieve this?
Hello!
I am trying to remove a photo from my Photos Library using PhotosUI. I run into this error when I attempt to delete it:
"Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)""
No photos access scope requirements declared for changes
Failed to log access with error: access= accessor:<> identifier:82068C12-FD10-4DE2-9867-B4406FBFB706 kind:intervalEvent timestampAdjustment:0 visibilityState:0 assetIdentifierCount:0 accessCount:0 tccService:kTCCServicePhotos, error=Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.privacyaccountingd" UserInfo={NSDebugDescription=connection to service named com.apple.privacyaccountingd}