diff --git a/SlackTextViewController/SlackTextViewController.xcodeproj/project.pbxproj b/SlackTextViewController/SlackTextViewController.xcodeproj/project.pbxproj index 7fdd7780..f4cb0e63 100644 --- a/SlackTextViewController/SlackTextViewController.xcodeproj/project.pbxproj +++ b/SlackTextViewController/SlackTextViewController.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 751FBFFA20B434480073DF8B /* UIApplication+ExtensionSafe.h in Headers */ = {isa = PBXBuildFile; fileRef = 751FBFF820B434480073DF8B /* UIApplication+ExtensionSafe.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 751FBFFB20B434480073DF8B /* UIApplication+ExtensionSafe.m in Sources */ = {isa = PBXBuildFile; fileRef = 751FBFF920B434480073DF8B /* UIApplication+ExtensionSafe.m */; }; F52253811CBE2F85002EECA9 /* SLKInputAccessoryView.h in Headers */ = {isa = PBXBuildFile; fileRef = F522536B1CBE2F85002EECA9 /* SLKInputAccessoryView.h */; settings = {ATTRIBUTES = (Public, ); }; }; F52253821CBE2F85002EECA9 /* SLKInputAccessoryView.m in Sources */ = {isa = PBXBuildFile; fileRef = F522536C1CBE2F85002EECA9 /* SLKInputAccessoryView.m */; }; F52253831CBE2F85002EECA9 /* SLKTextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = F522536D1CBE2F85002EECA9 /* SLKTextInput.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -45,6 +47,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 751FBFF820B434480073DF8B /* UIApplication+ExtensionSafe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIApplication+ExtensionSafe.h"; sourceTree = ""; }; + 751FBFF920B434480073DF8B /* UIApplication+ExtensionSafe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIApplication+ExtensionSafe.m"; sourceTree = ""; }; F522536B1CBE2F85002EECA9 /* SLKInputAccessoryView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLKInputAccessoryView.h; sourceTree = ""; }; F522536C1CBE2F85002EECA9 /* SLKInputAccessoryView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLKInputAccessoryView.m; sourceTree = ""; }; F522536D1CBE2F85002EECA9 /* SLKTextInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLKTextInput.h; sourceTree = ""; }; @@ -125,6 +129,8 @@ F5A7828F1BD0CF1D00EC230B /* Source */ = { isa = PBXGroup; children = ( + 751FBFF820B434480073DF8B /* UIApplication+ExtensionSafe.h */, + 751FBFF920B434480073DF8B /* UIApplication+ExtensionSafe.m */, F522536B1CBE2F85002EECA9 /* SLKInputAccessoryView.h */, F522536C1CBE2F85002EECA9 /* SLKInputAccessoryView.m */, F522536D1CBE2F85002EECA9 /* SLKTextInput.h */, @@ -181,6 +187,7 @@ F522538D1CBE2F85002EECA9 /* SLKTypingIndicatorProtocol.h in Headers */, F52253951CBE2F85002EECA9 /* UIView+SLKAdditions.h in Headers */, F52253851CBE2F85002EECA9 /* SLKTextInputbar.h in Headers */, + 751FBFFA20B434480073DF8B /* UIApplication+ExtensionSafe.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -287,6 +294,7 @@ F52253841CBE2F85002EECA9 /* SLKTextInput+Implementation.m in Sources */, F522538A1CBE2F85002EECA9 /* SLKTextView+SLKAdditions.m in Sources */, F52253861CBE2F85002EECA9 /* SLKTextInputbar.m in Sources */, + 751FBFFB20B434480073DF8B /* UIApplication+ExtensionSafe.m in Sources */, F52253881CBE2F85002EECA9 /* SLKTextView.m in Sources */, F52253961CBE2F85002EECA9 /* UIView+SLKAdditions.m in Sources */, F522538C1CBE2F85002EECA9 /* SLKTextViewController.m in Sources */, @@ -420,6 +428,7 @@ F5A782891BD0CEF400EC230B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -437,6 +446,7 @@ F5A7828A1BD0CEF400EC230B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/SlackTextViewController/SlackTextViewController/SlackTextViewController.h b/SlackTextViewController/SlackTextViewController/SlackTextViewController.h index 4486494b..1540fa82 100644 --- a/SlackTextViewController/SlackTextViewController/SlackTextViewController.h +++ b/SlackTextViewController/SlackTextViewController/SlackTextViewController.h @@ -18,6 +18,7 @@ FOUNDATION_EXPORT const unsigned char SlackTextViewControllerVersionString[]; #import #import +#import #import #import diff --git a/Source/SLKTextView.m b/Source/SLKTextView.m index 08a43081..70e63d49 100644 --- a/Source/SLKTextView.m +++ b/Source/SLKTextView.m @@ -193,7 +193,7 @@ - (NSUInteger)maxNumberOfLines { NSUInteger numberOfLines = _maxNumberOfLines; - if (SLK_IS_LANDSCAPE) { + if (SLKIsLandscape()) { if ((SLK_IS_IPHONE4 || SLK_IS_IPHONE5)) { numberOfLines = 2.0; // 2 lines max on smaller iPhones } @@ -203,7 +203,12 @@ - (NSUInteger)maxNumberOfLines } if (self.isDynamicTypeEnabled) { - NSString *contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory]; + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp == nil) { + return numberOfLines; + } + + NSString *contentSizeCategory = [sharedApp preferredContentSizeCategory]; CGFloat pointSizeDifference = SLKPointSizeDifferenceForCategory(contentSizeCategory); CGFloat factor = pointSizeDifference/self.initialFontSize; @@ -504,7 +509,11 @@ - (void)setAttributedText:(NSAttributedString *)attributedText - (void)setFont:(UIFont *)font { - NSString *contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory]; + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp == nil) { + return; + } + NSString *contentSizeCategory = [sharedApp preferredContentSizeCategory]; [self setFontName:font.fontName pointSize:font.pointSize withContentSizeCategory:contentSizeCategory]; @@ -533,8 +542,11 @@ - (void)setDynamicTypeEnabled:(BOOL)dynamicTypeEnabled _dynamicTypeEnabled = dynamicTypeEnabled; - NSString *contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory]; - + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp == nil) { + return; + } + NSString *contentSizeCategory = [sharedApp preferredContentSizeCategory]; [self setFontName:self.font.fontName pointSize:self.initialFontSize withContentSizeCategory:contentSizeCategory]; } diff --git a/Source/SLKTextViewController.m b/Source/SLKTextViewController.m index 60a3fc18..8aa09676 100644 --- a/Source/SLKTextViewController.m +++ b/Source/SLKTextViewController.m @@ -467,13 +467,16 @@ - (CGFloat)slk_topBarsHeight CGFloat topBarsHeight = CGRectGetHeight(self.navigationController.navigationBar.frame); - if ((SLK_IS_IPHONE && SLK_IS_LANDSCAPE && SLK_IS_IOS8_AND_HIGHER) || + if ((SLK_IS_IPHONE && SLKIsLandscape() && SLK_IS_IOS8_AND_HIGHER) || (SLK_IS_IPAD && self.modalPresentationStyle == UIModalPresentationFormSheet) || self.isPresentedInPopover) { return topBarsHeight; } - - topBarsHeight += CGRectGetHeight([UIApplication sharedApplication].statusBarFrame); + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp == nil) { + return topBarsHeight; + } + topBarsHeight += CGRectGetHeight(sharedApp.statusBarFrame); return topBarsHeight; } @@ -1170,7 +1173,7 @@ - (void)slk_postKeyboarStatusNotification:(NSNotification *)notification CGRect endFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; // Fixes iOS7 oddness with inverted values on landscape orientation - if (!SLK_IS_IOS8_AND_HIGHER && SLK_IS_LANDSCAPE) { + if (!SLK_IS_IOS8_AND_HIGHER && SLKIsLandscape()) { beginFrame = SLKRectInvert(beginFrame); endFrame = SLKRectInvert(endFrame); } diff --git a/Source/SLKUIConstants.h b/Source/SLKUIConstants.h index 9323b12a..2d6a281f 100644 --- a/Source/SLKUIConstants.h +++ b/Source/SLKUIConstants.h @@ -6,7 +6,6 @@ // Licence: MIT-Licence // -#define SLK_IS_LANDSCAPE ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeRight) #define SLK_IS_IPAD ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) #define SLK_IS_IPHONE ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) #define SLK_IS_IPHONE4 (SLK_IS_IPHONE && SLKKeyWindowBounds().size.height < 568.0) @@ -20,6 +19,7 @@ static NSString *SLKTextViewControllerDomain = @"com.slack.TextViewController"; +#import "UIApplication+ExtensionSafe.h" /** Returns a constant font size difference reflecting the current accessibility settings. @@ -43,9 +43,22 @@ __unused static CGFloat SLKPointSizeDifferenceForCategory(NSString *category) return 0; } +__unused static Boolean SLKIsLandscape() +{ + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp != nil) { + return ([sharedApp statusBarOrientation] == UIDeviceOrientationLandscapeLeft || [sharedApp statusBarOrientation] == UIDeviceOrientationLandscapeRight); + } + return false; +} + __unused static CGRect SLKKeyWindowBounds() { - return [[UIApplication sharedApplication] keyWindow].bounds; + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp != nil) { + return sharedApp.keyWindow.bounds; + } + return CGRectZero; } __unused static CGRect SLKRectInvert(CGRect rect) diff --git a/Source/UIApplication+ExtensionSafe.h b/Source/UIApplication+ExtensionSafe.h new file mode 100644 index 00000000..7e13d4ab --- /dev/null +++ b/Source/UIApplication+ExtensionSafe.h @@ -0,0 +1,15 @@ +// +// UIApplication+ExtensionSafe.h +// SlackTextViewController +// +// Created by Oskar Groth on 2018-05-22. +// Copyright © 2018 Slack Technologies, Inc. All rights reserved. +// + +#import + +@interface UIApplication (ExtensionSafe) + ++(UIApplication *)safeSharedApplication; + +@end diff --git a/Source/UIApplication+ExtensionSafe.m b/Source/UIApplication+ExtensionSafe.m new file mode 100644 index 00000000..21745f33 --- /dev/null +++ b/Source/UIApplication+ExtensionSafe.m @@ -0,0 +1,32 @@ +// +// UIApplication+ExtensionSafe.m +// SlackTextViewController +// +// Created by Oskar Groth on 2018-05-22. +// Copyright © 2018 Slack Technologies, Inc. All rights reserved. +// + +#import "UIApplication+ExtensionSafe.h" + +@implementation UIApplication (ExtensionSafe) + ++ (BOOL)isAppExtension +{ + return [[self class] safeSharedApplication] == nil; +} + ++ (UIApplication *)safeSharedApplication +{ + UIApplication *safeSharedApplication = nil; + + if ([UIApplication respondsToSelector:@selector(sharedApplication)]) { + safeSharedApplication = [UIApplication performSelector:@selector(sharedApplication)]; + } + if (!safeSharedApplication.delegate) { + safeSharedApplication = nil; + } + + return safeSharedApplication; +} + +@end diff --git a/Source/UIResponder+SLKAdditions.m b/Source/UIResponder+SLKAdditions.m index ff6ed6f8..c28ff461 100644 --- a/Source/UIResponder+SLKAdditions.m +++ b/Source/UIResponder+SLKAdditions.m @@ -7,6 +7,7 @@ // #import "UIResponder+SLKAdditions.h" +#import "UIApplication+ExtensionSafe.h" static __weak id ___currentFirstResponder; @@ -18,8 +19,10 @@ @implementation UIResponder (SLKAdditions) + (instancetype)slk_currentFirstResponder { ___currentFirstResponder = nil; - [[UIApplication sharedApplication] sendAction:@selector(slk_findFirstResponder:) to:nil from:nil forEvent:nil]; - + UIApplication *sharedApp = [UIApplication safeSharedApplication]; + if (sharedApp != nil) { + [sharedApp sendAction:@selector(slk_findFirstResponder:) to:nil from:nil forEvent:nil]; + } return ___currentFirstResponder; }