Post

Replies

Boosts

Views

Activity

How to solve "Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates." error?
for Hi,I am retrieving data from a web service in an URLSession and store all the entries to an arrayself.warehouseOrders.append(warehouseOrder)The array is used in another view as data source for a List() item but now I get this error message:Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.My question is: where is SwiftUI expecting me to put the operator receive(on:)) to fix this?I have kinda solved it by changing the code toDispatchQueue.main.async { self.warehouseOrders.append(warehouseOrder) }but I am not sure if that is the correct approach here?See https://forums.developer.apple.com/thread/128068for more details on my code - I have actually posted this already there as a reply but for some reason it still gets moderated for almost 24 hours ...Max
11
2
32k
Jan ’20
Update of @Published array does not update view
Hi,I have a view that displays pictures loaded via web service call. The model for the view is@ObservedObject private var pictureController: PictureController = PictureController()The pictures are provided in an array from the controller:@Published var images:[Picture] = []and the View displays the data from the array with a List (my Picture class conforms to the Identifiable protocol)List(pictureController.images){ item in Text(item.bkey) }When loading the pictures from the web service, I store them in a buffer array and afterwards copy the array over to the images arrayDispatchQueue.main.async { self.images = self.imageBuffer completionHandler(true) }I call the controller in the View's onAppear()self.pictureController.fetchPicturesByTask(bkey_issue: self.bkey_task, completionHandler: { success in print(self.pictureController.images.count) self.pictureController.images.forEach(){picture in print(picture.id) print(picture.bkey!) } })Here is the thing: self.pictureController.images.count actually return the proper count of items in the array, the prints below show the correct values but for whatever reason, the List in the View does not get updated ...Just for the sake of it I have also added a button to the View that calls a function on the controller to manually add dummy items to the array and that works perfect ...Any ideas what I am missing here?Max
11
1
9.2k
Jun ’20
Xcode cannot compile if there are too many modifiers
I have noticed that Xcode fails to compile with The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions You can execute the below demo project to recreate the error. Once you uncomment confirmationDialog entries 11+ it fails to compile. // // ContentView.swift // confDialogTest // // Created by Max on 13.06.22. // import SwiftUI struct ContentView: View { @State private var showingConf1 = false @State private var showingConf2 = false @State private var showingConf3 = false @State private var showingConf4 = false @State private var showingConf5 = false var body: some View { Button(role: .destructive) { self.showingConf1.toggle() } label: { Label("Conf 1", systemImage: "trash.fill") } .padding() Button(role: .destructive) { self.showingConf2.toggle() } label: { Label("Conf 2", systemImage: "trash.fill") } .padding() Button(role: .destructive) { self.showingConf3.toggle() } label: { Label("Conf 3", systemImage: "trash.fill") } .padding() Button(role: .destructive) { self.showingConf4.toggle() } label: { Label("Conf 4", systemImage: "trash.fill") } .padding() Button(role: .destructive) { self.showingConf5.toggle() } label: { Label("Conf 5", systemImage: "trash.fill") } // .padding() .confirmationDialog("Select location", isPresented: $showingConf1, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf2, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf3, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf4, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { Text("Conf") } //next group is dialogs 6-10 .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { Text("Conf") } .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { Text("Conf") } //next group is dialogs 11-15 // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } //next group is dialogs 16-20 // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } // .confirmationDialog("Select location", isPresented: $showingConf5, titleVisibility: .visible) { // Text("Conf") // } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } Whiel it is easy to fix here if I just move some confirmationDialogs to another Button view, I have the same problem in another problem where I have to add many modifiers to a NavigationLink in a List View and there I cannot move it around ... :/ Any ideas what to do here? Max
0
0
430
Jun ’22
NavigationView scrolling broken when using TabView
With the below code I get a very weird scrolling behaviour in my TabViews, LoginView is called on app launch: struct LoginView: View { @State private var presentContent = false var body: some View { return NavigationView { ZStack{ NavigationLink( destination: ContentView(), isActive: $presentContent, label: { EmptyView() }) Button("TEst") { self.presentContent.toggle() } } } } } struct ContentView: View { var body: some View { TabView{ Group{ List{ Text("Item 1") Text("Item 2") Text("Item 3") } } .navigationTitle("Transactions") .tabItem { Image(systemName: "list.dash") Text("Transactions") } Group{ List{ Text("Item 11") Text("Item 12") Text("Item 13") } } .navigationTitle("Summary") .tabItem { Image(systemName: "list.dash") Text("Summary") } } } } Example image below: Any ideas what that might cause?
2
0
524
May ’22
Open view deep in NavigationView from push notification
Hi, I want to open a view after taping on a push notification. The views and notifications are all working fine but my problem is when I try to open the view from the push notification via .sheet(isPresented) it is always presenting the view as modal. I would like to achieve that the view is actually opened embedded in the NavigationView it would usually be when accessing it manually. To make it more clear: import SwiftUI struct ContentView: View { 		var body: some View { NavigationView{ VStack{ NavigationLink(destination: ListView()){ Text("Going one level down") } } } 		} } struct ContentView_Previews: PreviewProvider { 		static var previews: some View { 				ContentView() 		} } struct ListView: View { var body: some View{ NavigationLink(destination: DetailView()){ Text("Click me") } } } struct DetailView: View { var body: some View{ Text("I want to display this view after tapping on a notification.") } } After tapping on the push notification, I want to jump directly to the DetailView() down in the NavigationView tree (similar to what the Apple Calendar app is doing when you tap on the notification). Any ideas? :) Max
1
0
1.1k
Jul ’20
Run CKQueryOperation with results from previous CKQueryOperation
Hi, I have an app that is a shopping list. I can store prices per product and vendor in my app, the model is Product Vendor Price One product can have multiple prices from different vendors. I store the price information with references to the product and vendor (CKRecord.Reference). Now I am using the below to fetch all the prices related to a product: public func fetchDataByProduct(product: Product, completionHandler: @escaping (Bool) -> Void){ self.pricesBuffer = [] let cloudContainer = CKContainer.init(identifier: "iCloud.XYZ") let publicDatabase = cloudContainer.publicCloudDatabase let reference = CKRecord.Reference(recordID: product.recordID, action: .deleteSelf) let predicate = NSPredicate(format: "priceToProduct == %@", reference) let query = CKQuery(recordType: "Price", predicate: predicate) let operation = CKQueryOperation(query: query) operation.recordFetchedBlock = { record in let price = Price() price.recordID = record.recordID price.grossPrice = record.object(forKey: "grossPrice") as? Double let dummy = record.object(forKey: "priceToVendor") as! CKRecord.Reference price.vendorRecordID = dummy.recordID self.pricesBuffer.append(price) } operation.queryCompletionBlock = { [unowned self] (cursor, error) in self.pricesBuffer.forEach({price in price.retrieveVendor() }) DispatchQueue.main.async { if error == nil { self.prices = self.pricesBuffer completionHandler(true) } else { } } } publicDatabase.add(operation) } My problem is now that I cannot retrieve the vendor name which is part of the Vendor object (Vendor.name). I have tried to loop over the pricesBuffer and run this one per price but the problem seems to be that CloudKit first completes the initial request to fetchDataByProduct() and then afterwards fetches the vendor data but then its too late because that updated data does not get pushed to my View (SwiftUI). publicDatabase.fetch(withRecordID: self.vendorRecordID, completionHandler:  {[unowned self] record, error in if let record = record { print(record) self.vendor.recordID = record.recordID self.vendor.name = record["name"] as! String print(self.vendor.name) } }) Any ideas how to solve this? I believe I have to add a second CKQueryOperation to the mix and use the .addDependency() but I cannot wrap my head around how that should look like in the end. Max
0
0
509
Aug ’20
An invalid value was provided for the parameter 'permissions'
Hi, When trying to validate my app and upload it to the AppStore, I get this message: An attribute in the provided entity has invalid value An invalid value was provided for the parameter 'permissions' Provisioning profile failed qualifications Profile doesn't support Push Notifications Provisioning profile failed qualification Profile doesn't include the asp-environment entitlement. I have checked the profile in Xcode and it shows that all of those are fulfilled and I have no idea what parameter 'permissions' should be ... Can you please help me out here? Regards Max
0
0
1k
Jul ’20
Trigger function when Picker changes
Hi,I have a picker of style SegmentedPickerStyle and based on the selection (Inbound, Outbound) a chart below displays different data. How can I send an event to my chart model to reload the data based on the picker selection? I know how to send the picker value to the model but how do I trigger it every time when the picker changes?I have tried something likeSunburstView(configuration: self.sunburstController.configuration).onAppear{ self.sunburstController.loadNodes(countMode: self.selectedCountMode, direction: self.selectedDirection) }but that obviously only works first time the view is loading and not after every picker change.Thanks for any hints!Max
0
0
549
May ’20
navigationBarItems disappear in TabView
Hi,I have a view that has navigation bar items and I embed that view in a TabView. But when doing that, the bar items no longer appear. If I call the view outside of a TabView everything works as expected.Below a small sample project to illustrate my issue:// // ContentView.swift // TabView // // Created by Max on 2020-03-30. // Copyright © 2020 Max. All rights reserved. // import SwiftUI struct ContentView: View { var body: some View { NavigationView{ NavigationLink(destination: WarehouseOrderTabView()){ Text("Click me") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct WarehouseOrderTabView: View { var body: some View { TabView{ TabView1().navigationBarTitle("Dashboard") .tabItem { Image(systemName: "gauge") Text("Dashboard") } TabView2().navigationBarTitle("Orders") .tabItem { Image(systemName: "list.dash") Text("Orders") } } } } struct TabView1: View { var body: some View { Text("TabView 1") //I would expect to see those bar items when displaying tab 1 .navigationBarItems(trailing: ( HStack{ Button(action: { }, label: { Image(systemName: "arrow.clockwise") .font(.title) }) .padding(.init(top: 0, leading: 0, bottom: 0, trailing: 20)) Button(action: { }, label: { Image(systemName: "slider.horizontal.3") .font(.title) }) } )) } } struct TabView2: View { var body: some View { Text("TabView 2") } }What am I missing here?Max
2
0
929
Mar ’20
Let View disappear automatically
Hi,I have a view that is triggred by a button touch. It appears nicely, all good. Now I want the View to disappear automatically again after a few seconds. How do I do that?!Below my test project// // ContentView.swift // FadeOut // // Created by Max on 2020-03-19. // Copyright © 2020 Max. All rights reserved. // import SwiftUI struct ContentView: View { @State private var presentClipboardView = false @State private var scale: CGFloat = 1.0 var body: some View { VStack{ Button(action: { let pasteboard = UIPasteboard() pasteboard.string = "http://I_AM_A_URL.com" withAnimation(.easeInOut(duration: 2)) { self.presentClipboardView.toggle() } }, label: { HStack { Image(systemName: "list.dash") .padding(.trailing) VStack(alignment: .leading) { Text("Open URL") .font(.headline) } Spacer() } } ) if(self.presentClipboardView){ LabelView() } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct LabelView: View { var body: some View { Text("URL copied to clipboard!") .padding(10) .font(.title) .foregroundColor(.white) .background(RoundedRectangle(cornerRadius: 8).fill(Color.green).shadow(color: .gray, radius: 3)) } }
3
0
1.6k
Mar ’20
Passing arguments over to View is not always available
Hi,I have a problem with passing arguments over to a View when calling it. I have this Viewstruct GoodsItemFilterView: View { @Environment(\.presentationMode) var presentationMode @EnvironmentObject private var goodsItemFilter: GoodsItemFilter @State var ref1Array: [String] = [] @State var ref2Array: [String] = [] @State var ref3Array: [String] = [] ...and when I call it I can pass over the values of the arrays as arguments:GoodsItemFilterView(ref1Array: ["MAX100", "MAX101", "MAX102"], ref2Array: ["REF2_100", "REF2_101"], ref3Array: ["REF3_100", "REF3_101"])Now I have another view which is basically a copy of this one with a few changed names etcstruct OrderHeaderFilterView: View { @Environment(\.presentationMode) var presentationMode @EnvironmentObject var settingStore: SettingStore @EnvironmentObject private var itemFilter: WarehouseOrderFilter @State var orderTypeArray: [String] = [] @State var carrierArray: [String] = [] ...and when I call it, it is not prompting me to pass over the arrays as arguments:OrderHeaderFilterView()What is the difference between those 2 views that the one is asking for arguments on initilization and the other one isn't? To be clear, in the end I want to pass over the arguments, so GoodsItemFilterView() is doing exactly what I need.Max
9
0
3.3k
Mar ’20
Localizable.strings not recognized in SwiftUI
Hi,I have a Localizable.strings file for English and German. In there I have these entries"orderOverview" = "Order Overview"; "goal" = "XXXXXXXXXXXrder Overview";in my ContentView I haveNavigationLink(destination: WarehouseOrderOverview().environmentObject(self.settingStore).navigationBarTitle("orderOverview")) { MenuButtonNavigation(title: "goal", color: Color.gray, icon: "doc.text.magnifyingglass").padding(.top) }When I now run the app, it actually shows "goal" and "orderOverview" instead of the translated values. Is there anything else I have to do?Max
0
0
412
Mar ’20