Although I've had no trouble persisting data with NSCoder in the past, I've encountered a problem after making the contents of the file conditional on certain data being initialized. Apologies for the length of the code - I wasn't sure how much would be relevant. The encoder looks like this:
func encode(with aCoder: NSCoder)
{
aCoder.encode(fID, forKey: "fID")
aCoder.encode(fDucats, forKey: "fDucats")
aCoder.encode(fHelpers, forKey: "fHelpers")
aCoder.encode(fClues, forKey: "fClues")
aCoder.encode(fMaps, forKey: "fMaps")
aCoder.encode(fPermits, forKey: "fPermits")
aCoder.encode(fExplorerID, forKey: "gExplorer")
aCoder.encode(fSurveyID, forKey: "gCampfire")
aCoder.encode(fHomesiteID, forKey: "gHomesite")
aCoder.encode(gSites, forKey: "gSites")
if fSurveyID >= 0
{
let total = gSurvey?.fTotalWaypoints
aCoder.encode(total, forKey: "fTotalWaypoints") // BREAKPOINT
aCoder.encode(gSurvey?.fWaypointsSet, forKey: "fWaypointsSet")
aCoder.encode(gSurvey?.fCampfireID, forKey: "fCampfireID")
aCoder.encode(gSurvey?.fWaypointIDs, forKey: "fWaypointIDs")
}
}
Using the debugger, I've determined that the value of total (an Int?) was 4 at the breakpoint.
The decoder looks like this:
required convenience init(coder aDecoder: NSCoder)
{
let id = aDecoder.decodeObject(forKey: "fID") as? String
let ducats = aDecoder.decodeInteger(forKey: "fDucats")
let helpers = aDecoder.decodeInteger(forKey: "fHelpers")
let clues = aDecoder.decodeInteger(forKey: "fClues")
let maps = aDecoder.decodeInteger(forKey: "fMaps")
let permits = aDecoder.decodeInteger(forKey: "fPermits")
let explorer = aDecoder.decodeInteger(forKey: "gExplorer")
let campfire = aDecoder.decodeInteger(forKey: "gCampfire")
let homesite = aDecoder.decodeInteger(forKey: "gHomesite")
self.init()
self.fID = id!
self.fDucats = ducats
self.fHelpers = helpers
self.fClues = clues
self.fMaps = maps
self.fPermits = permits
self.fExplorerID = explorer
self.fSurveyID = campfire
self.fHomesiteID = homesite
gSites = (aDecoder.decodeObject(forKey: "gSites") as? [Site])!
gExplorer = explorer < 0 ? nil : gSites[explorer]
gHomesite = homesite < 0 ? nil : gSites[homesite]
if fSurveyID >= 0
{
let total = aDecoder.decodeInteger(forKey: "fTotalWaypoints")
let unset = aDecoder.decodeInteger(forKey: "fWaypointsSet")
let cfire = aDecoder.decodeInteger(forKey: "fCampfireID")
gSurvey = Survey()
gSurvey?.fTotalWaypoints = total
gSurvey?.fWaypointsSet = unset
gSurvey?.fCampfireID = cfire
gSurvey?.fWaypointIDs = (aDecoder.decodeObject(forKey: "fWaypointIDs") as? [Int])!
}
}
At the initialization of total, the app crashes with "value for key (fTotalWaypoints) is not an integer number".
The file has already been saved several times when fSurveyID < 0, and I have been assuming that those earlier versions are cleanly overwritten each time.
Any help greatly appreciated,
Steve.