FBRuntimeUtils.m 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /**
  2. * Copyright (c) 2015-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. #import "FBRuntimeUtils.h"
  10. #import "FBMacros.h"
  11. #import "XCUIDevice.h"
  12. #include <dlfcn.h>
  13. #import <objc/runtime.h>
  14. NSArray<Class> *FBClassesThatConformsToProtocol(Protocol *protocol)
  15. {
  16. Class *classes = NULL;
  17. NSMutableArray *collection = [NSMutableArray array];
  18. int numClasses = objc_getClassList(NULL, 0);
  19. if (numClasses == 0 ) {
  20. return @[];
  21. }
  22. classes = (__unsafe_unretained Class*)malloc(sizeof(Class) * numClasses);
  23. numClasses = objc_getClassList(classes, numClasses);
  24. for (int index = 0; index < numClasses; index++) {
  25. Class aClass = classes[index];
  26. if (class_conformsToProtocol(aClass, protocol)) {
  27. [collection addObject:aClass];
  28. }
  29. }
  30. free(classes);
  31. return collection.copy;
  32. }
  33. void *FBRetrieveSymbolFromBinary(const char *binary, const char *name)
  34. {
  35. void *handle = dlopen(binary, RTLD_LAZY);
  36. NSCAssert(handle, @"%s could not be opened", binary);
  37. void *pointer = dlsym(handle, name);
  38. NSCAssert(pointer, @"%s could not be located", name);
  39. return pointer;
  40. }
  41. static NSString *sdkVersion = nil;
  42. static dispatch_once_t onceSdkVersionToken;
  43. NSString * _Nullable FBSDKVersion(void)
  44. {
  45. dispatch_once(&onceSdkVersionToken, ^{
  46. NSString *sdkName = [[NSBundle mainBundle] infoDictionary][@"DTSDKName"];
  47. if (sdkName) {
  48. // the value of DTSDKName looks like 'iphoneos9.2'
  49. NSRange versionRange = [sdkName rangeOfString:@"\\d+\\.\\d+" options:NSRegularExpressionSearch];
  50. if (versionRange.location != NSNotFound) {
  51. sdkVersion = [sdkName substringWithRange:versionRange];
  52. }
  53. }
  54. });
  55. return sdkVersion;
  56. }
  57. BOOL isSDKVersionLessThan(NSString *expected)
  58. {
  59. NSString *version = FBSDKVersion();
  60. if (nil == version) {
  61. return SYSTEM_VERSION_LESS_THAN(expected);
  62. }
  63. NSComparisonResult result = [version compare:expected options:NSNumericSearch];
  64. return result == NSOrderedAscending;
  65. }
  66. BOOL isSDKVersionLessThanOrEqualTo(NSString *expected)
  67. {
  68. NSString *version = FBSDKVersion();
  69. if (nil == version) {
  70. return SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(expected);
  71. }
  72. NSComparisonResult result = [version compare:expected options:NSNumericSearch];
  73. return result == NSOrderedAscending || result == NSOrderedSame;
  74. }
  75. BOOL isSDKVersionEqualTo(NSString *expected)
  76. {
  77. NSString *version = FBSDKVersion();
  78. if (nil == version) {
  79. return SYSTEM_VERSION_EQUAL_TO(expected);
  80. }
  81. NSComparisonResult result = [version compare:expected options:NSNumericSearch];
  82. return result == NSOrderedSame;
  83. }
  84. BOOL isSDKVersionGreaterThanOrEqualTo(NSString *expected)
  85. {
  86. NSString *version = FBSDKVersion();
  87. if (nil == version) {
  88. return SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(expected);
  89. }
  90. NSComparisonResult result = [version compare:expected options:NSNumericSearch];
  91. return result == NSOrderedDescending || result == NSOrderedSame;
  92. }
  93. BOOL isSDKVersionGreaterThan(NSString *expected)
  94. {
  95. NSString *version = FBSDKVersion();
  96. if (nil == version) {
  97. return SYSTEM_VERSION_GREATER_THAN(expected);
  98. }
  99. NSComparisonResult result = [version compare:expected options:NSNumericSearch];
  100. return result == NSOrderedDescending;
  101. }