How do I make it so that these two textfields aren't connected? They should have two separate backgrounds.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
So I was making a relationship between two entities in my data model and got a good ways in when I tried to run it and got a bunch of weird errors. Did I do something wrong to make this happen and if so what do I need to do? I've troubleshooted enough to realize that it happens as soon as I create a new entity. These are the errors.
So I've made a function using FetchRequest to search, but im getting an error: "Accessing StateObject's object without being installed on a View. This will create a new instance each time." The function takes a string and searches the core data for objects containing that string. The string is obtained from a .searchable object and the function is ran as a ForEach parameter.
This is the function:
func searchResults(searchingFor: String) -> FetchedResults<Recipe> {
@FetchRequest(sortDescriptors: [SortDescriptor(\.date, order: .reverse)], predicate: NSPredicate(format: "title CONTAINS[c] %@",searchingFor)) var searchRecipes: FetchedResults<Recipe>
return searchRecipes
}
Is there a better way to do this or can I do it this way and tweak it a little bit? I really just need to have a search bar that returns a FetechedResults type so I can use it in a ForEach loop. Any help is greatly appreciated.
I'm trying to filter an array containing Recipes that have a property called title of type String that is required.
These are the variables used in the line of code:
@State private var searchingFor = ""
@State private var filteredRecipes = [Recipe]()
This is the line of code giving me the error:
filteredRecipes=filteredRecipes.filter{$0.title.contains(searchingFor)}
The error: "Value of optional type 'String?' must be unwrapped to refer to member 'contains' of wrapped base type 'String'"
Any ideas on how I need to rewrite that line of code so that I don't get that error? ie. how do I unwrap 'String?'
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.
Topic:
App & System Services
SubTopic:
Core OS
Tags:
Files and Storage
Developer Tools
CloudKit
Core Data
So I have an entity in my core data model called recipe. I need to create another entity containing a recipe and a date that the recipe is assigned to. Can I do this similar to the way I've done it in the image and just save a Recipe object in the initialization of PlannedRecipe object in the Persistence file?
Basically I just need to know how to add a entity in an entity using this core data model and persistence file.
Persistence file:
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "ReciPrep")
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 addPlannedRecipe(recipe: Recipe,date: Date, context: NSManagedObjectContext){
let plannedRecipe = PlannedRecipe(context: context)
plannedRecipe.id = UUID()
plannedRecipe.date = Date()
plannedRecipe.recipe = recipe //Giving me an error: "Cannot assign value of type 'Recipe' to type 'Data?'"
save(context: context)
}
func save(context: NSManagedObjectContext){
do {
try context.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
I guess this problem can be solved if I can convert a recipe into binary data or some other savable data in an entity.
Any help would be greatly appreciated.
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!
I’ve been looking for how to do this for AGES and I’ve finally found and app made in Swift that has it.
So I really need a bar that stays at the bottom of my screen even when scrolling or changing views that has buttons on it that takes the user to a different view. And I don’t mean like a NavigationLink with a back button and a sliding transition. I mean I want it to open a whole new view and save the user’s location in the other view so when they press the button to return to the previous view they continue where they left off.
This is the GitHub app and they’ve executed exactly what I need:
To be clear this is what I’m talking about:
If anyone has a repository or a YouTube tutorial that has something like this I would be SO grateful. Thanks! :)
I need a wheel picker for hours and minutes. I've found stuff online but it does have the "Hours" and "Minutes" right after and it isn't as compact. Is there a newer way to accomplish this to look exactly like it does in the timer app?
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")
}
}
Anyone have any idea as to how to embed an SwiftUI View in a UITabBarController. From what I understand they were made to contain views made from UIKit and my views are made from SwiftUI so I’m not exactly sure how to use a UITabBarController in the storyboard with the views that I have. Any help would be greatly appreciated!
I'm sorry I know this is basic swift, but how do I get I make the selection an optional return? I know it's with ?? "" with a string, but I don't know how to do it with a date type.
Also how do I get a navigationBarTitle to work on this view? The "My Calendar" doesn't show up when I run the code.
import SwiftUI
struct ReciPrep: View {
@State private var date: Date? = ni
@Environment(\.calendar) var calendar
@State private var showingAddView = false
var body: some View {
VStack{
DatePicker("Calendar", selection: $date, in: Date.now...,displayedComponents: [.date]) //Error: Cannot convert value of type 'Binding<Date?>' to expected argument type 'Binding<Date>'
.datePickerStyle(.graphical)
Spacer()
}
.navigationBarTitle("My Calendar")
}
}
Any help would be greatly appreciated. Have a good day!
I've made a simplified version of what I'm trying to do in the included code, but basically I'm trying to make a view that edits a data model. This edit view shows up when a button in a context menu is clicked. The problem is no matter which one I open up the context menu on it always opens up whichever one I clicked first. The reference to the object in the .sheet never changes. How can I fix this??
Example Code:
import SwiftUI
class Object: Identifiable{
var id: UUID?
var title: String
var string: String
init(title: String, string: String) {
self.id = UUID()
self.title = title
self.string = string
}
}
struct ContentView: View {
@State private var showingEditView = false
@State private var objectList = [Object(title: "First", string: "Editor"), Object(title: "Second", string: "Addition"), Object(title: "Third", string: "Twelve")]
var body: some View {
NavigationView{
List{
Section("Objects"){
ForEach(objectList) { object in
NavigationLink(destination: ObjectView(obj: object)){
Text(object.title)
}
.sheet(isPresented: $showingEditView){
EditView(obj: object)
}
}
}
.contextMenu{
Button(action: {
self.showingEditView.toggle()
}){
Text("Edit Item")
}
}
}
.listStyle(InsetGroupedListStyle())
.cornerRadius(10)
.navigationBarTitle("My List")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ObjectView: View {
@State var obj: Object
var body: some View {
NavigationView{
VStack{
Text(obj.string)
}
.navigationBarTitle(obj.title)
}
}
}
struct EditView: View {
@Environment(\.dismiss) var dismiss
@State var obj: Object
@State var word = ""
var body: some View {
NavigationView{
Form{
TextField("Change Word", text: $word)
.onAppear(perform: {
word = obj.string
})
}
.navigationBarItems(trailing:
Button(action: {
dismiss()
}){
Text("Done")
.bold()
})
}
}
}
Any help would be greatly appreciated. All the best!
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.
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!