I have two classes: Board and Formation. There is a relationship between them - each Formation is assigned a single Board. Multiple formations can be assigned to a board. This relationship is set up in CoreData as well.
I am having trouble using Core Data with Codable to encode that relationship. It throws a bad access error.
I have done my research online, but most of the articles do not touch on relationships. Please advise.
public class Board: NSManagedObject, Codable {
enum CodingKeys: CodingKey {
case lastEdited, name, notes, song, uniqueId, subFormations
}
required convenience public init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[CodingUserInfoKey.managedObjectContext] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
self.init(context: context)
let container = try decoder.container(keyedBy: CodingKeys.self)
do{
self.lastEdited = try container.decode(Date.self, forKey: .lastEdited)
self.name = try container.decode(String?.self, forKey: .name)
self.notes = try container.decode(String?.self, forKey: .notes)
self.song = try container.decode(String?.self, forKey: .song)
self.uniqueId = try container.decode(String.self, forKey: .uniqueId)
self.subFormations = try container.decode(Set<Formation>.self, forKey: .subFormations)
} catch{
print("Error Decoding Board")
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(lastEdited, forKey: .lastEdited)
try container.encode(name, forKey: .name)
try container.encode(notes, forKey: .notes)
try container.encode(song, forKey: .song)
try container.encode(uniqueId, forKey: .uniqueId)
try container.encode(subFormations, forKey: .subFormations)
}
public class Formation: NSManagedObject, Codable {
enum CodingKeys: CodingKey {
case name, position, songTime, uniqueId, waitTime, dancers, formationOwner
}
required convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[CodingUserInfoKey.managedObjectContext] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
self.init(context: context)
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.position = try container.decode(Int16.self, forKey: .position)
self.songTime = try container.decode(Float.self, forKey: .songTime)
self.uniqueId = try container.decode(String.self, forKey: .uniqueId)
self.waitTime = try container.decode(Int16.self, forKey: .waitTime)
self.formationOwner = try container.decode(Board.self, forKey: .formationOwner)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(position, forKey: .position)
try container.encode(songTime, forKey: .songTime)
try container.encode(uniqueId, forKey: .uniqueId)
try container.encode(waitTime, forKey: .waitTime)
try container.encode(formationOwner as Board, forKey: .formationOwner)
}
//Formation Properties
@NSManaged public var name: String?
@NSManaged public var position: Int16
@NSManaged public var songTime: Float
@NSManaged public var uniqueId: String
@NSManaged public var waitTime: Int16
@NSManaged public var dancers: NSSet?
@NSManaged public var formationOwner: Board
//Board Properties
try container.encode(lastEdited, forKey: .lastEdited)
try container.encode(name, forKey: .name)
try container.encode(notes, forKey: .notes)
try container.encode(song, forKey: .song)
try container.encode(uniqueId, forKey: .uniqueId)
try container.encode(subFormations, forKey: .subFormations) //Thread 1: EXC_BAD_ACCESS
Post
Replies
Boosts
Views
Activity
After having researched SpriteKit implementations and QAs, I felt it was better for me to ask the question myself. I'm trying to create a Dance Formations App where there is an option to play through all formations created. I'm Using SKAction to move each of the nodes in the formation. For example, the code loops through an array of formations, for formation 1: the 3 dancers move to their respective positions, for formation 2, the 3 dancers move to their next respective positions together, and so on.
The problem is that as I go through the for loop - each of the nodes move position is being updated asynchronously, so the dancers never go from Formation 1 -> 2 -> 3, they end up going from Formation 1 -> Last formation positions. Please help!
let action = SKAction.run{
//Calculating formationArray to get next Formation done here
for dancer in formationArray {
if let toUpdateIndex = currNodes.firstIndex(where: { $0.nodeId == dancer.id }) {
let next = CGPoint(x: CGFloat(dancer.xPos), y: CGFloat(dancer.yPos))
let action = SKAction.move(to: next , duration: 3.0)
currNodes[toUpdateIndex].run(action)
////In the above line, each node is receiving it's own position to move to
}
}
let sequence = SKAction.sequence([action, action, action])
self.run(sequence)