From aae7b67945b93eee3262b36031c76f7c02b4e331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20A=2E=20A=CC=81lvarez?= Date: Thu, 26 May 2016 23:23:49 +0200 Subject: [PATCH] iOS 7 compatibility (disables some animations and disk image creation/renaming) --- Mini vMac.xcodeproj/project.pbxproj | 11 +++- Mini vMac/AppDelegate.m | 15 +++-- Mini vMac/Info.plist | 94 ++++++++++++++-------------- Mini vMac/InsertDiskViewController.m | 39 +++++++----- Mini vMac/KBKeyboardView.m | 2 +- Mini vMac/MYOSGLUE.m | 20 +++--- Mini vMac/compat.m | 54 ++++++++++++++++ README.md | 2 +- 8 files changed, 160 insertions(+), 77 deletions(-) create mode 100644 Mini vMac/compat.m diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index 56f2567..988fa97 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ 28F6B4C11CF07F5C002D76D0 /* liblibmfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28F6B4A81CF07EC9002D76D0 /* liblibmfs.a */; }; 28F6B4C21CF07F5C002D76D0 /* liblibres.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28F6B4B61CF07F32002D76D0 /* liblibres.a */; }; 28F6B4CA1CF1FA7A002D76D0 /* about.plist in Resources */ = {isa = PBXBuildFile; fileRef = 28F6B4C91CF1FA7A002D76D0 /* about.plist */; }; + 28F6B4CF1CF77099002D76D0 /* compat.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F6B4CE1CF77099002D76D0 /* compat.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -206,6 +207,7 @@ 28F6B4A81CF07EC9002D76D0 /* liblibmfs.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblibmfs.a; sourceTree = BUILT_PRODUCTS_DIR; }; 28F6B4B61CF07F32002D76D0 /* liblibres.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblibres.a; sourceTree = BUILT_PRODUCTS_DIR; }; 28F6B4C91CF1FA7A002D76D0 /* about.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = about.plist; sourceTree = ""; }; + 28F6B4CE1CF77099002D76D0 /* compat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = compat.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -362,6 +364,7 @@ 28F6B4501CF07C48002D76D0 /* UIImage+DiskImageIcon.h */, 28F6B4511CF07C48002D76D0 /* UIImage+DiskImageIcon.m */, 28F6B4C91CF1FA7A002D76D0 /* about.plist */, + 28F6B4CE1CF77099002D76D0 /* compat.m */, ); path = "Mini vMac"; sourceTree = ""; @@ -455,6 +458,7 @@ 28F676B91CD15E0B00FC6FA6 /* Sources */, 28F676BA1CD15E0B00FC6FA6 /* Frameworks */, 28F676BB1CD15E0B00FC6FA6 /* Resources */, + 28F6B4CD1CF76D88002D76D0 /* ShellScript */, ); buildRules = ( ); @@ -612,6 +616,7 @@ 28CE8EB81CD4C3B200FE25A8 /* M68KITAB.c in Sources */, 28848B651CDE97E900B86C45 /* SettingsViewController.m in Sources */, 28BA89881CE73FBC00A98104 /* MNVMApplication.m in Sources */, + 28F6B4CF1CF77099002D76D0 /* compat.m in Sources */, 28F6B4521CF07C48002D76D0 /* UIImage+DiskImageIcon.m in Sources */, 28CE8EB71CD4C3B200FE25A8 /* KBRDEMDV.c in Sources */, 28CE8EBC1CD4C3B200FE25A8 /* ROMEMDEV.c in Sources */, @@ -724,7 +729,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -763,7 +768,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -779,6 +784,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; HEADER_SEARCH_PATHS = "$(SRCROOT)"; INFOPLIST_FILE = "Mini vMac/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_CFLAGS = "-DUSE_LIBRES"; PRODUCT_BUNDLE_IDENTIFIER = net.namedfork.minivmac; @@ -795,6 +801,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; HEADER_SEARCH_PATHS = "$(SRCROOT)"; INFOPLIST_FILE = "Mini vMac/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_CFLAGS = "-DUSE_LIBRES"; PRODUCT_BUNDLE_IDENTIFIER = net.namedfork.minivmac; diff --git a/Mini vMac/AppDelegate.m b/Mini vMac/AppDelegate.m index 1477c1d..55a6686 100644 --- a/Mini vMac/AppDelegate.m +++ b/Mini vMac/AppDelegate.m @@ -90,10 +90,15 @@ NSString * const MNVMDidEjectDiskNotification = @"MNVMDidEjectDisk"; }); return; } - UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; - UIViewController *controller = self.window.rootViewController; - [controller presentViewController:alert animated:YES completion:nil]; + if ([UIAlertController class]) { + UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; + UIViewController *controller = self.window.rootViewController; + [controller presentViewController:alert animated:YES completion:nil]; + } else { + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alertView show]; + } } #pragma mark - Settings / Insert Disk panels @@ -150,7 +155,7 @@ NSString * const MNVMDidEjectDiskNotification = @"MNVMDidEjectDisk"; UIViewController *viewController = [rootViewController.storyboard instantiateViewControllerWithIdentifier:name]; viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; viewController.modalPresentationStyle = UIModalPresentationFormSheet; - if ([sender isKindOfClass:[UISwipeGestureRecognizer class]]) { + if ([sender isKindOfClass:[UISwipeGestureRecognizer class]] && [UIDevice currentDevice].systemVersion.integerValue >= 8) { modalPanePresentationDirection = [(UISwipeGestureRecognizer*)sender direction]; viewController.transitioningDelegate = self; } diff --git a/Mini vMac/Info.plist b/Mini vMac/Info.plist index 1196904..05c8a60 100644 --- a/Mini vMac/Info.plist +++ b/Mini vMac/Info.plist @@ -4,6 +4,51 @@ CFBundleDevelopmentRegion en + CFBundleDocumentTypes + + + CFBundleTypeIconFiles + + CFBundleTypeName + Disk Image + CFBundleTypeRole + Editor + LSHandlerRank + Owner + LSItemContentTypes + + com.apple.disk-image + + + + CFBundleTypeIconFiles + + CFBundleTypeName + Disk Copy 4.2 Disk Image + CFBundleTypeRole + Editor + LSHandlerRank + Owner + LSItemContentTypes + + com.apple.disk-image-dc42 + + + + CFBundleTypeIconFiles + + CFBundleTypeName + ROM image + CFBundleTypeRole + Editor + LSHandlerRank + Owner + LSItemContentTypes + + net.namedfork.minivmac.rom + + + CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -15,11 +60,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion - 1 + 2 LSRequiresIPhoneOS UIFileSharingEnabled @@ -114,50 +159,5 @@ - CFBundleDocumentTypes - - - CFBundleTypeIconFiles - - CFBundleTypeName - Disk Image - CFBundleTypeRole - Editor - LSHandlerRank - Owner - LSItemContentTypes - - com.apple.disk-image - - - - CFBundleTypeIconFiles - - CFBundleTypeName - Disk Copy 4.2 Disk Image - CFBundleTypeRole - Editor - LSHandlerRank - Owner - LSItemContentTypes - - com.apple.disk-image-dc42 - - - - CFBundleTypeIconFiles - - CFBundleTypeName - ROM image - CFBundleTypeRole - Editor - LSHandlerRank - Owner - LSItemContentTypes - - net.namedfork.minivmac.rom - - - diff --git a/Mini vMac/InsertDiskViewController.m b/Mini vMac/InsertDiskViewController.m index 9d00bca..498cdc2 100644 --- a/Mini vMac/InsertDiskViewController.m +++ b/Mini vMac/InsertDiskViewController.m @@ -104,7 +104,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { switch (section) { - case 0: return diskImages.count + (self.editing ? 1 : 0); + case 0: return diskImages.count + (self.editing && [UIAlertController class] ? 1 : 0); case 1: return otherFiles.count; default: return 0; } @@ -188,7 +188,12 @@ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { - [self askDeleteFile:[self fileAtIndexPath:indexPath]]; + NSString *filePath = [self fileAtIndexPath:indexPath]; + if ([UIAlertController class]) { + [self askDeleteFile:filePath]; + } else { + [self deleteFile:filePath]; + } } else if (editingStyle == UITableViewCellEditingStyleInsert) { [self createDiskImage]; } @@ -199,7 +204,7 @@ } - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - return (action == @selector(share:) || action == @selector(rename:) || action == @selector(delete:)); + return (action == @selector(share:) || ([UIAlertController class] && (action == @selector(rename:) || action == @selector(delete:)))); } - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { @@ -217,19 +222,23 @@ #pragma mark - File Actions +- (void)deleteFile:(NSString*)filePath { + NSError *error = nil; + if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]) { + NSIndexPath *indexPath = [self indexPathForFile:filePath]; + [self loadDirectoryContents]; + [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else { + [[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not delete file", nil) message:error.localizedDescription]; + } +} + - (void)askDeleteFile:(NSString*)filePath { NSString *fileName = filePath.lastPathComponent; NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete %@? This operation cannot be undone.", nil), fileName]; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Delete File", nil) message:message preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Delete", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { - NSError *error = nil; - if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]) { - NSIndexPath *indexPath = [self indexPathForFile:filePath]; - [self loadDirectoryContents]; - [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; - } else { - [[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not delete file", nil) message:error.localizedDescription]; - } + [self deleteFile:filePath]; }]]; [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alertController animated:YES completion:nil]; @@ -451,9 +460,11 @@ - (void)share:(id)sender { UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL fileURLWithPath:self.filePath]] applicationActivities:nil]; - avc.modalPresentationStyle = UIModalPresentationPopover; - avc.popoverPresentationController.sourceView = self.imageView; - avc.popoverPresentationController.sourceRect = self.imageView.bounds; + if ([avc respondsToSelector:@selector(popoverPresentationController)]) { + avc.modalPresentationStyle = UIModalPresentationPopover; + avc.popoverPresentationController.sourceView = self.imageView; + avc.popoverPresentationController.sourceRect = self.imageView.bounds; + } [self.controller presentViewController:avc animated:YES completion:nil]; } diff --git a/Mini vMac/KBKeyboardView.m b/Mini vMac/KBKeyboardView.m index cabbf31..8a8f59e 100644 --- a/Mini vMac/KBKeyboardView.m +++ b/Mini vMac/KBKeyboardView.m @@ -122,7 +122,7 @@ fontScale *= [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? 0.6 : 0.65; } key.label = label; - key.titleLabel.font = [UIFont systemFontOfSize:fontSize * fontScale weight:UIFontWeightRegular]; + key.titleLabel.font = [UIFont systemFontOfSize:fontSize * fontScale weight:&UIFontWeightRegular ? UIFontWeightRegular : 1.0]; [keyPlane addObject:key]; }]; return keyPlane; diff --git a/Mini vMac/MYOSGLUE.m b/Mini vMac/MYOSGLUE.m index 71f64c9..7a319d9 100644 --- a/Mini vMac/MYOSGLUE.m +++ b/Mini vMac/MYOSGLUE.m @@ -1548,13 +1548,19 @@ LOCALPROC MacMsgDisplayOn() { if (SavedBriefMsg != nullpr) { NSString *title = NSStringCreateFromSubstCStr(SavedBriefMsg, falseblnr); NSString *message = NSStringCreateFromSubstCStr(SavedLongMsg, falseblnr); - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; - blnr wasStopped = CurSpeedStopped; - [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - SetSpeedStopped(wasStopped); - }]]; - SetSpeedStopped(trueblnr); - [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil]; + if ([UIAlertController class]) { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; + blnr wasStopped = CurSpeedStopped; + [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + SetSpeedStopped(wasStopped); + }]]; + SetSpeedStopped(trueblnr); + [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil]; + } else { + // fallback for iOS 7 + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alertView show]; + } SavedBriefMsg = nullpr; SavedLongMsg = nullpr; } diff --git a/Mini vMac/compat.m b/Mini vMac/compat.m new file mode 100644 index 0000000..5802901 --- /dev/null +++ b/Mini vMac/compat.m @@ -0,0 +1,54 @@ +// +// compat.m +// Mini vMac +// +// Created by Jesús A. Álvarez on 26/05/2016. +// Copyright © 2016 namedfork. All rights reserved. +// + +@import Foundation; +@import UIKit; +@import ObjectiveC.runtime; + +@implementation NSObject (Compat) + +/// Add newSelector if it doesn't exist, backed by originalSelector ++ (void)_nfCompatAddInstanceMethod:(SEL)newSelector withCompatibilityMethod:(SEL)originalSelector { + if (![self instancesRespondToSelector:newSelector]) { + Method m = class_getInstanceMethod(self, originalSelector); + class_addMethod(self, newSelector, method_getImplementation(m), method_getTypeEncoding(m)); + } +} + ++ (void)_nfCompatAddClassMethod:(SEL)newSelector withCompatibilityMethod:(SEL)originalSelector { + if (class_getClassMethod(self, newSelector) == NULL) { + Method m = class_getClassMethod(self, originalSelector); + class_addMethod(object_getClass(self), newSelector, method_getImplementation(m), method_getTypeEncoding(m)); + } +} + +@end + +@implementation NSString (Compat) + ++ (void)load { + [NSString _nfCompatAddInstanceMethod:@selector(containsString:) withCompatibilityMethod:@selector(_nfCompatContainsString:)]; +} + +- (BOOL)_nfCompatContainsString:(NSString*)string { + return [self rangeOfString:string].location != NSNotFound; +} + +@end + +@implementation UIFont (Compat) + ++ (void)load { + [UIFont _nfCompatAddClassMethod:@selector(systemFontOfSize:weight:) withCompatibilityMethod:@selector(_nfCompatSystemFontOfSize:weight:)]; +} + ++ (UIFont *)_nfCompatSystemFontOfSize:(CGFloat)fontSize weight:(CGFloat)weight { + return [self systemFontOfSize:fontSize]; +} + +@end \ No newline at end of file diff --git a/README.md b/README.md index dc5b355..50a66f1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Requirements -* iOS 9 or later +* iOS 7 or later * Mac Plus ROM image * Disk images with Mac software * A Mac with Xcode 7 (required to build)