0

I'm trying to work with Core Data & SwiftUI's previews and think I'm close but haven't been able to get this to work.

    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let newGame = Game.init(context: context)
        newGame.gameName = "Testy Game"
        newGame.gameDescription = "Wooo play the thing"
        newGame.goal = Goal.init(goalName: "Try Harder", goalComplete: false, goalOfGame: newGame)
        return GameGoalsDetail(game: newGame).environment(\.managedObjectContext, context)
    }
}

I'm getting a "Ambiguous reference to member 'init(entity:insertInto:)'" on the newGame.Goal = Goal.init... line.

I'm trying to figure out how to initialize a new Game and then initialize a connected Goal to it right after.

My Core Data Game class takes gameName, gameDescription, and a goal as a NSSet?. The Core Data Goal class has goalName, goalComplete, & goalOfGame: Game?. I think my issue is in connecting the two.

Appreciate the help in advance and willing to share more code if requested.

2
  • Is the Goal init method yours? How does the Goal get a reference to the MOC? Commented Jan 15, 2020 at 20:35
  • what is Goal? How do you initialize it with no context? All the @NSManagedObject have defined init with context. In with context will Goal be inserted? By the way, you don't have to use .init(). Just call Game(context: context) Commented Jan 15, 2020 at 23:24

2 Answers 2

3

The Goal is @NSManagedObject thats why you need to use its init with context. When tou create an entity object, you must place it in some store - context is that store. After that you can cast all the properties you need including links.

let goal = Goal(context: context)
goal.goalName = "Try Harder"
goal.goalComplete = false
goal.goalOfGame = newGame
return GameGoalsDetail(game: newGame).environment(\.managedObjectContext, context)

if you set reversed links in data model, there is no need to use add-methods generated by CoreData, if you have at least 1 one-to-one link. You just set this link as a property value and CoreData do all the work for you. goal.goalOfGame is that property - reverced link one-to-one to it parent.

If you realy want to use init with all the property you want to cast, just override it in extention to your class like this:

extention Goal{
    init(of game: Game, name: String = "unnamed", complete: Bool = false, context: NSManagedObjectContext  
    ){
        super.init(context: context)
        self.goalOfGame = game
        self.goalName  = name
        self.complete = goalComplete 
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

added some ditails
In other tries I was so close. Just needed the goal.goalOfGame = newGame. I was using so many variations but kept missing that one.
2

If they are one-to-many or many-to-many relationship, you can't simply assign the Goal to the Game. When you use core data with relationships you get free "add" methods with the name of your relationship. You should be creating the Goal on one line

let newGoal = Goal.init(goalName: "Try Harder", goalComplete: false)

and then add the newGoal by calling:

newGame.addToGoal(newGoal)

That should take care of any inverse relationship as well.

1 Comment

I think it not necessary. I use one-to-many and it works with no add-method called. i just fill child-entities reversed-link property (it is one-to-many) and that's it. This item automatic inserts to parent @NSManaged NSSet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.