Allows explicitly downloading corrupted record versions from RecordVersionsViewController
This commit is contained in:
parent
be047b28a6
commit
061f5abd3e
@ -23,6 +23,12 @@ public class GameSave: _GameSave
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension GameSave
|
||||||
|
{
|
||||||
|
// Hacky, but YOLO I'm under time crunch.
|
||||||
|
public static var ignoredCorruptedIDs = Set<String>()
|
||||||
|
}
|
||||||
|
|
||||||
extension GameSave: Syncable
|
extension GameSave: Syncable
|
||||||
{
|
{
|
||||||
public static var syncablePrimaryKey: AnyKeyPath {
|
public static var syncablePrimaryKey: AnyKeyPath {
|
||||||
@ -71,27 +77,46 @@ extension GameSave: Syncable
|
|||||||
|
|
||||||
public func awakeFromSync(_ record: AnyRecord) throws
|
public func awakeFromSync(_ record: AnyRecord) throws
|
||||||
{
|
{
|
||||||
guard let game = self.game else { throw SyncValidationError.incorrectGame(nil) }
|
do
|
||||||
|
|
||||||
if game.identifier != self.identifier
|
|
||||||
{
|
{
|
||||||
let fetchRequest = GameSave.fetchRequest()
|
guard let game = self.game else { throw SyncValidationError.incorrectGame(nil) }
|
||||||
fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(GameSave.identifier), game.identifier)
|
|
||||||
|
|
||||||
if let misplacedGameSave = try self.managedObjectContext?.fetch(fetchRequest).first, misplacedGameSave.game == nil
|
if game.identifier != self.identifier
|
||||||
{
|
{
|
||||||
// Relink game with its correct gameSave, in case we accidentally misplaced it.
|
let fetchRequest = GameSave.fetchRequest()
|
||||||
// Otherwise, corrupted records might displace already-downloaded GameSaves
|
fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(GameSave.identifier), game.identifier)
|
||||||
// due to automatic Core Data relationship propagation, despite us throwing error.
|
|
||||||
game.gameSave = misplacedGameSave
|
if let misplacedGameSave = try self.managedObjectContext?.fetch(fetchRequest).first, misplacedGameSave.game == nil
|
||||||
|
{
|
||||||
|
// Relink game with its correct gameSave, in case we accidentally misplaced it.
|
||||||
|
// Otherwise, corrupted records might displace already-downloaded GameSaves
|
||||||
|
// due to automatic Core Data relationship propagation, despite us throwing error.
|
||||||
|
game.gameSave = misplacedGameSave
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Either there is no misplacedGameSave, or there is but it's linked to another game somehow.
|
||||||
|
game.gameSave = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
throw SyncValidationError.incorrectGame(game.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch let error as SyncValidationError
|
||||||
|
{
|
||||||
|
guard GameSave.ignoredCorruptedIDs.contains(self.identifier) else { throw error }
|
||||||
|
|
||||||
|
let fetchRequest = Game.fetchRequest()
|
||||||
|
fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(Game.identifier), self.identifier)
|
||||||
|
|
||||||
|
if let correctGame = try self.managedObjectContext?.fetch(fetchRequest).first
|
||||||
|
{
|
||||||
|
self.game = correctGame
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Either there is no misplacedGameSave, or there is but it's linked to another game somehow.
|
throw ValidationError.nilRelationshipObjects(keys: [#keyPath(GameSave.game)])
|
||||||
game.gameSave = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw SyncValidationError.incorrectGame(game.name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -258,6 +258,8 @@ private extension RecordVersionsViewController
|
|||||||
{
|
{
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
||||||
|
GameSave.ignoredCorruptedIDs.remove(self.record.recordID.identifier)
|
||||||
|
|
||||||
CATransaction.begin()
|
CATransaction.begin()
|
||||||
|
|
||||||
CATransaction.setCompletionBlock {
|
CATransaction.setCompletionBlock {
|
||||||
@ -287,17 +289,34 @@ private extension RecordVersionsViewController
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
let title: String
|
switch error
|
||||||
|
|
||||||
switch self.mode
|
|
||||||
{
|
{
|
||||||
case .restoreVersion: title = NSLocalizedString("Failed to Restore Version", comment: "")
|
case RecordError.other(let record, let error as SyncValidationError):
|
||||||
case .resolveConflict: title = NSLocalizedString("Failed to Resolve Conflict", comment: "")
|
// Only allow restoring corrupted records with incorrect games.
|
||||||
|
guard case .incorrectGame = error else { fallthrough }
|
||||||
|
|
||||||
|
let message = NSLocalizedString("Would you like to download this version anyway?", comment: "")
|
||||||
|
let alertController = UIAlertController(title: NSLocalizedString("Record Version Corrupted", comment: ""), message: message, preferredStyle: .alert)
|
||||||
|
alertController.addAction(.cancel)
|
||||||
|
alertController.addAction(UIAlertAction(title: NSLocalizedString("Download Anyway", comment: ""), style: .destructive) { _ in
|
||||||
|
GameSave.ignoredCorruptedIDs.insert(record.recordID.identifier)
|
||||||
|
self.restoreVersion()
|
||||||
|
})
|
||||||
|
self.present(alertController, animated: true, completion: nil)
|
||||||
|
|
||||||
|
default:
|
||||||
|
let title: String
|
||||||
|
|
||||||
|
switch self.mode
|
||||||
|
{
|
||||||
|
case .restoreVersion: title = NSLocalizedString("Failed to Restore Version", comment: "")
|
||||||
|
case .resolveConflict: title = NSLocalizedString("Failed to Resolve Conflict", comment: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
let alertController = UIAlertController(title: title, message: error.localizedDescription, preferredStyle: .alert)
|
||||||
|
alertController.addAction(.ok)
|
||||||
|
self.present(alertController, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let alertController = UIAlertController(title: title, message: error.localizedDescription, preferredStyle: .alert)
|
|
||||||
alertController.addAction(.ok)
|
|
||||||
self.present(alertController, animated: true, completion: nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CATransaction.commit()
|
CATransaction.commit()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user