123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- #ifdef SHOULD_COMPILE_LOOKIN_SERVER
- //
- // LKS_AttrGroupsMaker.m
- // LookinServer
- //
- // Created by Li Kai on 2019/6/6.
- // https://lookin.work
- //
- #import "LKS_AttrGroupsMaker.h"
- #import "LookinAttributesGroup.h"
- #import "LookinAttributesSection.h"
- #import "LookinAttribute.h"
- #import "LookinDashboardBlueprint.h"
- #import "LookinIvarTrace.h"
- #import "UIColor+LookinServer.h"
- #import "LookinServerDefines.h"
- @implementation LKS_AttrGroupsMaker
- + (NSArray<LookinAttributesGroup *> *)attrGroupsForLayer:(CALayer *)layer {
- if (!layer) {
- NSAssert(NO, @"");
- return nil;
- }
- NSArray<LookinAttributesGroup *> *groups = [[LookinDashboardBlueprint groupIDs] lookin_map:^id(NSUInteger idx, LookinAttrGroupIdentifier groupID) {
- LookinAttributesGroup *group = [LookinAttributesGroup new];
- group.identifier = groupID;
- NSArray<LookinAttrSectionIdentifier> *secIDs = [LookinDashboardBlueprint sectionIDsForGroupID:groupID];
- group.attrSections = [secIDs lookin_map:^id(NSUInteger idx, LookinAttrSectionIdentifier secID) {
- LookinAttributesSection *sec = [LookinAttributesSection new];
- sec.identifier = secID;
-
- NSArray<LookinAttrIdentifier> *attrIDs = [LookinDashboardBlueprint attrIDsForSectionID:secID];
- sec.attributes = [attrIDs lookin_map:^id(NSUInteger idx, LookinAttrIdentifier attrID) {
- NSInteger minAvailableVersion = [LookinDashboardBlueprint minAvailableOSVersionWithAttrID:attrID];
- if (minAvailableVersion > 0 && (NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < minAvailableVersion)) {
- // iOS 版本过低不支持该属性
- return nil;
- }
-
- id targetObj = nil;
- if ([LookinDashboardBlueprint isUIViewPropertyWithAttrID:attrID]) {
- targetObj = layer.lks_hostView;
- } else {
- targetObj = layer;
- }
-
- if (targetObj) {
- Class targetClass = NSClassFromString([LookinDashboardBlueprint classNameWithAttrID:attrID]);
- if (![targetObj isKindOfClass:targetClass]) {
- return nil;
- }
-
- LookinAttribute *attr = [self _attributeWithIdentifer:attrID targetObject:targetObj];
- return attr;
- } else {
- return nil;
- }
- }];
-
- if (sec.attributes.count) {
- return sec;
- } else {
- return nil;
- }
- }];
-
- if ([groupID isEqualToString:LookinAttrGroup_AutoLayout]) {
- // 这里特殊处理一下,如果 AutoLayout 里面不包含 Constraints 的话(只有 Hugging 和 Resistance),就丢弃掉这整个 AutoLayout 不显示
- BOOL hasConstraits = [group.attrSections lookin_any:^BOOL(LookinAttributesSection *obj) {
- return [obj.identifier isEqualToString:LookinAttrSec_AutoLayout_Constraints];
- }];
- if (!hasConstraits) {
- return nil;
- }
- }
-
- if (group.attrSections.count) {
- return group;
- } else {
- return nil;
- }
- }];
-
- return groups;
- }
- + (LookinAttribute *)_attributeWithIdentifer:(LookinAttrIdentifier)identifier targetObject:(id)target {
- if (!target) {
- NSAssert(NO, @"");
- return nil;
- }
-
- LookinAttribute *attribute = [LookinAttribute new];
- attribute.identifier = identifier;
-
- SEL getter = [LookinDashboardBlueprint getterWithAttrID:identifier];
- if (!getter) {
- NSAssert(NO, @"");
- return nil;
- }
- if (![target respondsToSelector:getter]) {
- // 比如某些 QMUI 的属性,不引入 QMUI 就会走到这个分支里
- return nil;
- }
- NSMethodSignature *signature = [target methodSignatureForSelector:getter];
- if (signature.numberOfArguments > 2) {
- NSAssert(NO, @"getter 不可以有参数");
- return nil;
- }
- if (strcmp([signature methodReturnType], @encode(void)) == 0) {
- NSAssert(NO, @"getter 返回值不能为 void");
- return nil;
- }
-
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
- invocation.target = target;
- invocation.selector = getter;
- [invocation invoke];
-
- const char *returnType = [signature methodReturnType];
-
- if (strcmp(returnType, @encode(char)) == 0) {
- char targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeChar;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(int)) == 0) {
- int targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.value = @(targetValue);
- if ([LookinDashboardBlueprint enumListNameWithAttrID:identifier]) {
- attribute.attrType = LookinAttrTypeEnumInt;
- } else {
- attribute.attrType = LookinAttrTypeInt;
- }
-
- } else if (strcmp(returnType, @encode(short)) == 0) {
- short targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeShort;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(long)) == 0) {
- long targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.value = @(targetValue);
- if ([LookinDashboardBlueprint enumListNameWithAttrID:identifier]) {
- attribute.attrType = LookinAttrTypeEnumLong;
- } else {
- attribute.attrType = LookinAttrTypeLong;
- }
-
- } else if (strcmp(returnType, @encode(long long)) == 0) {
- long long targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeLongLong;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(unsigned char)) == 0) {
- unsigned char targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUnsignedChar;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(unsigned int)) == 0) {
- unsigned int targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUnsignedInt;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(unsigned short)) == 0) {
- unsigned short targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUnsignedShort;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(unsigned long)) == 0) {
- unsigned long targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUnsignedLong;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(unsigned long long)) == 0) {
- unsigned long long targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUnsignedLongLong;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(float)) == 0) {
- float targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeFloat;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(double)) == 0) {
- double targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeDouble;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(BOOL)) == 0) {
- BOOL targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeBOOL;
- attribute.value = @(targetValue);
-
- } else if (strcmp(returnType, @encode(SEL)) == 0) {
- SEL targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeSel;
- attribute.value = NSStringFromSelector(targetValue);
-
- } else if (strcmp(returnType, @encode(Class)) == 0) {
- Class targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeClass;
- attribute.value = NSStringFromClass(targetValue);
-
- } else if (strcmp(returnType, @encode(CGPoint)) == 0) {
- CGPoint targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeCGPoint;
- attribute.value = [NSValue valueWithCGPoint:targetValue];
-
- } else if (strcmp(returnType, @encode(CGVector)) == 0) {
- CGVector targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeCGVector;
- attribute.value = [NSValue valueWithCGVector:targetValue];
-
- } else if (strcmp(returnType, @encode(CGSize)) == 0) {
- CGSize targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeCGSize;
- attribute.value = [NSValue valueWithCGSize:targetValue];
-
- } else if (strcmp(returnType, @encode(CGRect)) == 0) {
- CGRect targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeCGRect;
- attribute.value = [NSValue valueWithCGRect:targetValue];
-
- } else if (strcmp(returnType, @encode(CGAffineTransform)) == 0) {
- CGAffineTransform targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeCGAffineTransform;
- attribute.value = [NSValue valueWithCGAffineTransform:targetValue];
-
- } else if (strcmp(returnType, @encode(UIEdgeInsets)) == 0) {
- UIEdgeInsets targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUIEdgeInsets;
- attribute.value = [NSValue valueWithUIEdgeInsets:targetValue];
-
- } else if (strcmp(returnType, @encode(UIOffset)) == 0) {
- UIOffset targetValue;
- [invocation getReturnValue:&targetValue];
- attribute.attrType = LookinAttrTypeUIOffset;
- attribute.value = [NSValue valueWithUIOffset:targetValue];
-
- } else {
- NSString *argType_string = [[NSString alloc] lookin_safeInitWithUTF8String:returnType];
- if ([argType_string hasPrefix:@"@"]) {
- __unsafe_unretained id returnObjValue;
- [invocation getReturnValue:&returnObjValue];
-
- if (!returnObjValue && [LookinDashboardBlueprint hideIfNilWithAttrID:identifier]) {
- // 对于某些属性,若 value 为 nil 则不显示
- return nil;
- }
-
- attribute.attrType = [LookinDashboardBlueprint objectAttrTypeWithAttrID:identifier];
- if (attribute.attrType == LookinAttrTypeUIColor) {
- if (returnObjValue == nil) {
- attribute.value = nil;
- } else if ([returnObjValue isKindOfClass:[UIColor class]] && [returnObjValue respondsToSelector:@selector(lks_rgbaComponents)]) {
- attribute.value = [returnObjValue lks_rgbaComponents];
- } else {
- // https://github.com/QMUI/LookinServer/issues/124
- return nil;
- }
- } else {
- attribute.value = returnObjValue;
- }
-
- } else {
- NSAssert(NO, @"不支持解析该类型的返回值");
- return nil;
- }
- }
-
- return attribute;
- }
- @end
- #endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|