This commit is contained in:
2025-10-28 10:18:10 +08:00
parent efb04d134e
commit 1deca2ae5b
166 changed files with 17288 additions and 1427 deletions

View File

@@ -0,0 +1,242 @@
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
//
// LookinAppInfo.m
// qmuidemo
//
// Created by Li Kai on 2018/11/3.
// Copyright © 2018 QMUI Team. All rights reserved.
//
#import "LookinAppInfo.h"
#import "LKS_MultiplatformAdapter.h"
static NSString * const CodingKey_AppIcon = @"1";
static NSString * const CodingKey_Screenshot = @"2";
static NSString * const CodingKey_DeviceDescription = @"3";
static NSString * const CodingKey_OsDescription = @"4";
static NSString * const CodingKey_AppName = @"5";
static NSString * const CodingKey_ScreenWidth = @"6";
static NSString * const CodingKey_ScreenHeight = @"7";
static NSString * const CodingKey_DeviceType = @"8";
@implementation LookinAppInfo
- (id)copyWithZone:(NSZone *)zone {
LookinAppInfo *newAppInfo = [[LookinAppInfo allocWithZone:zone] init];
newAppInfo.appIcon = self.appIcon;
newAppInfo.appName = self.appName;
newAppInfo.deviceDescription = self.deviceDescription;
newAppInfo.osDescription = self.osDescription;
newAppInfo.osMainVersion = self.osMainVersion;
newAppInfo.deviceType = self.deviceType;
newAppInfo.screenWidth = self.screenWidth;
newAppInfo.screenHeight = self.screenHeight;
newAppInfo.screenScale = self.screenScale;
newAppInfo.appInfoIdentifier = self.appInfoIdentifier;
return newAppInfo;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.serverVersion = [aDecoder decodeIntForKey:@"serverVersion"];
self.serverReadableVersion = [aDecoder decodeObjectForKey:@"serverReadableVersion"];
self.swiftEnabledInLookinServer = [aDecoder decodeIntForKey:@"swiftEnabledInLookinServer"];
NSData *screenshotData = [aDecoder decodeObjectForKey:CodingKey_Screenshot];
self.screenshot = [[LookinImage alloc] initWithData:screenshotData];
NSData *appIconData = [aDecoder decodeObjectForKey:CodingKey_AppIcon];
self.appIcon = [[LookinImage alloc] initWithData:appIconData];
self.appName = [aDecoder decodeObjectForKey:CodingKey_AppName];
self.appBundleIdentifier = [aDecoder decodeObjectForKey:@"appBundleIdentifier"];
self.deviceDescription = [aDecoder decodeObjectForKey:CodingKey_DeviceDescription];
self.osDescription = [aDecoder decodeObjectForKey:CodingKey_OsDescription];
self.osMainVersion = [aDecoder decodeIntegerForKey:@"osMainVersion"];
self.deviceType = [aDecoder decodeIntegerForKey:CodingKey_DeviceType];
self.screenWidth = [aDecoder decodeDoubleForKey:CodingKey_ScreenWidth];
self.screenHeight = [aDecoder decodeDoubleForKey:CodingKey_ScreenHeight];
self.screenScale = [aDecoder decodeDoubleForKey:@"screenScale"];
self.appInfoIdentifier = [aDecoder decodeIntegerForKey:@"appInfoIdentifier"];
self.shouldUseCache = [aDecoder decodeBoolForKey:@"shouldUseCache"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt:self.serverVersion forKey:@"serverVersion"];
[aCoder encodeObject:self.serverReadableVersion forKey:@"serverReadableVersion"];
[aCoder encodeInt:self.swiftEnabledInLookinServer forKey:@"swiftEnabledInLookinServer"];
#if TARGET_OS_IPHONE
NSData *screenshotData = UIImagePNGRepresentation(self.screenshot);
[aCoder encodeObject:screenshotData forKey:CodingKey_Screenshot];
NSData *appIconData = UIImagePNGRepresentation(self.appIcon);
[aCoder encodeObject:appIconData forKey:CodingKey_AppIcon];
#elif TARGET_OS_MAC
NSData *screenshotData = [self.screenshot TIFFRepresentation];
[aCoder encodeObject:screenshotData forKey:CodingKey_Screenshot];
NSData *appIconData = [self.appIcon TIFFRepresentation];
[aCoder encodeObject:appIconData forKey:CodingKey_AppIcon];
#endif
[aCoder encodeObject:self.appName forKey:CodingKey_AppName];
[aCoder encodeObject:self.appBundleIdentifier forKey:@"appBundleIdentifier"];
[aCoder encodeObject:self.deviceDescription forKey:CodingKey_DeviceDescription];
[aCoder encodeObject:self.osDescription forKey:CodingKey_OsDescription];
[aCoder encodeInteger:self.osMainVersion forKey:@"osMainVersion"];
[aCoder encodeInteger:self.deviceType forKey:CodingKey_DeviceType];
[aCoder encodeDouble:self.screenWidth forKey:CodingKey_ScreenWidth];
[aCoder encodeDouble:self.screenHeight forKey:CodingKey_ScreenHeight];
[aCoder encodeDouble:self.screenScale forKey:@"screenScale"];
[aCoder encodeInteger:self.appInfoIdentifier forKey:@"appInfoIdentifier"];
[aCoder encodeBool:self.shouldUseCache forKey:@"shouldUseCache"];
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if (![object isKindOfClass:[LookinAppInfo class]]) {
return NO;
}
if ([self isEqualToAppInfo:object]) {
return YES;
}
return NO;
}
- (NSUInteger)hash {
return self.appName.hash ^ self.deviceDescription.hash ^ self.osDescription.hash ^ self.deviceType;
}
- (BOOL)isEqualToAppInfo:(LookinAppInfo *)info {
if (!info) {
return NO;
}
if ([self.appName isEqualToString:info.appName] && [self.deviceDescription isEqualToString:info.deviceDescription] && [self.osDescription isEqualToString:info.osDescription] && self.deviceType == info.deviceType) {
return YES;
}
return NO;
}
#if TARGET_OS_IPHONE
+ (LookinAppInfo *)currentInfoWithScreenshot:(BOOL)hasScreenshot icon:(BOOL)hasIcon localIdentifiers:(NSArray<NSNumber *> *)localIdentifiers {
NSInteger selfIdentifier = [self getAppInfoIdentifier];
if ([localIdentifiers containsObject:@(selfIdentifier)]) {
LookinAppInfo *info = [LookinAppInfo new];
info.appInfoIdentifier = selfIdentifier;
info.shouldUseCache = YES;
return info;
}
LookinAppInfo *info = [[LookinAppInfo alloc] init];
info.serverReadableVersion = LOOKIN_SERVER_READABLE_VERSION;
#ifdef LOOKIN_SERVER_SWIFT_ENABLED
info.swiftEnabledInLookinServer = 1;
#else
info.swiftEnabledInLookinServer = -1;
#endif
info.appInfoIdentifier = selfIdentifier;
info.appName = [self appName];
info.deviceDescription = [UIDevice currentDevice].name;
info.appBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
if ([self isSimulator]) {
info.deviceType = LookinAppInfoDeviceSimulator;
} else if ([LKS_MultiplatformAdapter isiPad]) {
info.deviceType = LookinAppInfoDeviceIPad;
} else {
info.deviceType = LookinAppInfoDeviceOthers;
}
info.osDescription = [UIDevice currentDevice].systemVersion;
NSString *mainVersionStr = [[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."].firstObject;
info.osMainVersion = [mainVersionStr integerValue];
CGSize screenSize = [LKS_MultiplatformAdapter mainScreenBounds].size;
info.screenWidth = screenSize.width;
info.screenHeight = screenSize.height;
info.screenScale = [LKS_MultiplatformAdapter mainScreenScale];
if (hasScreenshot) {
info.screenshot = [self screenshotImage];
}
if (hasIcon) {
info.appIcon = [self appIcon];
}
return info;
}
+ (NSString *)appName {
NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
NSString *displayName = [info objectForKey:@"CFBundleDisplayName"];
NSString *name = [info objectForKey:@"CFBundleName"];
return displayName.length ? displayName : name;
}
+ (UIImage *)appIcon {
#if TARGET_OS_TV
return nil;
#else
NSString *imageName = [[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIcons"] objectForKey:@"CFBundlePrimaryIcon"] objectForKey:@"CFBundleIconFiles"] lastObject];
if (!imageName.length) {
// name AppIcon60x60 nil return [UIImage imageNamed:nil] console "CUICatalog: Invalid asset name supplied: '(null)'"
return nil;
}
return [UIImage imageNamed:imageName];
#endif
}
+ (UIImage *)screenshotImage {
UIWindow *window = [LKS_MultiplatformAdapter keyWindow];
if (!window) {
return nil;
}
CGSize size = window.bounds.size;
if (size.width <= 0 || size.height <= 0) {
// *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={0, 0}, scale=3.000000, bitmapInfo=0x2002. Use UIGraphicsImageRenderer to avoid this assert.'
// https://github.com/hughkli/Lookin/issues/21
return nil;
}
UIGraphicsBeginImageContextWithOptions(size, YES, 0.4);
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
+ (BOOL)isSimulator {
if (TARGET_OS_SIMULATOR) {
return YES;
}
return NO;
}
#endif
+ (NSInteger)getAppInfoIdentifier {
static dispatch_once_t onceToken;
static NSInteger identifier = 0;
dispatch_once(&onceToken,^{
identifier = [[NSDate date] timeIntervalSince1970];
});
return identifier;
}
@end
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */