Post

Replies

Boosts

Views

Activity

Dismissing a Sheet That Doesn't Call Another View
I need to dismiss a sheet that doesn't call a view inside of it instead it makes it's own view. The reason this is necessary is because the view changes an attribute of an object in the previous view which won't update unless the attribute is changed in the same struct. Is there any way I could dismiss the view without swiping down in this way? Or a way I can pass a reference to the attribute so that when I change it in a separate struct it will update live in a previous one I'm sorry for my super confusing explanation. I've simplified my actual implemented code to the following: struct ContentView: View {     @Environment(\.dismiss) var dismiss     @State var word = ""     @State private var isSheetShowing = false     var body: some View {         NavigationView{             Form{                 TextField("Change Word", text: $word)                 Button(action: {                     isSheetShowing.toggle()                 }){                     Text("Done")                         .bold()                 }                 .sheet(isPresented: $isSheetShowing){                     NavigationView{                         List{                             Text("Hello User")                         }                         .navigationBarItems(leading:                                                 Button(action: {                             dismiss()                         }){                             Text("Cancel")                                 .bold()                         })                     }                 }             }         }     } } Pressing cancel in the sheet does not dismiss the view as I want it to.
2
0
506
Jun ’22
Calendar with Correlating Data. Please Help!!!
Basically I need a view with a calendar that will show data attributes from the item. I've tried two different approaches both have their listed problems. There must be a better way to do something like this. Surely it's not ideal to create a new item every time a date is opened or constantly check if something is there, but I don't know any other way. Actual View: import SwiftUI import CoreData struct ContentView: View {     @Environment(\.managedObjectContext) var managedObjContext     @Environment(\.calendar) var calenda     @Environment(\.dismiss) var dismiss     @FetchRequest(sortDescriptors: [], predicate: NSPredicate(format: "timestamp == %@", Date.now as CVarArg)) var items: FetchedResults<Item>          @State private var date = Date.now          var body: some View {         NavigationView{             VStack{                 DatePicker("Calendar", selection: $date, in: Date.now...,displayedComponents: [.date])                     .datePickerStyle(.graphical)                     .onAppear(perform: {                         if (items.isEmpty){                             PersistenceController().addItem(date: date, context: managedObjContext)                         }                     })                     .onChange(of: date){ value in                         items.nsPredicate=NSPredicate(format: "timestamp == %@", date as CVarArg)                         if (items.isEmpty){                             PersistenceController().addItem(date: date, context: managedObjContext)                         }                     }                 if (!items.isEmpty){ //This is the only difference in the two approaches. I just put either one of the next two blocks of code in here                 }             }             .navigationBarTitle("My Planner")         }     }          func getTitle(date: Date)->String{         let formatter = DateFormatter()         formatter.dateStyle = .medium         return formatter.string(from: date)     } } First (looks correct, but doesn't show the changes live): PlannedMealsView(item: items[0]) Spacer() //And then this is added at the bottom struct PlannedMealsView: View {     @Environment(\.managedObjectContext) var managedObjContext     @State var item: Item     var body: some View {             VStack{                 Text(item.timestamp ?? Date.now, style: .date)                     .font(.title2)                     .bold()                 Section("Word"){                     if(item.word != nil){                         HStack{                             Spacer()                             Text(item.word!)                             Spacer()                             Button(action: {                                 PersistenceController().removeFromItem(item: item, context: managedObjContext)                             }){                                 Image(systemName: "minus.circle").bold()                             }                             Spacer()                         }                     } else {                         Button(action: {                             PersistenceController().addToItem(item: item, context: managedObjContext)                         }){                             Image(systemName: "plus.circle").bold()                                 .padding(.vertical, 10)                                 .padding(.horizontal, 20)                         }                     }                 }                 Spacer()             }             .frame(height:200)     } } Second (allows direct access to the objects data, but bugs after 5 or 6 date changes): VStack{                             Text(items[0].timestamp ?? Date.now, style: .date)                                 .font(.title2)                                 .bold()                             Section("Word"){                                 if(items[0].word != nil){                                     HStack{                                         Spacer()                                         Text(items[0].word!)                                         Spacer()                                         Button(action: {                                             PersistenceController().removeFromItem(item: items[0], context: managedObjContext)                                         }){                                             Image(systemName: "minus.circle").bold()                                         }                                         Spacer()                                     }                                 } else {                                     Button(action: {                                         PersistenceController().addToItem(item: items[0], context: managedObjContext)                                     }){                                         Image(systemName: "plus.circle").bold()                                             .padding(.vertical, 10)                                             .padding(.horizontal, 20)                                     }                                 }                             }                         Spacer()                     }                     .frame(height:200) Unchanged Files: Persistence- import CoreData struct PersistenceController {     static let shared = PersistenceController()     let container: NSPersistentContainer     init(inMemory: Bool = false) {         container = NSPersistentContainer(name: "Test")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })         container.viewContext.automaticallyMergesChangesFromParent = true     }          func addItem(date: Date, context: NSManagedObjectContext){         let item = Item(context: context)         item.timestamp = date         item.word = nil                  save(context: context)     }          func addToItem(item: Item, context: NSManagedObjectContext){         item.word = "Test"                  save(context: context)     }          func removeFromItem(item: Item, context: NSManagedObjectContext){         item.word = nil                  save(context: context)     }          func save(context: NSManagedObjectContext){         do {             try context.save()         } catch {             let nsError = error as NSError             fatalError("Unresolved error \(nsError), \(nsError.userInfo)")         }     } } Data Model- If you have any questions I'll be happy to answer. Any help is greatly appreciated. All the best!
2
0
1.6k
Jun ’22
Combine Duplicate Items in an Array
I have an object called Item with two attributes, name (String) and value (Double). Given an array of Items I need combine the values of all items with the same name and keep the items with no duplicates. For example, say there were 4 items in the array and two of them named "Test" and the others "Object" and "Item". "Object" and "Item" would remain in the list, but the values of the two "Test"s would be combined into one item with the same name "Test". I've included the following code for a visual representation. Delete the comments as you read them to clean up. They're just there to clear up any confusion. Leave a comment if you have any questions. Thanks for the help! Content View: import SwiftUI import CoreData struct ContentView: View {     @Environment(\.managedObjectContext) var managedObjContext     @ObservedObject var persistence = PersistenceController.shared     @State private var items = PersistenceController.shared.getItems()          @State var isAddViewShowing = false     var body: some View {         NavigationView{             List{                 Section{                     ForEach(items) { item in //Displays the list of items                         HStack{                             Text(String(item.name!))                             Spacer()                             Text(String(Int(item.value)))                         }                     }                     .onDelete(perform: { indexSet in                         deleteItem(indexSet: indexSet)                     })                 }             }             .navigationBarTitle("Items")             .navigationBarItems(leading: combineItemsButton, trailing: addButton)             .sheet(isPresented: $isAddViewShowing){ //displays the view to add an item                 AddView()                     .onDisappear(perform: {                         items = persistence.getItems() //"refreshes" the list of items                     })             }         }     }          var combineItemsButton: some View{         Button(action:{ //combine duplicates here             persistence.contextSave()             items = persistence.getItems()         }){             Text("Combine Duplicates")                 .bold()         }     }          var addButton: some View{         Button(action:{             isAddViewShowing.toggle()         }){             Text("Add Item")                 .bold()         }     }          func deleteItem(indexSet: IndexSet){         withAnimation{             indexSet.map {                 items[$0]             }             .forEach(managedObjContext.delete)                          persistence.contextSave()             items = persistence.getItems()         }     } } Add View: struct AddView: View{     @Environment(\.dismiss) var dismiss     @ObservedObject var persistence = PersistenceController.shared          @State var name: String = ""     @State var value = ""     @State private var alertMessage = ""     @State private var showAlert = false     var body: some View{         NavigationView{             Form{                 TextField("Item Name", text: $name)                 TextField("Item Value", text: $value)                     .keyboardType(.decimalPad)             }             .navigationBarTitle("Add Item")             .navigationBarItems(leading: dismissButton, trailing: submitButton)         }     }     var submitButton: some View{         Button(action: {             if (name == ""){ //ensures the item has a name                 alertMessage="Your recipe needs a name"                 showAlert.toggle()             } else {                 persistence.addItem(name: name, value: Double(value) ?? 2)                 dismiss()             }         }){             Text("Submit")                 .bold()         }         .alert(alertMessage, isPresented: $showAlert){             Button("OK",role: .cancel){}         }     }          var dismissButton: some View{         Button(action: {             dismiss()         }){             Text("Cancel")                 .bold()         }     } } Persistence File: import CoreData class PersistenceController : ObservableObject{     static let shared = PersistenceController()     let container: NSPersistentContainer          init(inMemory: Bool = false) {         container = NSPersistentContainer(name: "Test")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })         container.viewContext.automaticallyMergesChangesFromParent = true     }          func getItems() -> [Item] { //fetches items         let context = container.viewContext         var request = NSFetchRequest<Item>()         request = Item.fetchRequest()         request.entity = NSEntityDescription.entity(forEntityName: "Item", in: context)         do {             let items = try context.fetch(request)             if items.count == 0 { return []}             return items.sorted(by: {$0.name! > $1.name!})         } catch {             print("**** ERROR: items fetch failed \(error)")             return []         }     }          func addItem(name: String, value: Double){         let context = container.viewContext         let item = Item(context: context)         item.id = UUID()         item.name = name         item.value = value                  contextSave()     }          func contextSave() {         let context = container.viewContext         if context.hasChanges {             do {                 try context.save()                 self.objectWillChange.send()             } catch {                 print("**** ERROR: Unable to save context \(error)")             }         }     } } Data Model:
2
0
2.1k
Jun ’22
Data Persistence using Core Data
So I created a program without selecting “use core data” and realized after trying to make a persistence data storage that it helps very much so I created a new program and selected it this time and copied everything over. It provided a file called “Persistence” and the contentView file had a bunch of stuff already filled in (Also something called the title of the program). I have the data I need saved to the persistent data storage narrowed down to a singular array, but none of the videos I found online showed this version of xcode that supplied a “Persistence” file when using core data so I’m unsure how to use it. I will provide the contentView and Persistence file for context. The array I need saved is called mainList in contentView. ContentView: import SwiftUI import CoreData struct ContentView: View {     var mainList = [RecipeList(),RecipeList(),RecipeList(),RecipeList(),RecipeList()]          @Environment(\.managedObjectContext) private var viewContext     @FetchRequest(         sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],         animation: .default)     private var items: FetchedResults<Item>     var body: some View {         NavigationView {             List {                 ForEach(items) { item in                     NavigationLink {                         Text("Item at \(item.timestamp!, formatter: itemFormatter)")                     } label: {                         Text(item.timestamp!, formatter: itemFormatter)                     }                 }                 .onDelete(perform: deleteItems)             }             .toolbar {                 ToolbarItem(placement: .navigationBarTrailing) {                     EditButton()                 }                 ToolbarItem {                     Button(action: addItem) {                         Label("Add Item", systemImage: "plus")                     }                 }             }             Text("Select an item")         }     }     private func addItem() {         withAnimation {             let newItem = Item(context: viewContext)             newItem.timestamp = Date()             do {                 try viewContext.save()             } catch {                 // Replace this implementation with code to handle the error appropriately.                 // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.                 let nsError = error as NSError                 fatalError("Unresolved error \(nsError), \(nsError.userInfo)")             }         }     }     private func deleteItems(offsets: IndexSet) {         withAnimation {             offsets.map { items[$0] }.forEach(viewContext.delete)             do {                 try viewContext.save()             } catch {                 // Replace this implementation with code to handle the error appropriately.                 // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.                 let nsError = error as NSError                 fatalError("Unresolved error \(nsError), \(nsError.userInfo)")             }         }     } } private let itemFormatter: DateFormatter = {     let formatter = DateFormatter()     formatter.dateStyle = .short     formatter.timeStyle = .medium     return formatter }() struct ContentView_Previews: PreviewProvider {     static var previews: some View {         ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)     } } Persistence: import CoreData struct PersistenceController {     static let shared = PersistenceController()     static var preview: PersistenceController = {         let result = PersistenceController(inMemory: true)         let viewContext = result.container.viewContext         for _ in 0..<10 {             let newItem = Item(context: viewContext)             newItem.timestamp = Date()         }         do {             try viewContext.save()         } catch {             // Replace this implementation with code to handle the error appropriately.             // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.             let nsError = error as NSError             fatalError("Unresolved error \(nsError), \(nsError.userInfo)")         }         return result     }()     let container: NSPersistentCloudKitContainer     init(inMemory: Bool = false) {         container = NSPersistentCloudKitContainer(name: "ReciStorage")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 // Replace this implementation with code to handle the error appropriately.                 // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.                 /*                  Typical reasons for an error here include:                  * The parent directory does not exist, cannot be created, or disallows writing.                  * The persistent store is not accessible, due to permissions or data protection when the device is locked.                  * The device is out of space.                  * The store could not be migrated to the current model version.                  Check the error message to determine what the actual problem was.                  */                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })         container.viewContext.automaticallyMergesChangesFromParent = true     } } Image showing the thing named the title of the program that I’m certain is relevant to the persisting data storage: Also I’m unsure what I need to replace those comments with and what subclasses I should add to existing swift files like “codable” for example. Any help would be greatly appreciated.
2
1
1.8k
Jun ’22
FetchedResults to Array
So I have a core data entity titled recipe. I'm trying to make a search bar to search the list of recipes and my method of doing so is doing a fetch request of all objects and converting it to an array of those objects and then filtering the array and displaying the results. Any idea as to how to convert a type fetch results to an array? PS: as I'm typing this it occurred to me I could just do a for each loop and add them to the array as I go, but is there a quicker way to do this? Like a function? Thanks!!!
1
0
2.6k
Jun ’22
FetchedResults to Array (Error)
So I've found a way to convert fetched results to an array of the same data type, and not only that but filter them with the fetch request given a string: func searchResults(searchingFor: String)->[Recipe]{     var filteredRecipeList=[Recipe]()     @FetchRequest(sortDescriptors: [SortDescriptor(\.date, order: .reverse)], predicate: NSPredicate(format: "title CONTAINS[c] %@",searchingFor)) var filteredResults: FetchedResults<Recipe>     for recipe in filteredResults {         filteredRecipeList.append(recipe)     }     return filteredRecipeList } To clarify, this would ideally return an array with a list of Recipes that contain the given string in the title. In theory this should work just fine, but I'm getting a weird error. I've never seen an error like this and I'm not sure how to understand it. It is purple with a yellow warning. The error says "Accessing StateObject's object without being installed on a View. This will create a new instance each time." How do I get around this issue to accomplish what I'm trying to accomplish. Thanks in advance for any help whatsoever. I'll upvote anyone with any bit of helpful information. Have a good one!
2
1
2.3k
Jun ’22
Unknown Errors From Inverse Relationship. Please Help!!!
I had the idea of adding a list feature in my app where users can create a list and add multiple recipes to the app so first and only thing I did was add an entity to my data model called "List" that contains a string: title and an array of Recipes: recipes (I remembered to put "NSSecureUnarchiveFromData" in Transformer and put [Recipe] for custom class). Afterwards I made the relationship in both entities and made them inverse. I made no other changes to my code. But I ran it just to make sure nothing went wrong and lo and behold: 7 never before seen errors, but only in one file. Before adding this entity this same code compiled just fine. This is the file and these are the errors I'm getting. Any help would be greatly appreciated. import SwiftUI struct RecipeView: View {     @Environment (\.managedObjectContext) var managedObjContext     @Environment(\.dismiss) var dismiss          var recipe: FetchedResults<Recipe>.Element     @State var isFavorite: Bool     @State var servings = -1          var body: some View {         VStack(alignment: .leading){ //Error: Trailing closure passed to parameter of type 'CGFloat?' that does not accept a closure             if (recipe.notes! != ""){                 Section{                     Text(recipe.notes!)                         .font(.headline)                 }                 .padding(.horizontal)             }             HStack{                 Spacer()                 Text("Total Time: "+calcTime(time:Int(recipe.totalTime!) ?? 0))                 Spacer()                 Text("Servings: "+recipe.servings!)                 Spacer()             }             .padding(.vertical)             Grid{                 GridRow{                     Button {                         isFavorite.toggle()                         recipe.isFavorite.toggle()                         PersistenceController().save(context: managedObjContext)                     } label: {                         HStack{                             Image(systemName: isFavorite ? "star.fill" : "star")                                 .foregroundStyle(.yellow)                             Text(isFavorite ? "Unfavorite" : "Favorite")                                 .foregroundColor(Color(UIColor.lightGray))                         }                         .frame(width: 300,height: 50)                         .background(Color(UIColor(hexString: "#202020")))                         .border(Color(UIColor(hexString: "#202020")))                         .cornerRadius(5)                     }                     Button {                         print("implement list functionality")                     } label: {                         Image(systemName: "plus")                             .frame(width: 50,height: 50)                             .background(Color(UIColor(hexString: "#202020")))                             .border(Color(UIColor(hexString: "#202020")))                             .cornerRadius(5)                     }                 }             }             .padding(.horizontal)             List{                 NavigationLink(destination: ingredientsView(ingredients: recipe.ingredients!)){                     HStack{                         Text("List of Ingredients")                         Spacer()                         Text(String(recipe.ingredients!.count))                             .foregroundColor(.gray)                     }                 }                 .frame(height: 50)                 NavigationLink(destination: instructionsView(instructions: recipe.instructions!)){                     HStack{                         Text("List of Instructions")                         Spacer()                         Text(String(recipe.instructions!.count))                             .foregroundColor(.gray)                     }                 }                 .frame(height: 50)             }             .listStyle(.grouped)             .scrollDisabled(true)             Spacer()         }         .navigationBarTitle(recipe.title!)         .navigationBarItems(trailing: shareButton)         .onAppear{             PersistenceController().updateDate(recipe: recipe, context: managedObjContext)         }         Spacer()     }     var shareButton: some View{         Button(action: {             print("Implement airdrop feature")         }){             Image(systemName: "square.and.arrow.up")                 .foregroundStyle(.blue)         }     } } struct ingredientsView: View{     @State var ingredients: [String]     var body: some View{         List{ // Error: Trailing closure passed to parameter of type 'NSManagedObjectContext' that does not accept a closure             Section(""){                 ForEach(ingredients,id: \.self){ String in                     NavigationLink(destination:                                     NavigationView{                         Text(String)                             .frame(alignment:.center)                             .font(.title)                     }){                         Text(String).lineLimit(1)                     }                 }             }         }         .frame(alignment: .center) //Error: Cannot infer contextual base in reference to member 'center' //Error: Value of type 'List' has no member 'frame'         .cornerRadius(10)         .navigationTitle("Ingredients List")     } } struct instructionsView: View{     @State var instructions: [String]     var body: some View{         List{ // Error: Trailing closure passed to parameter of type 'NSManagedObjectContext' that does not accept a closure             Section(""){                 ForEach(instructions,id: \.self){ String in                     NavigationLink(destination:                                     NavigationView{                         Text(String)                             .frame(alignment:.center)                             .font(.title)                     }){                         Text(String).lineLimit(1)                     }                 }             }         }         .frame(alignment: .center) //Error: Cannot infer contextual base in reference to member 'center' //Error: Value of type 'List' has no member 'frame'         .cornerRadius(10)         .navigationTitle("Instructions List")     } }
2
1
1.5k
Jun ’22