Adds ability to import games & controller skins from other apps

This commit is contained in:
Riley Testut 2016-12-22 16:59:29 -06:00
parent 03ddd7e7a6
commit 062abf6dbe
9 changed files with 87 additions and 33 deletions

@ -1 +1 @@
Subproject commit e936f39a694d0e1631ddceaccba6adcfda09474a
Subproject commit e2e166d01c4e866c9707944fd6df53556335056b

View File

@ -83,6 +83,7 @@
BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63BDE91D389EEB00FCB040 /* GameViewController.swift */; };
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FEC1B8AA4FA00495943 /* Settings.swift */; };
BFC314771E0C8CFC0056E3A8 /* GameType+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */; };
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; };
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; };
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
@ -186,6 +187,7 @@
BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameType+Delta.swift"; sourceTree = "<group>"; };
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatsViewController.swift; path = "Pause Menu/Cheats/CheatsViewController.swift"; sourceTree = "<group>"; };
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = "<group>"; };
BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollectionViewController.swift; sourceTree = "<group>"; };
@ -234,6 +236,7 @@
BF5942901E09BD1A0051894B /* NSFetchedResultsController+Conveniences.m */,
BF5942911E09BD1A0051894B /* NSManagedObject+Conveniences.swift */,
BF5942921E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift */,
BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -736,6 +739,7 @@
BF5942871E09BC8B0051894B /* _ControllerSkin.swift in Sources */,
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */,
BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */,
BFC314771E0C8CFC0056E3A8 /* GameType+Delta.swift in Sources */,
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
BF59426F1E09BC5D0051894B /* DatabaseManager.swift in Sources */,
BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */,

View File

@ -69,7 +69,42 @@ class AppDelegate: UIResponder, UIApplicationDelegate
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
extension AppDelegate
{
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool
{
return self.openURL(url)
}
@discardableResult fileprivate func openURL(_ url: URL) -> Bool
{
guard url.isFileURL else { return false }
let gameType = GameType.gameType(forFileExtension: url.pathExtension)
if gameType != .unknown
{
return self.importGame(at: url)
}
else if url.pathExtension.lowercased() == "deltaskin"
{
return self.importControllerSkin(at: url)
}
return false
}
private func importGame(at url: URL) -> Bool
{
DatabaseManager.shared.importGames(at: [url], completion: nil)
return true
}
private func importControllerSkin(at url: URL) -> Bool
{
DatabaseManager.shared.importControllerSkins(at: [url], completion: nil)
return true
}
}

View File

@ -38,7 +38,7 @@ class ImportController: NSObject
{
self.presentingViewController = presentingViewController
var documentTypes = Game.supportedTypes.map { $0.rawValue }
var documentTypes = GameType.supportedTypes.map { $0.rawValue }
documentTypes.append(kUTTypeDeltaControllerSkin as String)
// Add GBA4iOS's exported UTIs in case user has GBA4iOS installed (which may override Delta's UTI declarations)
@ -69,10 +69,10 @@ class ImportController: NSObject
let contents = try FileManager.default.contentsOfDirectory(at: documentsDirectoryURL, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
DatabaseManager.shared.performBackgroundTask { (context) in
let controllerSkinURLs = contents.filter { $0.pathExtension == "deltaskin" }
let controllerSkinURLs = contents.filter { $0.pathExtension.lowercased() == "deltaskin" }
self.importControllerSkins(at: controllerSkinURLs)
let gameURLs = contents.filter { GameCollection.gameSystemCollectionForPathExtension($0.pathExtension, inManagedObjectContext: context).identifier != GameType.delta.rawValue }
let gameURLs = contents.filter { GameType.gameType(forFileExtension: $0.pathExtension) != .unknown }
self.importGames(at: gameURLs)
}
@ -154,7 +154,7 @@ class ImportController: NSObject
{
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)
{
if url.pathExtension == "deltaskin"
if url.pathExtension.lowercased() == "deltaskin"
{
self.importControllerSkins(at: [url])
}

View File

@ -77,7 +77,7 @@ private extension DatabaseManager
{
self.performBackgroundTask { (context) in
for gameType in Game.supportedTypes
for gameType in GameType.supportedTypes
{
guard let deltaControllerSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: gameType) else { continue }

View File

@ -63,11 +63,3 @@ extension Game
}
}
}
extension Game
{
class var supportedTypes: Set<GameType>
{
return [GameType.snes, GameType.gba]
}
}

View File

@ -29,24 +29,16 @@ public class GameCollection: _GameCollection
class func gameSystemCollectionForPathExtension(_ pathExtension: String?, inManagedObjectContext managedObjectContext: NSManagedObjectContext) -> GameCollection
{
let identifier: String
let gameType = GameType.gameType(forFileExtension: pathExtension ?? "")
let identifier = gameType.rawValue
let index: Int16
switch pathExtension ?? ""
switch gameType
{
case "smc": fallthrough
case "sfc": fallthrough
case "fig":
identifier = GameType.snes.rawValue
index = 1990
case "gba":
identifier = GameType.gba.rawValue
index = 2001
default:
identifier = GameType.delta.rawValue
index = Int16(INT16_MAX)
case GameType.snes: index = 1990
case GameType.gba: index = 2001
default: index = Int16(INT16_MAX)
}
let predicate = NSPredicate(format: "%K == %@", #keyPath(GameCollection.identifier), identifier)

View File

@ -0,0 +1,31 @@
//
// GameType+Delta.swift
// Delta
//
// Created by Riley Testut on 12/22/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import DeltaCore
extension GameType
{
static var supportedTypes: Set<GameType>
{
return [GameType.snes, GameType.gba]
}
static func gameType(forFileExtension fileExtension: String) -> GameType
{
let gameType: GameType
switch fileExtension
{
case "smc", "sfc", "fig": gameType = GameType.snes
case "gba": gameType = GameType.gba
default: gameType = GameType.unknown
}
return gameType
}
}

View File

@ -16,7 +16,7 @@ extension GameType
{
case GameType.snes: return NSLocalizedString("Super Nintendo Entertainment System", comment: "")
case GameType.gba: return NSLocalizedString("Game Boy Advance", comment: "")
case GameType.delta: return NSLocalizedString("Unsupported System", comment: "")
case GameType.unknown: return NSLocalizedString("Unsupported System", comment: "")
default: return NSLocalizedString("Unknown", comment: "")
}
}
@ -27,7 +27,7 @@ extension GameType
{
case GameType.snes: return NSLocalizedString("SNES", comment: "")
case GameType.gba: return NSLocalizedString("GBA", comment: "")
case GameType.delta: return NSLocalizedString("Unsupported", comment: "")
case GameType.unknown: return NSLocalizedString("Unsupported", comment: "")
default: return NSLocalizedString("Unknown", comment: "")
}
}