diff --git a/Common/Database/DatabaseManager.swift b/Common/Database/DatabaseManager.swift index 3e5bcba..72dd5e5 100644 --- a/Common/Database/DatabaseManager.swift +++ b/Common/Database/DatabaseManager.swift @@ -186,7 +186,17 @@ class DatabaseManager game.name = URL.URLByDeletingPathExtension?.lastPathComponent ?? NSLocalizedString("Game", comment: "") game.identifier = identifier game.filename = filename - game.typeIdentifier = Game.typeIdentifierForURL(URL) ?? kUTTypeDeltaGame as String + + if let pathExtension = URL.pathExtension, + gameCollection = GameCollection.gameSystemCollectionForPathExtension(pathExtension, inManagedObjectContext: managedObjectContext) + { + game.typeIdentifier = gameCollection.identifier + game.gameCollections.insert(gameCollection) + } + else + { + game.typeIdentifier = kUTTypeDeltaGame as String + } do { diff --git a/Common/Database/Model/Game+CoreDataProperties.swift b/Common/Database/Model/Game+CoreDataProperties.swift index 04a0122..6c0d51d 100644 --- a/Common/Database/Model/Game+CoreDataProperties.swift +++ b/Common/Database/Model/Game+CoreDataProperties.swift @@ -19,6 +19,8 @@ enum GameAttributes: String case identifier case name case typeIdentifier + + case gameCollections } extension Game @@ -28,4 +30,6 @@ extension Game @NSManaged var identifier: String @NSManaged var name: String @NSManaged var typeIdentifier: String + + @NSManaged var gameCollections: Set } diff --git a/Common/Database/Model/Game.swift b/Common/Database/Model/Game.swift index 807d5b7..7c6b909 100644 --- a/Common/Database/Model/Game.swift +++ b/Common/Database/Model/Game.swift @@ -23,20 +23,6 @@ class Game: NSManagedObject, GameType extension Game { - class func typeIdentifierForURL(URL: NSURL) -> String? - { - guard let pathExtension = URL.pathExtension else { return nil } - - switch pathExtension - { - case "smc": fallthrough - case "sfc": fallthrough - case "fig": return kUTTypeSNESGame as String - - default: return nil - } - } - class func supportedTypeIdentifiers() -> Set { return [kUTTypeSNESGame as String] diff --git a/Common/Database/Model/GameCollection+CoreDataProperties.swift b/Common/Database/Model/GameCollection+CoreDataProperties.swift new file mode 100644 index 0000000..8d0b791 --- /dev/null +++ b/Common/Database/Model/GameCollection+CoreDataProperties.swift @@ -0,0 +1,31 @@ +// +// 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 name + case identifier + case shortName + + case games +} + +extension GameCollection { + + @NSManaged var name: String + @NSManaged var identifier: String + @NSManaged var shortName: String? + + @NSManaged var games: Set +} diff --git a/Common/Database/Model/GameCollection.swift b/Common/Database/Model/GameCollection.swift new file mode 100644 index 0000000..caa6cec --- /dev/null +++ b/Common/Database/Model/GameCollection.swift @@ -0,0 +1,52 @@ +// +// GameCollection.swift +// Delta +// +// Created by Riley Testut on 11/1/15. +// Copyright © 2015 Riley Testut. All rights reserved. +// + +import Foundation +import CoreData + +import SNESDeltaCore + +@objc(GameCollection) +class GameCollection: NSManagedObject +{ + class func gameSystemCollectionForPathExtension(pathExtension: String?, inManagedObjectContext managedObjectContext: NSManagedObjectContext) -> GameCollection? + { + guard let pathExtension = pathExtension else { return nil } + + let identifier: String + let name: String + let shortName: String + + switch pathExtension + { + case "smc": fallthrough + case "sfc": fallthrough + case "fig": + identifier = kUTTypeSNESGame as String + name = "Super Nintendo Entertainment System" + shortName = "SNES" + + + + default: return nil + } + + let predicate = NSPredicate(format: "%K == %@", GameCollectionAttributes.identifier.rawValue, identifier) + + var gameCollection = GameCollection.instancesWithPredicate(predicate, inManagedObjectContext: managedObjectContext, type: GameCollection.self).first + if gameCollection == nil + { + gameCollection = GameCollection.insertIntoManagedObjectContext(managedObjectContext) + gameCollection?.identifier = identifier + gameCollection?.name = name + gameCollection?.shortName = shortName + } + + return gameCollection + } +} diff --git a/Common/Database/Model/Model.xcdatamodeld/Model.xcdatamodel/contents b/Common/Database/Model/Model.xcdatamodeld/Model.xcdatamodel/contents index a126424..803fdd2 100644 --- a/Common/Database/Model/Model.xcdatamodeld/Model.xcdatamodel/contents +++ b/Common/Database/Model/Model.xcdatamodeld/Model.xcdatamodel/contents @@ -14,6 +14,18 @@ + + + + + + + + + + + + @@ -21,6 +33,7 @@ - + + \ No newline at end of file diff --git a/Common/Importing/GamePickerController.swift b/Common/Importing/GamePickerController.swift index d9d489d..607306f 100644 --- a/Common/Importing/GamePickerController.swift +++ b/Common/Importing/GamePickerController.swift @@ -57,8 +57,11 @@ class GamePickerController: NSObject { let contents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(documentsDirectoryURL!, includingPropertiesForKeys: nil, options: .SkipsHiddenFiles) - let gameURLs = contents.filter({ Game.typeIdentifierForURL($0) != nil }) - self.importGamesAtURLs(gameURLs) + let managedObjectContext = DatabaseManager.sharedManager.backgroundManagedObjectContext() + managedObjectContext.performBlock() { + let gameURLs = contents.filter({ GameCollection.gameSystemCollectionForPathExtension($0.pathExtension, inManagedObjectContext: managedObjectContext) != nil }) + self.importGamesAtURLs(gameURLs) + } } catch let error as NSError diff --git a/Delta.xcodeproj/project.pbxproj b/Delta.xcodeproj/project.pbxproj index 3187e31..d5a1d6e 100644 --- a/Delta.xcodeproj/project.pbxproj +++ b/Delta.xcodeproj/project.pbxproj @@ -52,6 +52,10 @@ 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 */; }; @@ -133,6 +137,8 @@ BFAA1FF31B8AD7F900495943 /* ControllersSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControllersSettingsViewController.swift; sourceTree = ""; }; BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewDataSource.swift; path = "Collection View/GameCollectionViewDataSource.swift"; sourceTree = ""; }; 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 = ""; }; + BFC273171BE6152200D22B05 /* GameCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollection.swift; sourceTree = ""; }; BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamePickerController.swift; sourceTree = ""; }; BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Game+CoreDataProperties.swift"; sourceTree = ""; }; BFDE39391BC0CEDF003F72E8 /* Game.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = ""; }; @@ -198,6 +204,7 @@ BF4566E31BC09026007BFA1A /* Common */ = { isa = PBXGroup; children = ( + BFC273151BE612CE00D22B05 /* Model */, BFF1E55F1BE04BF6000E9EF6 /* Components */, BF9257571BD8244800B109DA /* Collection View */, BF4566E41BC0902E007BFA1A /* Database */, @@ -219,9 +226,11 @@ BF4566E51BC09033007BFA1A /* Model */ = { isa = PBXGroup; children = ( - BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */, - BFDE39391BC0CEDF003F72E8 /* Game.swift */, BF4566E61BC090B6007BFA1A /* Model.xcdatamodeld */, + BFDE39391BC0CEDF003F72E8 /* Game.swift */, + BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */, + BFC273171BE6152200D22B05 /* GameCollection.swift */, + BFC273161BE6152200D22B05 /* GameCollection+CoreDataProperties.swift */, ); path = Model; sourceTree = ""; @@ -299,6 +308,13 @@ path = Settings; sourceTree = ""; }; + BFC273151BE612CE00D22B05 /* Model */ = { + isa = PBXGroup; + children = ( + ); + name = Model; + sourceTree = ""; + }; BFDB28431BC9D9D1001D0C83 /* Importing */ = { isa = PBXGroup; children = ( @@ -594,9 +610,11 @@ buildActionMask = 2147483647; files = ( BFF4EA021BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift in Sources */, + BFC273191BE6152200D22B05 /* GameCollection+CoreDataProperties.swift in Sources */, BF6BB2411BB73FE800CCF94A /* GameSelectionViewController.swift in Sources */, BF27CC8F1BCA010200A20D89 /* GamePickerController.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 */, @@ -625,6 +643,8 @@ BFFA71DD1AAC406100EE9DD1 /* AppDelegate.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 */, BFA5342A1BDC6B520088F1BE /* GameCollectionViewLayout.swift in Sources */,