Post

Replies

Boosts

Views

Activity

Reply to CodeSign error (nonzero exit code) HELP
Similar issue with Xcode 12 and target macOS 11.x Universal app written in SwiftUI. Suspect the cause of the issue was my late interruption of a build and run command. Not at all certain about this however. Searched A LOT but no other suggestions worked, including deleting keychain items and build folders and creating new certificates and provisioning profiles. The only solution that worked for me was to let Xcode automatically manage signing and to add the script detailed in the answer by @IndustrialDesigner PS for clarity the script was added for the macOS target under "Build Phases" by clicking the + button and selecting "New Run Script Phase", then copying the script into the black script "box" under the Shell/bin/sh line.
Jun ’21
Reply to @SectionedFetchRequest using relationship as sectionIdentifier
As hinted in the error message, you're attempting to cast the type ServiceCategory in a manner that SwiftUI cannot manage. The var sectionIdentifier is expecting a reference to a ServiceCategory as shown in this line ) var sectionedServices: SectionedFetchResults<ServiceCategory?, Service> but instead you are passing the faulted object ID _NSCoreDataTaggedObjectID per your line sectionIdentifier: \Service.serviceCategory, Service.serviceCategory holds a reference to an entity instance... in your situation the ServiceCategory entity. If you place a break point in your code and query the value you'll probably see a reference to a record id for that entity, not the actual entity object. Frankly I'd recommend that you change your approach a little write an extension on your Service entity and include a convenience method to grab this value... extension Service: NSManagedObject { @objc var serviceCategoryName: String {             return self.serviceCategory.name ?? "NO NAME" } } then use this as follows... @SectionedFetchRequest(     sectionIdentifier: \.serviceCategoryName,     sortDescriptors: [       SortDescriptor(\.active, order: .reverse),       SortDescriptor(\.displayText)     ],     predicate: NSPredicate(format: "%K = %d", #keyPath(.active), true),     animation: .default   ) var sectionedServices: SectionedFetchResults<String, Service> Note the change from type ServiceCategory to type String. and in the list... ForEach(sectionedServices) { section in Section(header: Text(section.id)) { ForEach(section) { service in Text(service.displayText ?? "") } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’21
Reply to SwiftUI TextField present integer (Int64) for macOS target
Probably shouldn't have included a link for the FB. But I figured out why NumberFormatter is not working for me... In my Core Data object graph and using my example above, the entity sortOrder is an Integer 64 type with "Use Scalar Type" checked. So when CodeGen creates an automatically generated property for my Account class, it does so with an entity attribute of type Int64 (or perhaps more correctly int64_t) instead of the (non-scalar) NSNumber. So from this I can only assume that NumberFormatter requires a non-scalar type NSNumber. I have a few reasons why I use scalar types but I expect that this will prompt me to do two things - update my feedback AND consider whether I transition to using non-scalar types in my SwiftUI code.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to SwiftUI TextField present integer (Int64) for macOS target
The problem made me realise that I was force unwrapping an Optional, something I knew but didn't fully comprehend in this context. So the entity attribute sortOrder is of type "Integer 64" and checks "Use Scalar Type". On that last point, I want to work with Int64 in my code, not NSNumber. Albeit that the UI isn't perfect, this works...     TextField("Sort Order",               text: Binding(                 get: { String(account.sortOrder) },                 set: { account.sortOrder = Int64($0.filter{ "0123456789".contains($0)}) ?? 0 }               )     ) I removed the force unwrap and instead "Coalesce using '??' to provide a default when the optional value contains 'nil'". This doesn't work...                 set: { account.sortOrder = Int64($0.filter{ "0123456789".contains($0)}) ?? nil } ... because "'nil' is not compatible with expected argument type 'Int64'". When I traverse my way into the automatically generated property file for the Account entity, I find this line of code for sortOrder...     @NSManaged public var sortOrder: Int64 This file cannot edited so, using CodeGen = Class Definition and "Use Scalar Type", I am stuck with Int64. So I guess I need to revisit my understanding of scalar types and how they work with Core Data CodeGen = Class Definition. It would seem that even though I check the "Optional" type option, the object graph and the automatically generated property file includes an Int64 - not Optional<Int64>. As noted above, in my Core Data object graph, I check the "Use Scalar Type" for the entity attribute sortOrder of type "Integer 64". I do this for a number of reasons that I will not go into here - mainly because I spent a lot of time researching this years ago and made a decision then but acknowledge it may be outdated now - so this will force me to review my use of this option in the object graph. FINALLY... Because CodeGen = Class Definition creates an automatically generated property in my Account property file with an entity attribute of scalar type Int64 instead of the (non-scalar) NSNumber (standard use), I must assume that NumberFormatter requires a non-scalar type NSNumber to function. Sure enough, when I uncheck the "Use Scalar Type" checkbox, NumberFormatter works perfectly for both macOS and iOS targets.  Conclusion: NumberFormatter currently (14 Aug 2021) works only with NSNumber.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’21
Reply to Cannot find type 'KeyPathComparator' in scope
You've not really identified the context in which the error is appearing, however I can suggest that if it is relation to sorting, then you should replace KeyPathComparator with SortDescriptor. For example... this doesn't work...     @State var sortOrder: [KeyPathComparator<ModelObject>] = [         .init(\.dateCommences, order: SortOrder.forward)     ] ... however this does...     @State var sortOrder: [SortDescriptor<ModelObject>] = [         .init(\.dateCommences, order: SortOrder.forward)     ] where dateCommences is an example property of ModelObject.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’21
Reply to Using Table Selection to Populate Other View
It may be easier to present the detail in a sheet... rather than the three column layout you are currently working with? Are you using the row selection option for Table? From the documentation... **Supporting Selection in Tables** To make rows of a table selectable, provide a binding to a selection variable. Also sounds like it may be worth submitting a Feedback to Apple to describe the problems you are facing.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’21
Reply to Using Table Selection to Populate Other View
It may be easier to present the detail in a sheet... rather than the three column layout you are currently working with? Are you using the row selection option for Table? From the documentation... Supporting Selection in Tables - To make rows of a table selectable, provide a binding to a selection variable. Also sounds like it may be worth submitting a Feedback to Apple to describe the problems you are facing.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’21
Reply to @SectionedFetchRequest filtered using an @AppStorage value
I'm not that pleased with this solution but it works (on iOS only) and until I can find a more elegant method (that also works on macOS), this will have to suffice! Noting that... @AppStorage("preference_displayArchived") var kDisplayArchived = true Using the same call to @SectionedFetchRequest in the question, I need to complete three tasks... 1 - Update the List when it appears and when the value to the preference changes to include a predicate that will effectively filter the SectionedFetchResults (in this case SectionedFetchResults<String, PTG_Event>):    var body: some View { List() { .... }         .onAppear() {         events.nsPredicate = predicateArchived         }        .onChange(of: kDisplayArchived) { _ in             events.nsPredicate = predicateArchived        } } 2 - Add a computer property for predicateArchived:     var predicateArchived: NSPredicate {         kDisplayArchived == true ? NSPredicate(value: true) : NSPredicate(format: "isArchived == %@", NSNumber(booleanLiteral: kDisplayArchived))     } 3 - Finally I also have to update the search to ensure that this app preference is adopted during the search. Building on the code presented to us in WWDC21-10017 (in presentation skip to time 21:29):     @State private var searchText = String()     var query: Binding<String> {         Binding {             searchText         } set: { newValue in             searchText = newValue             let predicate01 = NSPredicate(format: "name CONTAINS[cd] %@", newValue)             let predicate02 = NSPredicate(format: "reference CONTAINS[cd] %@", newValue)             let predicateArchived = kDisplayArchived == true ? NSPredicate(value: true) : NSPredicate(format: "isArchived == %@", NSNumber(booleanLiteral: kDisplayArchived))             let predicateOr = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate01, predicate02])             let predicateAll = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateArchived, predicateOr])             events.nsPredicate = newValue.isEmpty ? nil : predicateAll         }     } NOTES Known issue: after cancelling a search, the List refreshes without a predicate applied. Need to develop a workaround for this inconsistency.
Sep ’21
Reply to @SectionedFetchRequest filtered using an @AppStorage value
IGNORE MY PREVIOUS ANSWER!!! The following is based upon: a really good answer in StackOverflow to this question "SwiftUI View and @FetchRequest predicate with variable that can change", please refer https://stackoverflow.com/a/64200159/1883707. a well written blog "Swift with Majid" specifically this article https://swiftwithmajid.com/2020/01/22/optimizing-views-in-swiftui-using-equatableview/ and in particular his explanation of "Diffing in SwiftUI". This is the correct answer for two main reasons that I can currently identify... This pattern breaks up the larger view into smaller views, which allows SwiftUI to better render and re-render. This pattern breaks out the properties that are used in the SwiftUI diffing algorithm (as noted in the article by Majid) and therefore the fetch request calls are minimised and the predicate that I need for the @AppStorage property is injected into the child view. (I still can't quite get my head entirely around this, but the pattern works perfectly. If you can better explain it, I'd be grateful for an answer or comment.) So here is the code... struct Accounts: View {     @AppStorage("preference_displayArchived") var kDisplayArchived = true     var body: some View {         AccountsView(displayArchived: kDisplayArchived)     } } struct AccountsView: View {     let displayArchived: Bool     var body: some View {         AccountsList(accounts: SectionedFetchRequest(sectionIdentifier: \.sectionTypeName,                                                      sortDescriptors: [                                                         SortDescriptor(\.type?.name, order: .forward),                                                         SortDescriptor(\.sortOrder, order: .forward)                                                      ],                                                      predicate: displayArchived == true ? NSPredicate(value: true) : NSPredicate(format: "isArchived == %@", NSNumber(booleanLiteral: displayArchived)),                                                      animation: .default),                      displayArchived: displayArchived         )     } } struct AccountsList : View {     @SectionedFetchRequest var accounts: SectionedFetchResults<String, PTG_Account>     let displayArchived: Bool     @State private var searchText = String()     var query: Binding<String> {         Binding {             searchText         } set: { newValue in             searchText = newValue             let predicate01 = NSPredicate(format: "nameTensePresent CONTAINS[cd] %@", newValue)             let predicate02 = NSPredicate(format: "nameTensePast CONTAINS[cd] %@", newValue)             let predicateArchived = displayArchived ? NSPredicate(value: true) : NSPredicate(format: "isArchived == %@", NSNumber(booleanLiteral: displayArchived))             let predicateOr = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate01, predicate02])             let predicateAll = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateOr, predicateArchived])             accounts.nsPredicate = newValue.isEmpty ? predicateArchived : predicateAll         }     }     var title: String {         return "Title For Your View"     }     var body: some View {         VStack(spacing: 0) {             ZStack(alignment: .bottom) {                 ScrollViewReader { proxy in                     List { ...                     }                     .onChange(of: displayArchived) { _ in                         searchText = String()                     }                 }                 ListFooter(countListRows: accounts.reduce(0, {$0 + $1.count}))             }         }         .searchable(text: query)         .navigationTitle(title)         .toolbar {             ToolbarItem(placement: .primaryAction) {                 ...             }         }     } } Where @AppStorage("preference_displayArchived") var kDisplayArchived = true is the user setting to display archived files (in this case, in the Account List()). PTG_Account is the class name for a core data entity Account. .isArchived is the entity attribute of type Bool that is used to archive or unarchive an entity record (in this case, for the entity Account).
Sep ’21
Reply to Using Core Data in a new to macOS 12 (beta) `Table`
Ironically it’s not the code for Table() that was the issue. Table is itself a ScrollView At the time of writing this, Table does not function when it is embedded into another ScrollView. So, all I needed to make Table structure function as expected, is to remove it from the ScrollView! Many thanks to Apple DTS for solving this.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’21
Reply to Help with SwiftUI Binding function parameter.
Unless I'm mistaken, in your function you have declared the instance of I as Hashable, but not the Type. So maybe you should try this... func validName<I:Hashable>(name: String, focusState: Binding<FocusState<I>>, fieldToFocusNext: I, fieldToFocusOnError: I, showError: Binding<Bool> ) -> Bool?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’21
Reply to SectionedFetchRequest not updating order of Sections
I cannot make @SectionedFetchRequest work with a SortDescriptor where the value is obtained from traversing a Core Data entity relationship. Your example: item.name In fact in Xcode Version 13.1 the compiler presents me with the particularly informative "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions" and subsequently my project/s will not build. SO this is how I get around the issue (using your example)... I add a new attribute named sectionIdentifier of type String or Integer 64 optional (by default) and if Integer 64 then not scalar to the Core Data entity, in your case the entity named Attribute. With Codegen set to Class Definition, Core Data framework automatically creates an NSManagedObject with property type String? or NSNumber? respectively. Wherever the data for an instance of Attribute is entered by the user (or you), add the following .onChange modifier. (where attribute is defined by @ObservedObject var attribute: Attribute) .onChange(of: attribute.item) { changed in // or because we're not using changed, then { _ in     if let item = attribute.item {         let itemOrder = String(format: "%02d", item.order) // if you set sectionIdentifier type as String, OR         let itemOrder = item.order // if you set sectionIdentifier type as Integer 64         attribute.sectionIdentifier = itemOrder     }     else {         attribute.sectionIdentifier = "0" // if you set sectionIdentifier type as String, OR         attribute.sectionIdentifier = 0 // if you set sectionIdentifier type as Integer 64     } } Change a @SectionedFetchRequest to the following (specifically note the first SortDescriptor). @SectionedFetchRequest(sectionIdentifier: \.sectionName,                     sortDescriptors: [                         SortDescriptor(\.sectionIdentifier, order: .reverse),                          SortDescriptor(\.order, order: .reverse)],                      animation: .default ) var attributes: SectionedFetchResults<String, Attribute> This should produce a dynamically changing SectionedFetchResults for var attributes and subsequently update any List or similar view whenever order changes for an instance of Item.
Nov ’21
Reply to I can't get my ForEach List to present data from my Core Data store
I'll be straightforward about this... honestly you have created A LOT more work for yourself than needed. Modern SwiftUI projects that use the Core Data framework can handle ALL the notifications for you when you set up your persistence controller properly and use @FetchRequest or @SectionedFetchRequest. Apple has some great tutorials now that make it easier to understand common coding patterns including how to set up a Core Data stack and add and delete rows in a list. My advice would be to start a new SwiftUI project with the Core Data option checked (and "Host In CloudKit" checked if you want to backup / sync to iCloud), then rebuild your project using that template.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’21