From 72ab6507ea459a35e4fa18dd6fc93ab903cd4893 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 14 Mar 2019 07:56:48 -0700 Subject: [PATCH] fix crash when presenting alerts on iOS9 --- Signal.xcodeproj/project.pbxproj | 4 ++ Signal/src/UIAlerts+iOS9.m | 85 ++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 Signal/src/UIAlerts+iOS9.m diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index aadd52a2a..5ec0b33aa 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -462,6 +462,7 @@ 4C1885D2218F8E1C00B67051 /* PhotoGridViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1885D1218F8E1C00B67051 /* PhotoGridViewCell.swift */; }; 4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; }; 4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */; }; + 4C21D5D6223A9DC500EF8A77 /* UIAlerts+iOS9.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C21D5D5223A9DC500EF8A77 /* UIAlerts+iOS9.m */; }; 4C23A5F2215C4ADE00534937 /* SheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C23A5F1215C4ADE00534937 /* SheetViewController.swift */; }; 4C2F454F214C00E1004871FF /* AvatarTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C2F454E214C00E1004871FF /* AvatarTableViewCell.swift */; }; 4C3E245C21F29FCE000AE092 /* Toast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA5F792211E1F06008C2708 /* Toast.swift */; }; @@ -1196,6 +1197,7 @@ 4C1D233A218B6CDB00A0598F /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = translations/th.lproj/Localizable.strings; sourceTree = ""; }; 4C1D233B218B6D3100A0598F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = translations/tr.lproj/Localizable.strings; sourceTree = ""; }; 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearchViewController.swift; sourceTree = ""; }; + 4C21D5D5223A9DC500EF8A77 /* UIAlerts+iOS9.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIAlerts+iOS9.m"; sourceTree = ""; }; 4C23A5F1215C4ADE00534937 /* SheetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetViewController.swift; sourceTree = ""; }; 4C2F454E214C00E1004871FF /* AvatarTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarTableViewCell.swift; sourceTree = ""; }; 4C3EF7FC2107DDEE0007EBF7 /* ParamParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParamParserTest.swift; sourceTree = ""; }; @@ -2614,6 +2616,7 @@ FCFA64B11A24F29E0007FB87 /* UI Categories */ = { isa = PBXGroup; children = ( + 4C21D5D5223A9DC500EF8A77 /* UIAlerts+iOS9.m */, 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */, 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */, EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */, @@ -3613,6 +3616,7 @@ 34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */, 457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */, 34A6C28021E503E700B5B12E /* OWSImagePickerController.swift in Sources */, + 4C21D5D6223A9DC500EF8A77 /* UIAlerts+iOS9.m in Sources */, 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */, 3496957021A301A100DCFE74 /* OWSBackupIO.m in Sources */, 34E88D262098C5AE00A608F4 /* ContactViewController.swift in Sources */, diff --git a/Signal/src/UIAlerts+iOS9.m b/Signal/src/UIAlerts+iOS9.m new file mode 100644 index 000000000..bd2fa7ced --- /dev/null +++ b/Signal/src/UIAlerts+iOS9.m @@ -0,0 +1,85 @@ +// +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. +// + +#import + +@implementation UIAlertController (iOS9) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // On iOS9, avoids an exception when presenting an alert controller. + // + // *** Assertion failure in -[UIAlertController supportedInterfaceOrientations], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.30.14/UIAlertController.m:542 + // Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIAlertController:supportedInterfaceOrientations was invoked recursively!' + // + // I'm not sure when this was introduced, or the exact root casue, but this quick workaround + // seems reasonable given the small size of our iOS9 userbase. + if (@available(iOS 10, *)) { + return; + } + + Class class = [self class]; + + // supportedInterfaceOrientation + + SEL originalOrientationSelector = @selector(supportedInterfaceOrientations); + SEL swizzledOrientationSelector = @selector(ows_iOS9Alerts_swizzle_supportedInterfaceOrientation); + + Method originalOrientationMethod = class_getInstanceMethod(class, originalOrientationSelector); + Method swizzledOrientationMethod = class_getInstanceMethod(class, swizzledOrientationSelector); + + BOOL didAddOrientationMethod = class_addMethod(class, + originalOrientationSelector, + method_getImplementation(swizzledOrientationMethod), + method_getTypeEncoding(swizzledOrientationMethod)); + + if (didAddOrientationMethod) { + class_replaceMethod(class, + swizzledOrientationSelector, + method_getImplementation(originalOrientationMethod), + method_getTypeEncoding(originalOrientationMethod)); + } else { + method_exchangeImplementations(originalOrientationMethod, swizzledOrientationMethod); + } + + // shouldAutorotate + + SEL originalAutorotateSelector = @selector(shouldAutorotate); + SEL swizzledAutorotateSelector = @selector(ows_iOS9Alerts_swizzle_shouldAutorotate); + + Method originalAutorotateMethod = class_getInstanceMethod(class, originalAutorotateSelector); + Method swizzledAutorotateMethod = class_getInstanceMethod(class, swizzledAutorotateSelector); + + BOOL didAddAutorotateMethod = class_addMethod(class, + originalAutorotateSelector, + method_getImplementation(swizzledAutorotateMethod), + method_getTypeEncoding(swizzledAutorotateMethod)); + + if (didAddAutorotateMethod) { + class_replaceMethod(class, + swizzledAutorotateSelector, + method_getImplementation(originalAutorotateMethod), + method_getTypeEncoding(originalAutorotateMethod)); + } else { + method_exchangeImplementations(originalAutorotateMethod, swizzledAutorotateMethod); + } + }); +} + +#pragma mark - Method Swizzling + +- (UIInterfaceOrientationMask)ows_iOS9Alerts_swizzle_supportedInterfaceOrientation +{ + OWSLogInfo(@"swizzled"); + return UIInterfaceOrientationMaskAllButUpsideDown; +} + +- (BOOL)ows_iOS9Alerts_swizzle_shouldAutorotate +{ + OWSLogInfo(@"swizzled"); + return NO; +} + +@end