1
This commit is contained in:
26
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h
generated
Normal file
26
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.h
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
|
||||
//
|
||||
// LKS_AttrModificationPatchHandler.h
|
||||
// LookinServer
|
||||
//
|
||||
// Created by Li Kai on 2019/6/12.
|
||||
// https://lookin.work
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class LookinDisplayItemDetail;
|
||||
|
||||
@interface LKS_AttrModificationPatchHandler : NSObject
|
||||
|
||||
/**
|
||||
@param oids 数组内 idx 较小的应该为 displayItems 里的 subItem,idx 较大的应该为 superItem
|
||||
@param lowImageQuality 是否采用低图像质量
|
||||
@param block 该 block 会被多次调用,其中 tasksTotalCount 是总的调用次数(即可被用来作为 TotalResponseCount)
|
||||
*/
|
||||
+ (void)handleLayerOids:(NSArray<NSNumber *> *)oids lowImageQuality:(BOOL)lowImageQuality block:(void (^)(LookinDisplayItemDetail *detail, NSUInteger tasksTotalCount, NSError *error))block;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
51
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.m
generated
Normal file
51
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_AttrModificationPatchHandler.m
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
|
||||
//
|
||||
// LKS_AttrModificationPatchHandler.m
|
||||
// LookinServer
|
||||
//
|
||||
// Created by Li Kai on 2019/6/12.
|
||||
// https://lookin.work
|
||||
//
|
||||
|
||||
#import "LKS_AttrModificationPatchHandler.h"
|
||||
#import "LookinDisplayItemDetail.h"
|
||||
#import "LookinServerDefines.h"
|
||||
|
||||
@implementation LKS_AttrModificationPatchHandler
|
||||
|
||||
+ (void)handleLayerOids:(NSArray<NSNumber *> *)oids lowImageQuality:(BOOL)lowImageQuality block:(void (^)(LookinDisplayItemDetail *detail, NSUInteger tasksTotalCount, NSError *error))block {
|
||||
if (!block) {
|
||||
NSAssert(NO, @"");
|
||||
return;
|
||||
}
|
||||
if (![oids isKindOfClass:[NSArray class]]) {
|
||||
block(nil, 1, LookinErr_Inner);
|
||||
return;
|
||||
}
|
||||
|
||||
[oids enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
unsigned long oid = [obj unsignedLongValue];
|
||||
LookinDisplayItemDetail *detail = [LookinDisplayItemDetail new];
|
||||
detail.displayItemOid = oid;
|
||||
|
||||
CALayer *layer = (CALayer *)[NSObject lks_objectWithOid:oid];
|
||||
if (![layer isKindOfClass:[CALayer class]]) {
|
||||
block(nil, idx + 1, LookinErr_ObjNotFound);
|
||||
*stop = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
detail.soloScreenshot = [layer lks_soloScreenshotWithLowQuality:lowImageQuality];
|
||||
detail.groupScreenshot = [layer lks_groupScreenshotWithLowQuality:lowImageQuality];
|
||||
} else {
|
||||
detail.groupScreenshot = [layer lks_groupScreenshotWithLowQuality:lowImageQuality];
|
||||
}
|
||||
block(detail, oids.count, nil);
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
19
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h
generated
Normal file
19
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.h
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
//
|
||||
// LKS_CustomAttrModificationHandler.h
|
||||
// LookinServer
|
||||
//
|
||||
// Created by likaimacbookhome on 2023/11/4.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "LookinCustomAttrModification.h"
|
||||
|
||||
@interface LKS_CustomAttrModificationHandler : NSObject
|
||||
|
||||
/// 返回值表示是否修改成功(有成功调用 setter block 就算成功)
|
||||
+ (BOOL)handleModification:(LookinCustomAttrModification *)modification;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
155
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.m
generated
Normal file
155
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_CustomAttrModificationHandler.m
generated
Normal file
@@ -0,0 +1,155 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
//
|
||||
// LKS_CustomAttrModificationHandler.m
|
||||
// LookinServer
|
||||
//
|
||||
// Created by likaimacbookhome on 2023/11/4.
|
||||
//
|
||||
|
||||
#import "LKS_CustomAttrModificationHandler.h"
|
||||
#import "LKS_CustomAttrSetterManager.h"
|
||||
#import "UIColor+LookinServer.h"
|
||||
|
||||
@implementation LKS_CustomAttrModificationHandler
|
||||
|
||||
+ (BOOL)handleModification:(LookinCustomAttrModification *)modification {
|
||||
if (!modification || modification.customSetterID.length == 0) {
|
||||
return NO;
|
||||
}
|
||||
switch (modification.attrType) {
|
||||
case LookinAttrTypeNSString: {
|
||||
NSString *newValue = modification.value;
|
||||
if (newValue != nil && ![newValue isKindOfClass:[NSString class]]) {
|
||||
// nil 是合法的
|
||||
return NO;
|
||||
}
|
||||
LKS_StringSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getStringSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeDouble: {
|
||||
NSNumber *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSNumber class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_NumberSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getNumberSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeBOOL: {
|
||||
NSNumber *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSNumber class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_BoolSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getBoolSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue.boolValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeUIColor: {
|
||||
LKS_ColorSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getColorSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSArray<NSNumber *> *newValue = modification.value;
|
||||
if (newValue == nil) {
|
||||
// nil 是合法的
|
||||
setter(nil);
|
||||
return YES;
|
||||
}
|
||||
if (![newValue isKindOfClass:[NSArray class]]) {
|
||||
return NO;
|
||||
}
|
||||
UIColor *color = [UIColor lks_colorFromRGBAComponents:newValue];
|
||||
if (!color) {
|
||||
return NO;
|
||||
}
|
||||
setter(color);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeEnumString: {
|
||||
NSString *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSString class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_EnumSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getEnumSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeCGRect: {
|
||||
NSValue *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSValue class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_RectSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getRectSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue.CGRectValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeCGSize: {
|
||||
NSValue *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSValue class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_SizeSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getSizeSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue.CGSizeValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeCGPoint: {
|
||||
NSValue *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSValue class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_PointSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getPointSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue.CGPointValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
case LookinAttrTypeUIEdgeInsets: {
|
||||
NSValue *newValue = modification.value;
|
||||
if (![newValue isKindOfClass:[NSValue class]]) {
|
||||
return NO;
|
||||
}
|
||||
LKS_InsetsSetter setter = [[LKS_CustomAttrSetterManager sharedInstance] getInsetsSetterWithID:modification.customSetterID];
|
||||
if (!setter) {
|
||||
return NO;
|
||||
}
|
||||
setter(newValue.UIEdgeInsetsValue);
|
||||
return YES;
|
||||
}
|
||||
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
30
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h
generated
Normal file
30
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.h
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
|
||||
//
|
||||
// LKS_HierarchyDetailsHandler.h
|
||||
// LookinServer
|
||||
//
|
||||
// Created by Li Kai on 2019/6/20.
|
||||
// https://lookin.work
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class LookinDisplayItemDetail, LookinStaticAsyncUpdateTasksPackage;
|
||||
|
||||
typedef void (^LKS_HierarchyDetailsHandler_ProgressBlock)(NSArray<LookinDisplayItemDetail *> *details);
|
||||
typedef void (^LKS_HierarchyDetailsHandler_FinishBlock)(void);
|
||||
|
||||
@interface LKS_HierarchyDetailsHandler : NSObject
|
||||
|
||||
/// packages 会按照 idx 从小到大的顺序被执行
|
||||
/// 全部任务完成时,finishBlock 会被调用
|
||||
/// 如果调用了 cancel,则 finishBlock 不会被执行
|
||||
- (void)startWithPackages:(NSArray<LookinStaticAsyncUpdateTasksPackage *> *)packages block:(LKS_HierarchyDetailsHandler_ProgressBlock)progressBlock finishedBlock:(LKS_HierarchyDetailsHandler_FinishBlock)finishBlock;
|
||||
|
||||
/// 取消所有任务
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
148
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.m
generated
Normal file
148
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_HierarchyDetailsHandler.m
generated
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
|
||||
//
|
||||
// LKS_HierarchyDetailsHandler.m
|
||||
// LookinServer
|
||||
//
|
||||
// Created by Li Kai on 2019/6/20.
|
||||
// https://lookin.work
|
||||
//
|
||||
|
||||
#import "LKS_HierarchyDetailsHandler.h"
|
||||
#import "LookinDisplayItemDetail.h"
|
||||
#import "LKS_AttrGroupsMaker.h"
|
||||
#import "LookinStaticAsyncUpdateTask.h"
|
||||
#import "LKS_ConnectionManager.h"
|
||||
#import "LookinServerDefines.h"
|
||||
#import "LKS_CustomAttrGroupsMaker.h"
|
||||
#import "LKS_HierarchyDisplayItemsMaker.h"
|
||||
|
||||
@interface LKS_HierarchyDetailsHandler ()
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray<LookinStaticAsyncUpdateTasksPackage *> *taskPackages;
|
||||
/// 标识哪些 oid 已经拉取过 attrGroups 了
|
||||
@property(nonatomic, strong) NSMutableSet<NSNumber *> *attrGroupsSyncedOids;
|
||||
|
||||
@property(nonatomic, copy) LKS_HierarchyDetailsHandler_ProgressBlock progressBlock;
|
||||
@property(nonatomic, copy) LKS_HierarchyDetailsHandler_FinishBlock finishBlock;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LKS_HierarchyDetailsHandler
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleConnectionDidEnd:) name:LKS_ConnectionDidEndNotificationName object:nil];
|
||||
|
||||
self.attrGroupsSyncedOids = [NSMutableSet set];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)startWithPackages:(NSArray<LookinStaticAsyncUpdateTasksPackage *> *)packages block:(LKS_HierarchyDetailsHandler_ProgressBlock)progressBlock finishedBlock:(LKS_HierarchyDetailsHandler_FinishBlock)finishBlock {
|
||||
if (!progressBlock || !finishBlock) {
|
||||
NSAssert(NO, @"");
|
||||
return;
|
||||
}
|
||||
if (!packages.count) {
|
||||
finishBlock();
|
||||
return;
|
||||
}
|
||||
self.taskPackages = [packages mutableCopy];
|
||||
self.progressBlock = progressBlock;
|
||||
self.finishBlock = finishBlock;
|
||||
|
||||
[UIView lks_rebuildGlobalInvolvedRawConstraints];
|
||||
|
||||
[self _dequeueAndHandlePackage];
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[self.taskPackages removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)_dequeueAndHandlePackage {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
LookinStaticAsyncUpdateTasksPackage *package = self.taskPackages.firstObject;
|
||||
if (!package) {
|
||||
self.finishBlock();
|
||||
return;
|
||||
}
|
||||
// NSLog(@"LookinServer - will handle tasks, count: %@", @(tasks.count));
|
||||
NSArray<LookinDisplayItemDetail *> *details = [package.tasks lookin_map:^id(NSUInteger idx, LookinStaticAsyncUpdateTask *task) {
|
||||
LookinDisplayItemDetail *itemDetail = [LookinDisplayItemDetail new];
|
||||
itemDetail.displayItemOid = task.oid;
|
||||
|
||||
id object = [NSObject lks_objectWithOid:task.oid];
|
||||
if (!object || ![object isKindOfClass:[CALayer class]]) {
|
||||
itemDetail.failureCode = -1;
|
||||
return itemDetail;
|
||||
}
|
||||
|
||||
CALayer *layer = object;
|
||||
|
||||
if (task.taskType == LookinStaticAsyncUpdateTaskTypeSoloScreenshot) {
|
||||
UIImage *image = [layer lks_soloScreenshotWithLowQuality:NO];
|
||||
itemDetail.soloScreenshot = image;
|
||||
} else if (task.taskType == LookinStaticAsyncUpdateTaskTypeGroupScreenshot) {
|
||||
UIImage *image = [layer lks_groupScreenshotWithLowQuality:NO];
|
||||
itemDetail.groupScreenshot = image;
|
||||
}
|
||||
|
||||
BOOL shouldMakeAttr = [self queryIfShouldMakeAttrsFromTask:task];
|
||||
if (shouldMakeAttr) {
|
||||
itemDetail.attributesGroupList = [LKS_AttrGroupsMaker attrGroupsForLayer:layer];
|
||||
|
||||
NSString *version = task.clientReadableVersion;
|
||||
if (version.length > 0 && [version lookin_numbericOSVersion] >= 10004) {
|
||||
LKS_CustomAttrGroupsMaker *maker = [[LKS_CustomAttrGroupsMaker alloc] initWithLayer:layer];
|
||||
[maker execute];
|
||||
itemDetail.customAttrGroupList = [maker getGroups];
|
||||
itemDetail.customDisplayTitle = [maker getCustomDisplayTitle];
|
||||
itemDetail.danceUISource = [maker getDanceUISource];
|
||||
}
|
||||
[self.attrGroupsSyncedOids addObject:@(task.oid)];
|
||||
}
|
||||
|
||||
if (task.needBasisVisualInfo) {
|
||||
itemDetail.frameValue = [NSValue valueWithCGRect:layer.frame];
|
||||
itemDetail.boundsValue = [NSValue valueWithCGRect:layer.bounds];
|
||||
itemDetail.hiddenValue = [NSNumber numberWithBool:layer.isHidden];
|
||||
itemDetail.alphaValue = @(layer.opacity);
|
||||
}
|
||||
|
||||
if (task.needSubitems) {
|
||||
itemDetail.subitems = [LKS_HierarchyDisplayItemsMaker subitemsOfLayer:layer];
|
||||
}
|
||||
|
||||
return itemDetail;
|
||||
}];
|
||||
self.progressBlock(details);
|
||||
|
||||
[self.taskPackages removeObjectAtIndex:0];
|
||||
[self _dequeueAndHandlePackage];
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)queryIfShouldMakeAttrsFromTask:(LookinStaticAsyncUpdateTask *)task {
|
||||
switch (task.attrRequest) {
|
||||
case LookinDetailUpdateTaskAttrRequest_Automatic: {
|
||||
BOOL alreadyMadeBefore = [self.attrGroupsSyncedOids containsObject:@(task.oid)];
|
||||
return !alreadyMadeBefore;
|
||||
}
|
||||
case LookinDetailUpdateTaskAttrRequest_Need:
|
||||
return YES;
|
||||
case LookinDetailUpdateTaskAttrRequest_NotNeed:
|
||||
return NO;
|
||||
}
|
||||
NSAssert(NO, @"");
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)_handleConnectionDidEnd:(id)obj {
|
||||
[self cancel];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
23
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h
generated
Normal file
23
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.h
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
|
||||
//
|
||||
// LKS_InbuiltAttrModificationHandler.h
|
||||
// LookinServer
|
||||
//
|
||||
// Created by Li Kai on 2019/6/12.
|
||||
// https://lookin.work
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class LookinAttributeModification, LookinDisplayItemDetail, LookinStaticAsyncUpdateTask;
|
||||
|
||||
@interface LKS_InbuiltAttrModificationHandler : NSObject
|
||||
|
||||
+ (void)handleModification:(LookinAttributeModification *)modification completion:(void (^)(LookinDisplayItemDetail *data, NSError *error))completion;
|
||||
|
||||
+ (void)handlePatchWithTasks:(NSArray<LookinStaticAsyncUpdateTask *> *)tasks block:(void (^)(LookinDisplayItemDetail *data))block;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
255
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.m
generated
Normal file
255
Pods/LookinServer/Src/Main/Server/Connection/RequestHandler/LKS_InbuiltAttrModificationHandler.m
generated
Normal file
@@ -0,0 +1,255 @@
|
||||
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||||
|
||||
//
|
||||
// LKS_InbuiltAttrModificationHandler.m
|
||||
// LookinServer
|
||||
//
|
||||
// Created by Li Kai on 2019/6/12.
|
||||
// https://lookin.work
|
||||
//
|
||||
|
||||
#import "LKS_InbuiltAttrModificationHandler.h"
|
||||
#import "UIColor+LookinServer.h"
|
||||
#import "LookinAttributeModification.h"
|
||||
#import "LKS_AttrGroupsMaker.h"
|
||||
#import "LookinDisplayItemDetail.h"
|
||||
#import "LookinStaticAsyncUpdateTask.h"
|
||||
#import "LookinServerDefines.h"
|
||||
#import "LKS_CustomAttrGroupsMaker.h"
|
||||
|
||||
@implementation LKS_InbuiltAttrModificationHandler
|
||||
|
||||
+ (void)handleModification:(LookinAttributeModification *)modification completion:(void (^)(LookinDisplayItemDetail *data, NSError *error))completion {
|
||||
if (!completion) {
|
||||
NSAssert(NO, @"");
|
||||
return;
|
||||
}
|
||||
if (!modification || ![modification isKindOfClass:[LookinAttributeModification class]]) {
|
||||
completion(nil, LookinErr_Inner);
|
||||
return;
|
||||
}
|
||||
|
||||
NSObject *receiver = [NSObject lks_objectWithOid:modification.targetOid];
|
||||
if (!receiver) {
|
||||
completion(nil, LookinErr_ObjNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMethodSignature *setterSignature = [receiver methodSignatureForSelector:modification.setterSelector];
|
||||
NSInvocation *setterInvocation = [NSInvocation invocationWithMethodSignature:setterSignature];
|
||||
setterInvocation.target = receiver;
|
||||
setterInvocation.selector = modification.setterSelector;
|
||||
|
||||
if (setterSignature.numberOfArguments != 3 || ![receiver respondsToSelector:modification.setterSelector]) {
|
||||
completion(nil, LookinErr_Inner);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (modification.attrType) {
|
||||
case LookinAttrTypeNone:
|
||||
case LookinAttrTypeVoid: {
|
||||
completion(nil, LookinErr_Inner);
|
||||
return;
|
||||
}
|
||||
case LookinAttrTypeChar: {
|
||||
char expectedValue = [(NSNumber *)modification.value charValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeInt:
|
||||
case LookinAttrTypeEnumInt: {
|
||||
int expectedValue = [(NSNumber *)modification.value intValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeShort: {
|
||||
short expectedValue = [(NSNumber *)modification.value shortValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeLong:
|
||||
case LookinAttrTypeEnumLong: {
|
||||
long expectedValue = [(NSNumber *)modification.value longValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeLongLong: {
|
||||
long long expectedValue = [(NSNumber *)modification.value longLongValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUnsignedChar: {
|
||||
unsigned char expectedValue = [(NSNumber *)modification.value unsignedCharValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUnsignedInt: {
|
||||
unsigned int expectedValue = [(NSNumber *)modification.value unsignedIntValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUnsignedShort: {
|
||||
unsigned short expectedValue = [(NSNumber *)modification.value unsignedShortValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUnsignedLong: {
|
||||
unsigned long expectedValue = [(NSNumber *)modification.value unsignedLongValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUnsignedLongLong: {
|
||||
unsigned long long expectedValue = [(NSNumber *)modification.value unsignedLongLongValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeFloat: {
|
||||
float expectedValue = [(NSNumber *)modification.value floatValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeDouble: {
|
||||
double expectedValue = [(NSNumber *)modification.value doubleValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeBOOL: {
|
||||
BOOL expectedValue = [(NSNumber *)modification.value boolValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeSel: {
|
||||
SEL expectedValue = NSSelectorFromString(modification.value);
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeClass: {
|
||||
Class expectedValue = NSClassFromString(modification.value);
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeCGPoint: {
|
||||
CGPoint expectedValue = [(NSValue *)modification.value CGPointValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeCGVector: {
|
||||
CGVector expectedValue = [(NSValue *)modification.value CGVectorValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeCGSize: {
|
||||
CGSize expectedValue = [(NSValue *)modification.value CGSizeValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeCGRect: {
|
||||
CGRect expectedValue = [(NSValue *)modification.value CGRectValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeCGAffineTransform: {
|
||||
CGAffineTransform expectedValue = [(NSValue *)modification.value CGAffineTransformValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUIEdgeInsets: {
|
||||
UIEdgeInsets expectedValue = [(NSValue *)modification.value UIEdgeInsetsValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUIOffset: {
|
||||
UIOffset expectedValue = [(NSValue *)modification.value UIOffsetValue];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeCustomObj:
|
||||
case LookinAttrTypeNSString: {
|
||||
NSObject *expectedValue = modification.value;
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
[setterInvocation retainArguments];
|
||||
break;
|
||||
}
|
||||
case LookinAttrTypeUIColor: {
|
||||
NSArray<NSNumber *> *rgba = modification.value;
|
||||
UIColor *expectedValue = [UIColor lks_colorFromRGBAComponents:rgba];
|
||||
[setterInvocation setArgument:&expectedValue atIndex:2];
|
||||
[setterInvocation retainArguments];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
completion(nil, LookinErr_Inner);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSError *error = nil;
|
||||
@try {
|
||||
[setterInvocation invoke];
|
||||
} @catch (NSException *exception) {
|
||||
NSString *errorMsg = [NSString stringWithFormat:LKS_Localized(@"<%@: %p>: an exception was raised when invoking %@. (%@)"), NSStringFromClass(receiver.class), receiver, NSStringFromSelector(modification.setterSelector), exception.reason];
|
||||
error = [NSError errorWithDomain:LookinErrorDomain code:LookinErrCode_Exception userInfo:@{NSLocalizedDescriptionKey:LKS_Localized(@"The modification may failed."), NSLocalizedRecoverySuggestionErrorKey:errorMsg}];
|
||||
} @finally {
|
||||
|
||||
}
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
CALayer *layer = nil;
|
||||
if ([receiver isKindOfClass:[CALayer class]]) {
|
||||
layer = (CALayer *)receiver;
|
||||
} else if ([receiver isKindOfClass:[UIView class]]) {
|
||||
layer = ((UIView *)receiver).layer;
|
||||
} else {
|
||||
completion(nil, LookinErr_ObjNotFound);
|
||||
return;
|
||||
}
|
||||
// 比如试图更改 frame 时,这个改动很有可能触发用户业务的 relayout,因此这时 dispatch 一下以确保拿到的 attrGroups 数据是最新的
|
||||
LookinDisplayItemDetail *detail = [LookinDisplayItemDetail new];
|
||||
detail.displayItemOid = modification.targetOid;
|
||||
detail.attributesGroupList = [LKS_AttrGroupsMaker attrGroupsForLayer:layer];
|
||||
|
||||
NSString *version = modification.clientReadableVersion;
|
||||
if (version.length > 0 && [version lookin_numbericOSVersion] >= 10004) {
|
||||
LKS_CustomAttrGroupsMaker *maker = [[LKS_CustomAttrGroupsMaker alloc] initWithLayer:layer];
|
||||
[maker execute];
|
||||
detail.customAttrGroupList = [maker getGroups];
|
||||
}
|
||||
|
||||
detail.frameValue = [NSValue valueWithCGRect:layer.frame];
|
||||
detail.boundsValue = [NSValue valueWithCGRect:layer.bounds];
|
||||
detail.hiddenValue = [NSNumber numberWithBool:layer.isHidden];
|
||||
detail.alphaValue = @(layer.opacity);
|
||||
completion(detail, error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+ (void)handlePatchWithTasks:(NSArray<LookinStaticAsyncUpdateTask *> *)tasks block:(void (^)(LookinDisplayItemDetail *data))block {
|
||||
if (!block) {
|
||||
NSAssert(NO, @"");
|
||||
return;
|
||||
}
|
||||
[tasks enumerateObjectsUsingBlock:^(LookinStaticAsyncUpdateTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
LookinDisplayItemDetail *itemDetail = [LookinDisplayItemDetail new];
|
||||
itemDetail.displayItemOid = task.oid;
|
||||
id object = [NSObject lks_objectWithOid:task.oid];
|
||||
if (!object || ![object isKindOfClass:[CALayer class]]) {
|
||||
block(itemDetail);
|
||||
return;
|
||||
}
|
||||
|
||||
CALayer *layer = object;
|
||||
if (task.taskType == LookinStaticAsyncUpdateTaskTypeSoloScreenshot) {
|
||||
UIImage *image = [layer lks_soloScreenshotWithLowQuality:NO];
|
||||
itemDetail.soloScreenshot = image;
|
||||
} else if (task.taskType == LookinStaticAsyncUpdateTaskTypeGroupScreenshot) {
|
||||
UIImage *image = [layer lks_groupScreenshotWithLowQuality:NO];
|
||||
itemDetail.groupScreenshot = image;
|
||||
}
|
||||
block(itemDetail);
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|
||||
Reference in New Issue
Block a user