LKS_CustomDisplayItemsMaker.m 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #ifdef SHOULD_COMPILE_LOOKIN_SERVER
  2. //
  3. // LKS_CustomDisplayItemsMaker.m
  4. // LookinServer
  5. //
  6. // Created by likai.123 on 2023/11/1.
  7. //
  8. #import "LKS_CustomDisplayItemsMaker.h"
  9. #import "CALayer+LookinServer.h"
  10. #import "LookinDisplayItem.h"
  11. #import "NSArray+Lookin.h"
  12. #import "LKS_CustomAttrGroupsMaker.h"
  13. @interface LKS_CustomDisplayItemsMaker ()
  14. @property(nonatomic, weak) CALayer *layer;
  15. @property(nonatomic, assign) BOOL saveAttrSetter;
  16. @property(nonatomic, strong) NSMutableArray *allSubitems;
  17. @end
  18. @implementation LKS_CustomDisplayItemsMaker
  19. - (instancetype)initWithLayer:(CALayer *)layer saveAttrSetter:(BOOL)saveAttrSetter {
  20. if (self = [super init]) {
  21. self.layer = layer;
  22. self.saveAttrSetter = saveAttrSetter;
  23. self.allSubitems = [NSMutableArray array];
  24. }
  25. return self;
  26. }
  27. - (NSArray<LookinDisplayItem *> *)make {
  28. if (!self.layer) {
  29. NSAssert(NO, @"");
  30. return nil;
  31. }
  32. NSMutableArray<NSString *> *selectors = [NSMutableArray array];
  33. [selectors addObject:@"lookin_customDebugInfos"];
  34. for (int i = 0; i < 5; i++) {
  35. [selectors addObject:[NSString stringWithFormat:@"lookin_customDebugInfos_%@", @(i)]];
  36. }
  37. for (NSString *name in selectors) {
  38. [self makeSubitemsForViewOrLayer:self.layer selectorName:name];
  39. UIView *view = self.layer.lks_hostView;
  40. if (view) {
  41. [self makeSubitemsForViewOrLayer:view selectorName:name];
  42. }
  43. }
  44. if (self.allSubitems.count) {
  45. return self.allSubitems;
  46. } else {
  47. return nil;
  48. }
  49. }
  50. - (void)makeSubitemsForViewOrLayer:(id)viewOrLayer selectorName:(NSString *)selectorName {
  51. if (!viewOrLayer || !selectorName.length) {
  52. return;
  53. }
  54. if (![viewOrLayer isKindOfClass:[UIView class]] && ![viewOrLayer isKindOfClass:[CALayer class]]) {
  55. return;
  56. }
  57. SEL selector = NSSelectorFromString(selectorName);
  58. if (![viewOrLayer respondsToSelector:selector]) {
  59. return;
  60. }
  61. NSMethodSignature *signature = [viewOrLayer methodSignatureForSelector:selector];
  62. if (signature.numberOfArguments > 2) {
  63. NSAssert(NO, @"LookinServer - There should be no explicit parameters.");
  64. return;
  65. }
  66. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  67. [invocation setTarget:viewOrLayer];
  68. [invocation setSelector:selector];
  69. [invocation invoke];
  70. // 小心这里的内存管理
  71. NSDictionary<NSString *, id> * __unsafe_unretained tempRawData;
  72. [invocation getReturnValue:&tempRawData];
  73. NSDictionary<NSString *, id> *rawData = tempRawData;
  74. [self makeSubitemsFromRawData:rawData];
  75. }
  76. - (void)makeSubitemsFromRawData:(NSDictionary<NSString *, id> *)data {
  77. if (!data || ![data isKindOfClass:[NSDictionary class]]) {
  78. return;
  79. }
  80. NSArray *rawSubviews = data[@"subviews"];
  81. NSArray<LookinDisplayItem *> *newSubitems = [self displayItemsFromRawArray:rawSubviews];
  82. if (newSubitems) {
  83. [self.allSubitems addObjectsFromArray:newSubitems];
  84. }
  85. }
  86. - (NSArray<LookinDisplayItem *> *)displayItemsFromRawArray:(NSArray<NSDictionary *> *)rawArray {
  87. if (!rawArray || ![rawArray isKindOfClass:[NSArray class]]) {
  88. return nil;
  89. }
  90. NSArray *items = [rawArray lookin_map:^id(NSUInteger idx, NSDictionary *rawDict) {
  91. if (![rawDict isKindOfClass:[NSDictionary class]]) {
  92. return nil;
  93. }
  94. return [self displayItemFromRawDict:rawDict];
  95. }];
  96. return items;
  97. }
  98. - (LookinDisplayItem *)displayItemFromRawDict:(NSDictionary<NSString *, id> *)dict {
  99. NSString *title = dict[@"title"];
  100. NSString *subtitle = dict[@"subtitle"];
  101. NSValue *frameValue = dict[@"frameInWindow"];
  102. NSArray *properties = dict[@"properties"];
  103. NSArray *subviews = dict[@"subviews"];
  104. NSString *danceSource = dict[@"lookin_source"];
  105. if (![title isKindOfClass:[NSString class]]) {
  106. return nil;
  107. }
  108. LookinDisplayItem *newItem = [LookinDisplayItem new];
  109. if (subviews && [subviews isKindOfClass:[NSArray class]]) {
  110. newItem.subitems = [self displayItemsFromRawArray:subviews];
  111. }
  112. newItem.isHidden = NO;
  113. newItem.alpha = 1.0;
  114. newItem.customInfo = [LookinCustomDisplayItemInfo new];
  115. newItem.customInfo.title = title;
  116. newItem.customInfo.subtitle = subtitle;
  117. newItem.customInfo.frameInWindow = frameValue;
  118. newItem.customInfo.danceuiSource = danceSource;
  119. newItem.customAttrGroupList = [LKS_CustomAttrGroupsMaker makeGroupsFromRawProperties:properties saveCustomSetter:self.saveAttrSetter];
  120. return newItem;
  121. }
  122. @end
  123. #endif /* SHOULD_COMPILE_LOOKIN_SERVER */