FLEXUtility.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. //
  2. // FLEXUtility.h
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 4/18/14.
  6. // Copyright (c) 2014 Flipboard. All rights reserved.
  7. //
  8. #import <Availability.h>
  9. #import <AvailabilityInternal.h>
  10. #import <Foundation/Foundation.h>
  11. #import <UIKit/UIKit.h>
  12. #import <objc/runtime.h>
  13. #import "FLEXTypeEncodingParser.h"
  14. #import "FLEXAlert.h"
  15. #import "NSArray+Functional.h"
  16. #import "UIFont+FLEX.h"
  17. #import "NSMapTable+FLEX_Subscripting.h"
  18. // Used to prevent loading of pre-registered shortcuts and runtime categories in a test environment
  19. #define FLEX_EXIT_IF_TESTING() if (NSClassFromString(@"XCTest")) return;
  20. /// Rounds down to the nearest "point" coordinate
  21. NS_INLINE CGFloat FLEXFloor(CGFloat x) {
  22. return floor(UIScreen.mainScreen.scale * (x)) / UIScreen.mainScreen.scale;
  23. }
  24. /// Returns the given number of points in pixels
  25. NS_INLINE CGFloat FLEXPointsToPixels(CGFloat points) {
  26. return points / UIScreen.mainScreen.scale;
  27. }
  28. /// Creates a CGRect with all members rounded down to the nearest "point" coordinate
  29. NS_INLINE CGRect FLEXRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height) {
  30. return CGRectMake(FLEXFloor(x), FLEXFloor(y), FLEXFloor(width), FLEXFloor(height));
  31. }
  32. /// Adjusts the origin of an existing rect
  33. NS_INLINE CGRect FLEXRectSetOrigin(CGRect r, CGPoint origin) {
  34. r.origin = origin; return r;
  35. }
  36. /// Adjusts the size of an existing rect
  37. NS_INLINE CGRect FLEXRectSetSize(CGRect r, CGSize size) {
  38. r.size = size; return r;
  39. }
  40. /// Adjusts the origin.x of an existing rect
  41. NS_INLINE CGRect FLEXRectSetX(CGRect r, CGFloat x) {
  42. r.origin.x = x; return r;
  43. }
  44. /// Adjusts the origin.y of an existing rect
  45. NS_INLINE CGRect FLEXRectSetY(CGRect r, CGFloat y) {
  46. r.origin.y = y ; return r;
  47. }
  48. /// Adjusts the size.width of an existing rect
  49. NS_INLINE CGRect FLEXRectSetWidth(CGRect r, CGFloat width) {
  50. r.size.width = width; return r;
  51. }
  52. /// Adjusts the size.height of an existing rect
  53. NS_INLINE CGRect FLEXRectSetHeight(CGRect r, CGFloat height) {
  54. r.size.height = height; return r;
  55. }
  56. #ifdef __IPHONE_13_0
  57. #define FLEX_AT_LEAST_IOS13_SDK (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0)
  58. #else
  59. #define FLEX_AT_LEAST_IOS13_SDK NO
  60. #endif
  61. #define FLEXPluralString(count, plural, singular) [NSString \
  62. stringWithFormat:@"%@ %@", @(count), (count == 1 ? singular : plural) \
  63. ]
  64. #define FLEXPluralFormatString(count, pluralFormat, singularFormat) [NSString \
  65. stringWithFormat:(count == 1 ? singularFormat : pluralFormat), @(count) \
  66. ]
  67. #if !FLEX_AT_LEAST_IOS13_SDK
  68. @class UIWindowScene;
  69. #endif
  70. @interface FLEXUtility : NSObject
  71. /// The key window of the app, if it is not a \c FLEXWindow.
  72. /// If it is, then \c FLEXWindow.previousKeyWindow is returned.
  73. @property (nonatomic, readonly, class) UIWindow *appKeyWindow;
  74. /// @return the result of +[UIWindow allWindowsIncludingInternalWindows:onlyVisibleWindows:]
  75. @property (nonatomic, readonly, class) NSArray<UIWindow *> *allWindows;
  76. /// The first active \c UIWindowScene of the app.
  77. @property (nonatomic, readonly, class) UIWindowScene *activeScene API_AVAILABLE(ios(13.0));
  78. /// @return top-most view controller of the given window
  79. + (UIViewController *)topViewControllerInWindow:(UIWindow *)window;
  80. + (UIColor *)consistentRandomColorForObject:(id)object;
  81. + (NSString *)descriptionForView:(UIView *)view includingFrame:(BOOL)includeFrame;
  82. + (NSString *)stringForCGRect:(CGRect)rect;
  83. + (UIViewController *)viewControllerForView:(UIView *)view;
  84. + (UIViewController *)viewControllerForAncestralView:(UIView *)view;
  85. + (UIImage *)previewImageForView:(UIView *)view;
  86. + (UIImage *)previewImageForLayer:(CALayer *)layer;
  87. + (NSString *)detailDescriptionForView:(UIView *)view;
  88. + (UIImage *)circularImageWithColor:(UIColor *)color radius:(CGFloat)radius;
  89. + (UIColor *)hierarchyIndentPatternColor;
  90. + (NSString *)pointerToString:(void *)ptr;
  91. + (NSString *)addressOfObject:(id)object;
  92. + (NSString *)stringByEscapingHTMLEntitiesInString:(NSString *)originalString;
  93. + (UIInterfaceOrientationMask)infoPlistSupportedInterfaceOrientationsMask;
  94. + (UIImage *)thumbnailedImageWithMaxPixelDimension:(NSInteger)dimension fromImageData:(NSData *)data;
  95. + (NSString *)stringFromRequestDuration:(NSTimeInterval)duration;
  96. + (NSString *)statusCodeStringFromURLResponse:(NSURLResponse *)response;
  97. + (BOOL)isErrorStatusCodeFromURLResponse:(NSURLResponse *)response;
  98. + (NSArray<NSURLQueryItem *> *)itemsFromQueryString:(NSString *)query;
  99. + (NSString *)prettyJSONStringFromData:(NSData *)data;
  100. + (BOOL)isValidJSONData:(NSData *)data;
  101. + (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData;
  102. // Swizzling utilities
  103. + (SEL)swizzledSelectorForSelector:(SEL)selector;
  104. + (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls;
  105. + (void)replaceImplementationOfKnownSelector:(SEL)originalSelector onClass:(Class)class withBlock:(id)block swizzledSelector:(SEL)swizzledSelector;
  106. + (void)replaceImplementationOfSelector:(SEL)selector withSelector:(SEL)swizzledSelector forClass:(Class)cls withMethodDescription:(struct objc_method_description)methodDescription implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock;
  107. @end