Thanks for the advice, @janabanana! Those other methods specifying specific classes to load didn't work to eliminate the EXC_BAD_ACCESS, so now I'm trying loading data using -[NSKeyedUnarchiver decodeTopLevelObjectForKey:] like this: @objc static func load(_ fileUrl: URL, completion: @escaping ((Any?, Error?) -> ())) {
CFCSerialQueue.processingQueue.async {
measureTime(operation: "[iCloudService Load] Loading") {
do {
try validateTargetDirectory()
if (FileManager.default.fileExists(atPath: fileUrl.path)) {
let data: Data = try Data(contentsOf: fileUrl)
let unarchiver: NSKeyedUnarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
unarchiver.requiresSecureCoding = false;
let obj: Any? = try unarchiver.decodeTopLevelObject(forKey: NSKeyedArchiveRootObjectKey)
completion(obj, nil)
} else {
completion(nil, ServiceError.generic(message: "Data not found at URL \(fileUrl)"))
}
} catch {
completion(nil, error)
}
}
}
}and made some adjustments to saving as well: @objc static func save(_ content: NSCoding, at fileName: String, completion: ((Bool, Error?) -> ())?) {
CFCSerialQueue.processingQueue.async {
measureTime(operation: "[iCloudService Save] Saving") {
do {
try validateTargetDirectory()
try validateSourceDirectory()
// writing to both local documents directory and iCloud in sequence here
let data: Data = try NSKeyedArchiver.archivedData(withRootObject: content, requiringSecureCoding: false)
try data.write(to: sourceDirectory!.appendingPathComponent(CFC_LOCAL_FILE_NAME), options: .atomicWrite)
let combinedUrl: URL = targetDirectory!.appendingPathComponent(fileName)
try? FileManager.default.removeItem(at: combinedUrl)
try data.write(to: targetDirectory!.appendingPathComponent(fileName), options: .atomicWrite) //saving the file directly to icloud
if (completion != nil) {
completion!(true, nil)
}
} catch {
if (completion != nil) {
completion!(false, error)
}
}
}
}
}I've written a unit test for this, and it looks like when the target file is saved in the local documents directory, it gets decoded properly when loaded via the above load(). But when I try the flow out on device and the target file is saved in the app's iCloud container/directory, the decoding continues to fails with an EXC_BAD_ACCESS, but now in an even weirder place, where it looks like a Double pointer in some Swift code is getting deallocated early despite a valid value always being passed to the method in question:private static func formatStatValue(value: Double, stat: FCCombineStat) -> String {
switch (stat) {
case .benchReps:
return String(format: "%.0f reps", value)
case .fortyYardDash:
return String(format: "%.2f sec", value)
case .threeCone:
return String(format: "%.2f sec", value)
case .vertical:
return String(format: "%.1f\"", value)
case .broadJump: // EXC_BAD_ACCCESS occurring on next line, seemingly because value has been deallocated?
return String(format: "%.0f\'%.0f\"", value / 12.0, value.truncatingRemainder(dividingBy: 12.0))
default:
return String(format: "%.1f", value)
}
}Got any ideas on what this could be? Could the issue be further up the stack with something that's been deallocated?Beyond where the crash has shifted to, is there something that changes in NSKeyedArchiver when writing to the iCloud documents directory that I should be aware of? I worked my way through the docs but didn't find anything specific.Thanks for your help!