Fixes remaining Beta 4 syntax issues manually that the migrator missed

This commit is contained in:
Riley Testut 2016-08-06 23:18:55 -05:00
parent 95a2efdc01
commit 7c8405d4e7
20 changed files with 135 additions and 151 deletions

View File

@ -46,23 +46,23 @@ class GameCollectionViewDataSource: NSObject
let fetchRequest = Game.rst_fetchRequest()
var predicates: [Predicate] = []
var predicates: [NSPredicate] = []
if let identifiers = self.supportedGameCollectionIdentifiers
{
for identifier in identifiers
{
let predicate = Predicate(format: "SUBQUERY(%K, $x, $x.%K == %@).@count > 0", Game.Attributes.gameCollections.rawValue, GameCollection.Attributes.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)
}
}
if predicates.count > 0
{
fetchRequest.predicate = CompoundPredicate(orPredicateWithSubpredicates: predicates)
fetchRequest.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
}
fetchRequest.sortDescriptors = [SortDescriptor(key: Game.Attributes.type.rawValue, ascending: true), SortDescriptor(key: Game.Attributes.name.rawValue, ascending: true)]
fetchRequest.sortDescriptors = [NSSortDescriptor(key: Game.Attributes.type.rawValue, ascending: true), NSSortDescriptor(key: Game.Attributes.name.rawValue, ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: Game.Attributes.type.rawValue, cacheName: nil)
self.fetchedResultsController.delegate = previousDelegate

View File

@ -25,7 +25,7 @@ public class LoadImageOperation: RSTOperation
}
}
public var imageCache: Cache<NSURL, UIImage>? {
public var imageCache: NSCache<NSURL, UIImage>? {
didSet {
// Ensures if an image is cached, it will be returned immediately, to prevent temporary flash of placeholder image
self.isImmediate = self.imageCache?.object(forKey: self.URL) != nil

View File

@ -29,7 +29,7 @@ class DatabaseManager
private init()
{
let modelURL = Bundle.main.urlForResource("Model", withExtension: "momd")
let modelURL = Bundle.main.url(forResource: "Model", withExtension: "momd")
let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL!)
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel!)
@ -52,9 +52,9 @@ class DatabaseManager
func startWithCompletion(_ completionBlock: ((performingMigration: Bool) -> Void)?)
{
DispatchQueue.global(attributes: DispatchQueue.GlobalAttributes.qosUserInitiated).async {
DispatchQueue.global(qos: .userInitiated).async {
let storeURL = try! DatabaseManager.databaseDirectoryURL.appendingPathComponent("Delta.sqlite")
let storeURL = DatabaseManager.databaseDirectoryURL.appendingPathComponent("Delta.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
@ -106,42 +106,28 @@ class DatabaseManager
{
let identifier = FileHash.sha1HashOfFile(atPath: URL.path) as String
var filename = identifier
if let pathExtension = URL.pathExtension
{
filename += "." + pathExtension
}
let filename = identifier + "." + URL.pathExtension
let game = Game.insertIntoManagedObjectContext(managedObjectContext)
game.name = try! URL.deletingPathExtension().lastPathComponent ?? NSLocalizedString("Game", comment: "")
game.name = URL.deletingPathExtension().lastPathComponent ?? NSLocalizedString("Game", comment: "")
game.identifier = identifier
game.filename = filename
if let pathExtension = URL.pathExtension
{
let gameCollection = GameCollection.gameSystemCollectionForPathExtension(pathExtension, inManagedObjectContext: managedObjectContext)
game.type = GameType(rawValue: gameCollection.identifier)
game.gameCollections.insert(gameCollection)
}
else
{
game.type = GameType.delta
}
let gameCollection = GameCollection.gameSystemCollectionForPathExtension(URL.pathExtension, inManagedObjectContext: managedObjectContext)
game.type = GameType(rawValue: gameCollection.identifier)
game.gameCollections.insert(gameCollection)
do
{
let destinationURL = try! DatabaseManager.gamesDirectoryURL.appendingPathComponent(game.identifier + "." + game.preferredFileExtension)
let destinationURL = DatabaseManager.gamesDirectoryURL.appendingPathComponent(game.identifier + "." + game.preferredFileExtension)
if let path = destinationURL.path
if FileManager.default.fileExists(atPath: destinationURL.path)
{
if FileManager.default.fileExists(atPath: path)
{
try FileManager.default.removeItem(at: URL)
}
else
{
try FileManager.default.moveItem(at: URL, to: destinationURL)
}
try FileManager.default.removeItem(at: URL)
}
else
{
try FileManager.default.moveItem(at: URL, to: destinationURL)
}
identifiers.append(game.identifier)
@ -194,14 +180,14 @@ extension DatabaseManager
if UIDevice.current.userInterfaceIdiom == .tv
{
documentsDirectoryURL = FileManager.default.urlsForDirectory(FileManager.SearchPathDirectory.cachesDirectory, inDomains: FileManager.SearchPathDomainMask.userDomainMask).first!
documentsDirectoryURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
}
else
{
documentsDirectoryURL = FileManager.default.urlsForDirectory(FileManager.SearchPathDirectory.documentDirectory, inDomains: FileManager.SearchPathDomainMask.userDomainMask).first!
documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
}
let databaseDirectoryURL = try! documentsDirectoryURL.appendingPathComponent("Database")
let databaseDirectoryURL = documentsDirectoryURL.appendingPathComponent("Database")
self.createDirectoryAtURLIfNeeded(databaseDirectoryURL)
return databaseDirectoryURL
@ -209,7 +195,7 @@ extension DatabaseManager
class var gamesDirectoryURL: URL
{
let gamesDirectoryURL = try! DatabaseManager.databaseDirectoryURL.appendingPathComponent("Games")
let gamesDirectoryURL = DatabaseManager.databaseDirectoryURL.appendingPathComponent("Games")
self.createDirectoryAtURLIfNeeded(gamesDirectoryURL)
return gamesDirectoryURL
@ -217,7 +203,7 @@ extension DatabaseManager
class var saveStatesDirectoryURL: URL
{
let saveStatesDirectoryURL = try! DatabaseManager.databaseDirectoryURL.appendingPathComponent("Save States")
let saveStatesDirectoryURL = DatabaseManager.databaseDirectoryURL.appendingPathComponent("Save States")
self.createDirectoryAtURLIfNeeded(saveStatesDirectoryURL)
return saveStatesDirectoryURL
@ -225,7 +211,7 @@ extension DatabaseManager
class func saveStatesDirectoryURLForGame(_ game: Game) -> URL
{
let gameDirectoryURL = try! DatabaseManager.saveStatesDirectoryURL.appendingPathComponent(game.identifier)
let gameDirectoryURL = DatabaseManager.saveStatesDirectoryURL.appendingPathComponent(game.identifier)
self.createDirectoryAtURLIfNeeded(gameDirectoryURL)
return gameDirectoryURL
@ -322,7 +308,7 @@ private extension DatabaseManager
}
// Remove empty collections
let collections = GameCollection.instancesWithPredicate(Predicate(format: "%K.@count == 0", GameCollection.Attributes.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

@ -46,7 +46,7 @@ class Game: NSManagedObject, GameProtocol
var fileURL: URL!
self.managedObjectContext?.performAndWait {
fileURL = try! DatabaseManager.gamesDirectoryURL.appendingPathComponent(self.filename)
fileURL = DatabaseManager.gamesDirectoryURL.appendingPathComponent(self.filename)
}
return fileURL

View File

@ -76,7 +76,7 @@ class GameCollection: NSManagedObject
index = Int16(INT16_MAX)
}
let predicate = Predicate(format: "%K == %@", GameCollection.Attributes.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

@ -55,13 +55,13 @@ class SaveState: NSManagedObject, SaveStateProtocol
@NSManaged var previewGame: Game?
var fileURL: URL {
let fileURL = try! DatabaseManager.saveStatesDirectoryURLForGame(self.game).appendingPathComponent(self.filename)
let fileURL = DatabaseManager.saveStatesDirectoryURLForGame(self.game).appendingPathComponent(self.filename)
return fileURL
}
var imageFileURL: URL {
let imageFilename = (self.filename as NSString).deletingPathExtension + ".png"
let imageFileURL = try! DatabaseManager.saveStatesDirectoryURLForGame(self.game).appendingPathComponent(imageFilename)
let imageFileURL = DatabaseManager.saveStatesDirectoryURLForGame(self.game).appendingPathComponent(imageFilename)
return imageFileURL
}

View File

@ -39,7 +39,7 @@ extension NSManagedObject
return self.instancesWithPredicate(nil, inManagedObjectContext: managedObjectContext, type: type)
}
class func instancesWithPredicate<T: NSManagedObject>(_ predicate: Predicate?, inManagedObjectContext managedObjectContext: NSManagedObjectContext, type: T.Type) -> [T]
class func instancesWithPredicate<T: NSManagedObject>(_ predicate: NSPredicate?, inManagedObjectContext managedObjectContext: NSManagedObjectContext, type: T.Type) -> [T]
{
let fetchRequest = self.rst_fetchRequest()
fetchRequest.predicate = predicate

View File

@ -53,7 +53,7 @@ class GamePickerController: NSObject
let importAction = UIAlertAction(title: NSLocalizedString("Import", comment: ""), style: .default) { action in
let documentsDirectoryURL = try! DatabaseManager.databaseDirectoryURL.deletingLastPathComponent()
let documentsDirectoryURL = DatabaseManager.databaseDirectoryURL.deletingLastPathComponent()
do
{
@ -91,7 +91,7 @@ class GamePickerController: NSObject
DatabaseManager.sharedManager.managedObjectContext.perform() {
let predicate = Predicate(format: "%K IN (%@)", Game.Attributes.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

@ -48,6 +48,26 @@ class GameViewController: DeltaCore.GameViewController
private var sustainButtonsBlurView: UIVisualEffectView!
private var sustainButtonsBackgroundView: RSTBackgroundView!
override var previewActionItems: [UIPreviewActionItem]
{
if let previewActionItems = self.overridePreviewActionItems
{
return previewActionItems
}
guard let game = self.game as? Game else { return [] }
let presentingViewController = self.presentingViewController
let launchGameAction = UIPreviewAction(title: NSLocalizedString("Launch \(game.name)", comment: ""), style: .default) { (action, viewController) in
// Delaying until next run loop prevents self from being dismissed immediately
DispatchQueue.main.async {
presentingViewController?.present(viewController, animated: true, completion: nil)
}
}
return [launchGameAction]
}
required init()
{
self.reactivateSustainedInputsQueue = OperationQueue()
@ -86,7 +106,7 @@ class GameViewController: DeltaCore.GameViewController
{
super.gameController(gameController, didActivate: input)
if gameController is ControllerView && UIDevice.current().isVibrationSupported
if gameController is ControllerView && UIDevice.current.isVibrationSupported
{
UIDevice.current.vibrate()
}
@ -97,7 +117,7 @@ class GameViewController: DeltaCore.GameViewController
{
self.addSustainedInput(input, for: gameController)
}
else if let sustainedInputs = self.sustainedInputs[ObjectIdentifier(gameController)], sustainedInputs.contains({ $0.isEqual(input) })
else if let sustainedInputs = self.sustainedInputs[ObjectIdentifier(gameController)], sustainedInputs.contains(where: { $0.isEqual(input) })
{
// Perform on next run loop
DispatchQueue.main.async {
@ -157,26 +177,6 @@ extension GameViewController
self.controllerView.isHidden = self.isPreviewing
}
override func previewActionItems() -> [UIPreviewActionItem]
{
if let previewActionItems = self.overridePreviewActionItems
{
return previewActionItems
}
guard let game = self.game as? Game else { return [] }
let presentingViewController = self.presentingViewController
let launchGameAction = UIPreviewAction(title: NSLocalizedString("Launch \(game.name)", comment: ""), style: .default) { (action, viewController) in
// Delaying until next run loop prevents self from being dismissed immediately
DispatchQueue.main.async {
presentingViewController?.present(viewController, animated: true, completion: nil)
}
}
return [launchGameAction]
}
// MARK: - Segues
/// KVO
@ -228,7 +228,8 @@ extension GameViewController
self.emulatorCore?.audioManager.enabled = false
// Re-enable after delay
DispatchQueue.main.after(when: .now() + 0.1) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.emulatorCore?.audioManager.enabled = true
}
}
@ -292,14 +293,12 @@ extension GameViewController: SaveStatesViewControllerDelegate
{
func saveStatesViewController(_ saveStatesViewController: SaveStatesViewController, updateSaveState saveState: SaveState)
{
guard let filepath = saveState.fileURL.path else { return }
var updatingExistingSaveState = true
self.emulatorCore?.save { (temporarySaveState) in
do
{
if FileManager.default.fileExists(atPath: filepath)
if FileManager.default.fileExists(atPath: saveState.fileURL.path)
{
try FileManager.default.replaceItem(at: saveState.fileURL, withItemAt: temporarySaveState.fileURL, backupItemName: nil, options: [], resultingItemURL: nil)
}
@ -407,7 +406,7 @@ extension GameViewController: CheatsViewControllerDelegate
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
backgroundContext.performAndWait {
let predicate = Predicate(format: "%K == %@", Cheat.Attributes.game.rawValue, game)
let predicate = NSPredicate(format: "%K == %@", Cheat.Attributes.game.rawValue, game)
let cheats = Cheat.instancesWithPredicate(predicate, inManagedObjectContext: backgroundContext, type: Cheat.self)
for cheat in cheats
@ -488,7 +487,7 @@ private extension GameViewController
{
var inputs = self.sustainedInputs[ObjectIdentifier(gameController)] ?? []
guard !inputs.contains({ $0.isEqual(input) }) else { return }
guard !inputs.contains(where: { $0.isEqual(input) }) else { return }
inputs.append(input)
self.sustainedInputs[ObjectIdentifier(gameController)] = inputs
@ -514,7 +513,7 @@ private extension GameViewController
// Must deactivate first so core recognizes a secondary activation
gameController.deactivate(input)
let dispatchQueue = DispatchQueue(label: "com.rileytestut.Delta.sustainButtonsQueue", attributes: DispatchQueueAttributes.serial)
let dispatchQueue = DispatchQueue(label: "com.rileytestut.Delta.sustainButtonsQueue")
dispatchQueue.async {
let semaphore = DispatchSemaphore(value: 0)

View File

@ -18,7 +18,7 @@ internal extension UILabel
context.minimumScaleFactor = self.minimumScaleFactor
// Using self.attributedString returns incorrect calculations, so we create our own attributed string
let attributedString = AttributedString(string: text, attributes: [NSFontAttributeName: self.font])
let attributedString = NSAttributedString(string: text, attributes: [NSFontAttributeName: self.font])
attributedString.boundingRect(with: self.bounds.size, options: [.usesLineFragmentOrigin, .usesFontLeading], context: context)
let scaleFactor = context.actualScaleFactor

View File

@ -28,7 +28,7 @@ class GamesViewController: UIViewController
required init?(coder aDecoder: NSCoder)
{
let fetchRequest = GameCollection.rst_fetchRequest()
fetchRequest.sortDescriptors = [SortDescriptor(key: GameCollection.Attributes.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

@ -23,7 +23,7 @@ class CheatTextView: UITextView
}
}
@NSCopying private var attributedFormat: AttributedString?
@NSCopying private var attributedFormat: NSAttributedString?
required init?(coder aDecoder: NSCoder)
{
@ -117,9 +117,9 @@ extension CheatTextView: NSLayoutManagerDelegate
let bufferSize = max(attributedFormat.length + 1, glyphCount * 2)
// Allocate our replacement buffers
let glyphBuffer = UnsafeMutablePointer<CGGlyph>(allocatingCapacity: bufferSize)
let propertyBuffer = UnsafeMutablePointer<NSGlyphProperty>(allocatingCapacity: bufferSize)
let characterBuffer = UnsafeMutablePointer<Int>(allocatingCapacity: bufferSize)
let glyphBuffer = UnsafeMutablePointer<CGGlyph>.allocate(capacity: bufferSize)
let propertyBuffer = UnsafeMutablePointer<NSGlyphProperty>.allocate(capacity: bufferSize)
let characterBuffer = UnsafeMutablePointer<Int>.allocate(capacity: bufferSize)
var offset = 0
@ -156,9 +156,9 @@ extension CheatTextView: NSLayoutManagerDelegate
layoutManager.setGlyphs(glyphBuffer, properties: propertyBuffer, characterIndexes: characterBuffer, font: aFont, forGlyphRange: NSRange(location: glyphRange.location, length: glyphCount + offset))
// Clean up memory
characterBuffer.deallocateCapacity(bufferSize)
propertyBuffer.deallocateCapacity(bufferSize)
glyphBuffer.deallocateCapacity(bufferSize)
characterBuffer.deallocate(capacity: bufferSize)
propertyBuffer.deallocate(capacity: bufferSize)
glyphBuffer.deallocate(capacity: bufferSize)
// Return total number of glyphs
return glyphCount + offset

View File

@ -33,7 +33,7 @@ struct CheatValidator
let code = cheat.code
// Find all cheats that are for the same game, don't have the same identifier as the current cheat, but have either the same name or code
let predicate = Predicate(format: "%K == %@ AND %K != %@ AND (%K == %@ OR %K == %@)", Cheat.Attributes.game.rawValue, cheat.game, Cheat.Attributes.identifier.rawValue, cheat.identifier, Cheat.Attributes.code.rawValue, code, Cheat.Attributes.name.rawValue, name)
let predicate = NSPredicate(format: "%K == %@ AND %K != %@ AND (%K == %@ OR %K == %@)", Cheat.Attributes.game.rawValue, cheat.game, Cheat.Attributes.identifier.rawValue, cheat.identifier, Cheat.Attributes.code.rawValue, code, Cheat.Attributes.name.rawValue, name)
let cheats = Cheat.instancesWithPredicate(predicate, inManagedObjectContext: self.managedObjectContext, type: Cheat.self)
for cheat in cheats

View File

@ -86,8 +86,8 @@ private extension CheatsViewController
{
let fetchRequest = Cheat.rst_fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = Predicate(format: "%K == %@", Cheat.Attributes.game.rawValue, self.game)
fetchRequest.sortDescriptors = [SortDescriptor(key: Cheat.Attributes.name.rawValue, ascending: true)]
fetchRequest.predicate = NSPredicate(format: "%K == %@", Cheat.Attributes.game.rawValue, self.game)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: Cheat.Attributes.name.rawValue, ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
self.fetchedResultsController.delegate = self

View File

@ -54,6 +54,43 @@ class EditCheatViewController: UITableViewController
@IBOutlet private var nameTextField: UITextField!
@IBOutlet private var typeSegmentedControl: UISegmentedControl!
@IBOutlet private var codeTextView: CheatTextView!
override var previewActionItems: [UIPreviewActionItem]
{
guard let cheat = self.cheat else { return [] }
let copyCodeAction = UIPreviewAction(title: NSLocalizedString("Copy Code", comment: ""), style: .default) { (action, viewController) in
UIPasteboard.general.string = cheat.code
}
let presentingViewController = self.presentingViewController!
let editCheatAction = UIPreviewAction(title: NSLocalizedString("Edit", comment: ""), style: .default) { (action, viewController) in
// Delaying until next run loop prevents self from being dismissed immediately
DispatchQueue.main.async {
let editCheatViewController = viewController as! EditCheatViewController
editCheatViewController.presentWithPresentingViewController(presentingViewController)
}
}
let deleteAction = UIPreviewAction(title: NSLocalizedString("Delete", comment: ""), style: .destructive) { [unowned self] (action, viewController) in
self.delegate?.editCheatViewController(self, deactivateCheat: cheat)
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
backgroundContext.perform {
let temporaryCheat = backgroundContext.object(with: cheat.objectID)
backgroundContext.delete(temporaryCheat)
backgroundContext.saveWithErrorLogging()
}
}
let cancelDeleteAction = UIPreviewAction(title: NSLocalizedString("Cancel", comment: ""), style: .default) { (action, viewController) in
}
let deleteActionGroup = UIPreviewActionGroup(title: NSLocalizedString("Delete", comment: ""), style: .destructive, actions: [deleteAction, cancelDeleteAction])
return [copyCodeAction, editCheatAction, deleteActionGroup]
}
}
extension EditCheatViewController
@ -155,43 +192,6 @@ extension EditCheatViewController
}
}
override func previewActionItems() -> [UIPreviewActionItem]
{
guard let cheat = self.cheat else { return [] }
let copyCodeAction = UIPreviewAction(title: NSLocalizedString("Copy Code", comment: ""), style: .default) { (action, viewController) in
UIPasteboard.general.string = cheat.code
}
let presentingViewController = self.presentingViewController!
let editCheatAction = UIPreviewAction(title: NSLocalizedString("Edit", comment: ""), style: .default) { (action, viewController) in
// Delaying until next run loop prevents self from being dismissed immediately
DispatchQueue.main.async {
let editCheatViewController = viewController as! EditCheatViewController
editCheatViewController.presentWithPresentingViewController(presentingViewController)
}
}
let deleteAction = UIPreviewAction(title: NSLocalizedString("Delete", comment: ""), style: .destructive) { [unowned self] (action, viewController) in
self.delegate?.editCheatViewController(self, deactivateCheat: cheat)
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
backgroundContext.perform {
let temporaryCheat = backgroundContext.object(with: cheat.objectID)
backgroundContext.delete(temporaryCheat)
backgroundContext.saveWithErrorLogging()
}
}
let cancelDeleteAction = UIPreviewAction(title: NSLocalizedString("Cancel", comment: ""), style: .default) { (action, viewController) in
}
let deleteActionGroup = UIPreviewActionGroup(title: NSLocalizedString("Delete", comment: ""), style: .destructive, actions: [deleteAction, cancelDeleteAction])
return [copyCodeAction, editCheatAction, deleteActionGroup]
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
@ -380,7 +380,7 @@ extension EditCheatViewController: UITextViewDelegate
// We need to manually add back the attributes when manually modifying the underlying text storage
// Otherwise, pasting text into an empty text view will result in the wrong font being used
let attributedString = AttributedString(string: sanitizedText, attributes: textView.typingAttributes)
let attributedString = NSAttributedString(string: sanitizedText, attributes: textView.typingAttributes)
textView.textStorage.replaceCharacters(in: range, with: attributedString)
// We must add attributedString.length, not range.length, in case the attributed string's length differs

View File

@ -60,15 +60,14 @@ class PauseViewController: UIViewController, PauseInfoProviding
override var navigationController: UINavigationController? {
return self.pauseNavigationController
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
extension PauseViewController
{
override func preferredStatusBarStyle() -> UIStatusBarStyle
{
return .lightContent
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()

View File

@ -25,17 +25,7 @@ class PausePresentationController: UIPresentationController
@IBOutlet private weak var pauseIconImageView: UIImageView!
@IBOutlet private weak var stackView: UIStackView!
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?)
{
self.blurringView = UIVisualEffectView(effect: nil)
self.vibrancyView = UIVisualEffectView(effect: nil)
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
self.contentView = Bundle.main.loadNibNamed("PausePresentationControllerContentView", owner: self, options: nil)?.first as! UIView
}
override func frameOfPresentedViewInContainerView() -> CGRect
override var frameOfPresentedViewInContainerView: CGRect
{
guard let containerView = self.containerView else { return super.frameOfPresentedViewInContainerView }
@ -55,6 +45,16 @@ class PausePresentationController: UIPresentationController
return frame
}
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?)
{
self.blurringView = UIVisualEffectView(effect: nil)
self.vibrancyView = UIVisualEffectView(effect: nil)
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
self.contentView = Bundle.main.loadNibNamed("PausePresentationControllerContentView", owner: self, options: nil)?.first as! UIView
}
override func presentationTransitionWillBegin()
{
if let provider = self.presentedViewController as? PauseInfoProviding
@ -164,13 +164,13 @@ class PausePresentationController: UIPresentationController
if self.presentingViewController.transitionCoordinator == nil
{
self.presentedView?.frame = self.frameOfPresentedViewInContainerView()
self.presentedView?.frame = self.frameOfPresentedViewInContainerView
}
// Unhide pauseIconImageView so its height is involved with layout calculations
self.pauseIconImageView.isHidden = false
self.contentView.frame = CGRect(x: 0, y: statusBarHeight, width: self.containerView!.bounds.width, height: self.frameOfPresentedViewInContainerView().minY - statusBarHeight)
self.contentView.frame = CGRect(x: 0, y: statusBarHeight, width: self.containerView!.bounds.width, height: self.frameOfPresentedViewInContainerView.minY - statusBarHeight)
self.contentView.setNeedsLayout() // Ensures that layout will actually occur (sometimes the system thinks a layout is not needed, which messes up calculations)
self.contentView.layoutIfNeeded()

View File

@ -58,7 +58,7 @@ class SaveStatesViewController: UICollectionViewController
private var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!
private let imageOperationQueue = RSTOperationQueue()
private let imageCache = Cache<URL, UIImage>()
private let imageCache = NSCache<NSURL, UIImage>()
private var emulatorCoreSaveState: SaveStateProtocol?
private var selectedSaveState: SaveState?
@ -160,8 +160,8 @@ private extension SaveStatesViewController
{
let fetchRequest = SaveState.rst_fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = Predicate(format: "%K == %@", SaveState.Attributes.game.rawValue, self.game)
fetchRequest.sortDescriptors = [SortDescriptor(key: SaveState.Attributes.type.rawValue, ascending: true), SortDescriptor(key: SaveState.Attributes.creationDate.rawValue, ascending: true)]
fetchRequest.predicate = NSPredicate(format: "%K == %@", SaveState.Attributes.game.rawValue, self.game)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: SaveState.Attributes.type.rawValue, ascending: true), NSSortDescriptor(key: SaveState.Attributes.creationDate.rawValue, ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: SaveState.Attributes.type.rawValue, cacheName: nil)
self.fetchedResultsController.delegate = self

View File

@ -73,7 +73,7 @@ extension PauseStoryboardSegue: UIViewControllerAnimatedTransitioning
transitionContext.containerView.addSubview(presentedView)
self.animator.addAnimations { [unowned self] in
presentedView.frame = self.presentationController.frameOfPresentedViewInContainerView()
presentedView.frame = self.presentationController.frameOfPresentedViewInContainerView
}
self.animator.addCompletion { position in

View File

@ -39,7 +39,7 @@ class ControllersSettingsViewController: UITableViewController
}
}
private var connectedControllers = ExternalControllerManager.shared.connectedControllers.sorted(isOrderedBefore: { $0.playerIndex ?? NSIntegerMax < $1.playerIndex ?? NSIntegerMax })
private var connectedControllers = ExternalControllerManager.shared.connectedControllers.sorted(by: { $0.playerIndex ?? NSIntegerMax < $1.playerIndex ?? NSIntegerMax })
private lazy var localDeviceController: LocalDeviceController = {
let device = LocalDeviceController()
@ -176,7 +176,7 @@ extension ControllersSettingsViewController
{
cell.textLabel?.text = NSLocalizedString("None", comment: "")
if Settings.localControllerPlayerIndex != self.playerIndex && !self.connectedControllers.contains({ $0.playerIndex == self.playerIndex })
if Settings.localControllerPlayerIndex != self.playerIndex && !self.connectedControllers.contains(where: { $0.playerIndex == self.playerIndex })
{
cell.accessoryType = .checkmark
}