Refactors Core Data model objects

This commit is contained in:
Riley Testut 2016-03-14 20:03:51 -05:00
parent ba6805b0f1
commit 01bf9c0e06
13 changed files with 95 additions and 135 deletions

View File

@ -52,7 +52,7 @@ class GameCollectionViewDataSource: NSObject
{
for identifier in identifiers
{
let predicate = NSPredicate(format: "SUBQUERY(%K, $x, $x.%K == %@).@count > 0", GameAttributes.gameCollections.rawValue, GameCollectionAttributes.identifier.rawValue, identifier)
let predicate = NSPredicate(format: "SUBQUERY(%K, $x, $x.%K == %@).@count > 0", Game.Attributes.gameCollections.rawValue, GameCollection.Attributes.identifier.rawValue, identifier)
predicates.append(predicate)
}
}
@ -62,9 +62,9 @@ class GameCollectionViewDataSource: NSObject
fetchRequest.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
}
fetchRequest.sortDescriptors = [NSSortDescriptor(key: GameAttributes.typeIdentifier.rawValue, ascending: true), NSSortDescriptor(key: GameAttributes.name.rawValue, ascending: true)]
fetchRequest.sortDescriptors = [NSSortDescriptor(key: Game.Attributes.typeIdentifier.rawValue, ascending: true), NSSortDescriptor(key: Game.Attributes.name.rawValue, ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: GameAttributes.typeIdentifier.rawValue, cacheName: nil)
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: Game.Attributes.typeIdentifier.rawValue, cacheName: nil)
self.fetchedResultsController.delegate = previousDelegate
self.update()

View File

@ -321,7 +321,7 @@ private extension DatabaseManager
}
// Remove empty collections
let collections = GameCollection.instancesWithPredicate(NSPredicate(format: "%K.@count == 0", GameCollectionAttributes.games.rawValue), inManagedObjectContext: self.validationManagedObjectContext, type: GameCollection.self)
let collections = GameCollection.instancesWithPredicate(NSPredicate(format: "%K.@count == 0", GameCollection.Attributes.games.rawValue), inManagedObjectContext: self.validationManagedObjectContext, type: GameCollection.self)
for collection in collections
{

View File

@ -1,35 +0,0 @@
//
// Game+CoreDataProperties.swift
// Delta
//
// Created by Riley Testut on 10/4/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
// Choose "Create NSManagedObject Subclass" from the Core Data editor menu
// to delete and recreate this implementation file for your updated model.
//
import Foundation
import CoreData
enum GameAttributes: String
{
case artworkURL
case filename
case identifier
case name
case typeIdentifier
case gameCollections
}
extension Game
{
@NSManaged var artworkURL: NSURL?
@NSManaged var filename: String
@NSManaged var identifier: String
@NSManaged var name: String
@NSManaged var typeIdentifier: String
@NSManaged var gameCollections: Set<GameCollection>
}

View File

@ -14,9 +14,31 @@ import SNESDeltaCore
public let kUTTypeGBAGame: CFStringRef = "com.rileytestut.delta.game.gba"
extension Game
{
enum Attributes: String
{
case artworkURL
case filename
case identifier
case name
case typeIdentifier
case gameCollections
}
}
@objc(Game)
class Game: NSManagedObject, GameType
{
@NSManaged var artworkURL: NSURL?
@NSManaged var filename: String
@NSManaged var identifier: String
@NSManaged var name: String
@NSManaged var typeIdentifier: String
@NSManaged var gameCollections: Set<GameCollection>
var fileURL: NSURL {
let fileURL = DatabaseManager.gamesDirectoryURL.URLByAppendingPathComponent(self.filename)
return fileURL

View File

@ -1,29 +0,0 @@
//
// GameCollection+CoreDataProperties.swift
// Delta
//
// Created by Riley Testut on 11/1/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
// Choose "Create NSManagedObject Subclass" from the Core Data editor menu
// to delete and recreate this implementation file for your updated model.
//
import Foundation
import CoreData
enum GameCollectionAttributes: String
{
case identifier
case index
case games
}
extension GameCollection
{
@NSManaged var identifier: String
@NSManaged var index: Int16
@NSManaged var games: Set<Game>
}

View File

@ -12,9 +12,25 @@ import CoreData
import DeltaCore
import SNESDeltaCore
extension GameCollection
{
enum Attributes: String
{
case identifier
case index
case games
}
}
@objc(GameCollection)
class GameCollection: NSManagedObject
{
@NSManaged private(set) var identifier: String
@NSManaged private(set) var index: Int16
@NSManaged var games: Set<Game>
var name: String {
switch self.identifier
@ -59,7 +75,7 @@ class GameCollection: NSManagedObject
index = Int16(INT16_MAX)
}
let predicate = NSPredicate(format: "%K == %@", GameCollectionAttributes.identifier.rawValue, identifier)
let predicate = NSPredicate(format: "%K == %@", GameCollection.Attributes.identifier.rawValue, identifier)
var gameCollection = GameCollection.instancesWithPredicate(predicate, inManagedObjectContext: managedObjectContext, type: GameCollection.self).first
if gameCollection == nil

View File

@ -1,37 +0,0 @@
//
// SaveState+CoreDataProperties.swift
// Delta
//
// Created by Riley Testut on 1/31/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
// Choose "Create NSManagedObject Subclass" from the Core Data editor menu
// to delete and recreate this implementation file for your updated model.
//
import Foundation
import CoreData
enum SaveStateAttributes: String
{
case filename
case identifier
case name
case creationDate
case modifiedDate
case game
}
extension SaveState
{
@NSManaged var filename: String
@NSManaged var identifier: String
@NSManaged var name: String?
@NSManaged var creationDate: NSDate
@NSManaged var modifiedDate: NSDate
// Must be optional relationship to satisfy weird Core Data requirement
// https://forums.developer.apple.com/thread/20535
@NSManaged var game: Game!
}

View File

@ -11,9 +11,34 @@ import CoreData
import DeltaCore
extension SaveState
{
enum Attributes: String
{
case filename
case identifier
case name
case creationDate
case modifiedDate
case game
}
}
@objc(SaveState)
class SaveState: NSManagedObject, SaveStateType
{
@NSManaged var name: String?
@NSManaged var modifiedDate: NSDate
@NSManaged private(set) var filename: String
@NSManaged private(set) var identifier: String
@NSManaged private(set) var creationDate: NSDate
// Must be optional relationship to satisfy weird Core Data requirement
// https://forums.developer.apple.com/thread/20535
@NSManaged var game: Game!
var fileURL: NSURL {
let fileURL = DatabaseManager.saveStatesDirectoryURLForGame(self.game).URLByAppendingPathComponent(self.filename)
return fileURL
@ -25,3 +50,24 @@ class SaveState: NSManagedObject, SaveStateType
return imageFileURL
}
}
extension SaveState
{
@NSManaged private var primitiveFilename: String
@NSManaged private var primitiveIdentifier: String
@NSManaged private var primitiveCreationDate: NSDate
@NSManaged private var primitiveModifiedDate: NSDate
override func awakeFromInsert()
{
super.awakeFromInsert()
let identifier = NSUUID().UUIDString
let date = NSDate()
self.primitiveIdentifier = identifier
self.primitiveFilename = identifier
self.primitiveCreationDate = date
self.primitiveModifiedDate = date
}
}

View File

@ -91,7 +91,7 @@ class GamePickerController: NSObject
DatabaseManager.sharedManager.managedObjectContext.performBlock() {
let predicate = NSPredicate(format: "%K IN (%@)", GameAttributes.identifier.rawValue, identifiers)
let predicate = NSPredicate(format: "%K IN (%@)", Game.Attributes.identifier.rawValue, identifiers)
let games = Game.instancesWithPredicate(predicate, inManagedObjectContext: DatabaseManager.sharedManager.managedObjectContext, type: Game.self)
self.delegate?.gamePickerController(self, didImportGames: games)

View File

@ -13,8 +13,6 @@
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF107EC31BF413F000E0C32C /* GamesViewController.swift */; };
BF172AEB1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF172AEA1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift */; };
BF172AEC1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF172AEA1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift */; };
BF1FB1841C5EE643007E2494 /* SaveState+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FB1821C5EE643007E2494 /* SaveState+CoreDataProperties.swift */; };
BF1FB1851C5EE643007E2494 /* SaveState+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FB1821C5EE643007E2494 /* SaveState+CoreDataProperties.swift */; };
BF1FB1861C5EE643007E2494 /* SaveState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FB1831C5EE643007E2494 /* SaveState.swift */; };
BF1FB1871C5EE643007E2494 /* SaveState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FB1831C5EE643007E2494 /* SaveState.swift */; };
BF27CC8B1BC9FE4D00A20D89 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */; };
@ -75,13 +73,9 @@
BFB141191BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */; };
BFC134E11AAD82460087AD7B /* SNESDeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */; };
BFC134E21AAD82470087AD7B /* SNESDeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BFC273181BE6152200D22B05 /* GameCollection+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC273161BE6152200D22B05 /* GameCollection+CoreDataProperties.swift */; };
BFC273191BE6152200D22B05 /* GameCollection+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC273161BE6152200D22B05 /* GameCollection+CoreDataProperties.swift */; };
BFC2731A1BE6152200D22B05 /* GameCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC273171BE6152200D22B05 /* GameCollection.swift */; };
BFC2731B1BE6152200D22B05 /* GameCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC273171BE6152200D22B05 /* GameCollection.swift */; };
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */; };
BFDE393A1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */; };
BFDE393B1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */; };
BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39391BC0CEDF003F72E8 /* Game.swift */; };
BFDE393D1BC0CEDF003F72E8 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39391BC0CEDF003F72E8 /* Game.swift */; };
BFEC732D1AAECC4A00650035 /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; };
@ -136,7 +130,6 @@
BF0CDDAC1C8155D200640168 /* LoadImageOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadImageOperation.swift; path = Components/LoadImageOperation.swift; sourceTree = "<group>"; };
BF107EC31BF413F000E0C32C /* GamesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesViewController.swift; sourceTree = "<group>"; };
BF172AEA1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Conveniences.swift"; sourceTree = "<group>"; };
BF1FB1821C5EE643007E2494 /* SaveState+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SaveState+CoreDataProperties.swift"; sourceTree = "<group>"; };
BF1FB1831C5EE643007E2494 /* SaveState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SaveState.swift; sourceTree = "<group>"; };
BF27CC861BC9E3C600A20D89 /* Delta.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Delta.entitlements; sourceTree = "<group>"; };
BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pods.framework; path = "Pods/../build/Debug-appletvos/Pods.framework"; sourceTree = "<group>"; };
@ -173,10 +166,8 @@
BFAA1FF31B8AD7F900495943 /* ControllersSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControllersSettingsViewController.swift; sourceTree = "<group>"; };
BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewDataSource.swift; path = "Collection View/GameCollectionViewDataSource.swift"; sourceTree = "<group>"; };
BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFC273161BE6152200D22B05 /* GameCollection+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameCollection+CoreDataProperties.swift"; sourceTree = "<group>"; };
BFC273171BE6152200D22B05 /* GameCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollection.swift; sourceTree = "<group>"; };
BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamePickerController.swift; sourceTree = "<group>"; };
BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Game+CoreDataProperties.swift"; sourceTree = "<group>"; };
BFDE39391BC0CEDF003F72E8 /* Game.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = "<group>"; };
BFEC732C1AAECC4A00650035 /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxArtImageView.swift; path = Components/BoxArtImageView.swift; sourceTree = "<group>"; };
@ -281,11 +272,8 @@
children = (
BF4566E61BC090B6007BFA1A /* Model.xcdatamodeld */,
BFDE39391BC0CEDF003F72E8 /* Game.swift */,
BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */,
BFC273171BE6152200D22B05 /* GameCollection.swift */,
BFC273161BE6152200D22B05 /* GameCollection+CoreDataProperties.swift */,
BF1FB1831C5EE643007E2494 /* SaveState.swift */,
BF1FB1821C5EE643007E2494 /* SaveState+CoreDataProperties.swift */,
);
path = Model;
sourceTree = "<group>";
@ -685,17 +673,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BFC273191BE6152200D22B05 /* GameCollection+CoreDataProperties.swift in Sources */,
BF6BB2411BB73FE800CCF94A /* GameSelectionViewController.swift in Sources */,
BF27CC8F1BCA010200A20D89 /* GamePickerController.swift in Sources */,
BF172AEC1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift in Sources */,
BF7AE81F1C2E984300B1B5BC /* GridCollectionViewCell.swift in Sources */,
BF1FB1851C5EE643007E2494 /* SaveState+CoreDataProperties.swift in Sources */,
BF7AE8251C2E984300B1B5BC /* GridCollectionViewLayout.swift in Sources */,
BFDE393D1BC0CEDF003F72E8 /* Game.swift in Sources */,
BFC2731B1BE6152200D22B05 /* GameCollection.swift in Sources */,
BF762E9F1BC19D31002C8866 /* DatabaseManager.swift in Sources */,
BFDE393B1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */,
BF27CC911BCB156200A20D89 /* EmulationViewController.swift in Sources */,
BFB141191BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
BF1FB1871C5EE643007E2494 /* SaveState.swift in Sources */,
@ -719,7 +704,6 @@
BF7AE8241C2E984300B1B5BC /* GridCollectionViewLayout.swift in Sources */,
BF1FB1861C5EE643007E2494 /* SaveState.swift in Sources */,
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
BF1FB1841C5EE643007E2494 /* SaveState+CoreDataProperties.swift in Sources */,
BFFB709F1AF99B1700DE56FE /* EmulationViewController.swift in Sources */,
BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */,
BF353FF91C5D870B00C1184C /* PauseItem.swift in Sources */,
@ -728,7 +712,6 @@
BF7AE81E1C2E984300B1B5BC /* GridCollectionViewCell.swift in Sources */,
BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */,
BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */,
BFC273181BE6152200D22B05 /* GameCollection+CoreDataProperties.swift in Sources */,
BFC2731A1BE6152200D22B05 /* GameCollection.swift in Sources */,
BFF1E5641BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */,
BF762EAB1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */,
@ -744,7 +727,6 @@
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */,
BF353FF21C5D7FB000C1184C /* PauseViewController.swift in Sources */,
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */,
BFDE393A1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */,
BF7AE8081C2E858400B1B5BC /* PauseMenuViewController.swift in Sources */,
BF3540051C5DA70400C1184C /* SaveStatesViewController.swift in Sources */,
);

View File

@ -261,6 +261,8 @@ extension EmulationViewController: SaveStatesViewControllerDelegate
let image = UIImage(CGImage: quartzImage)
UIImagePNGRepresentation(image)?.writeToURL(saveState.imageFileURL, atomically: true)
}
saveState.modifiedDate = NSDate()
}
func saveStatesViewController(saveStatesViewController: SaveStatesViewController, loadSaveState saveState: SaveState)

View File

@ -28,7 +28,7 @@ class GamesViewController: UIViewController
required init?(coder aDecoder: NSCoder)
{
let fetchRequest = GameCollection.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: GameCollectionAttributes.index.rawValue, ascending: true)]
fetchRequest.sortDescriptors = [NSSortDescriptor(key: GameCollection.Attributes.index.rawValue, ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

View File

@ -139,8 +139,8 @@ private extension SaveStatesViewController
let fetchRequest = SaveState.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = NSPredicate(format: "%K == %@", SaveStateAttributes.game.rawValue, game)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: SaveStateAttributes.creationDate.rawValue, ascending: true)]
fetchRequest.predicate = NSPredicate(format: "%K == %@", SaveState.Attributes.game.rawValue, game)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: SaveState.Attributes.creationDate.rawValue, ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
self.fetchedResultsController.delegate = self
@ -222,17 +222,10 @@ private extension SaveStatesViewController
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
backgroundContext.performBlock {
let identifier = NSUUID().UUIDString
let date = NSDate()
var game = self.delegate.saveStatesViewControllerActiveGame(self)
game = backgroundContext.objectWithID(game.objectID) as! Game
let saveState = SaveState.insertIntoManagedObjectContext(backgroundContext)
saveState.identifier = identifier
saveState.filename = identifier
saveState.creationDate = date
saveState.modifiedDate = date
saveState.game = game
self.updateSaveState(saveState)