update
This commit is contained in:
20
Pods/CocoaDebug/Sources/Categories/GPBMessage+CocoaDebug.h
generated
Normal file
20
Pods/CocoaDebug/Sources/Categories/GPBMessage+CocoaDebug.h
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
////
|
||||
//// Example
|
||||
//// man.li
|
||||
////
|
||||
//// Created by man 11/11/2018.
|
||||
//// Copyright © 2020 man. All rights reserved.
|
||||
////
|
||||
//
|
||||
//#import <Protobuf/GPBMessage.h>
|
||||
//
|
||||
//@interface GPBMessage (CocoaDebug)
|
||||
//
|
||||
//- (id _Nullable)initWithDictionary:(NSDictionary *_Nullable)dict;
|
||||
//
|
||||
//- (NSDictionary *_Nullable)containerType;
|
||||
//- (NSDictionary *_Nullable)nameMap;
|
||||
//- (NSString *_Nullable)_JSONStringWithIgnoreFields:(NSArray * _Nullable)ignoreFields;
|
||||
//- (NSDictionary *_Nullable)dictionaryWithIgnoreFields:(NSArray * _Nullable)ignoreFields;
|
||||
//
|
||||
//@end
|
||||
411
Pods/CocoaDebug/Sources/Categories/GPBMessage+CocoaDebug.m
generated
Normal file
411
Pods/CocoaDebug/Sources/Categories/GPBMessage+CocoaDebug.m
generated
Normal file
@@ -0,0 +1,411 @@
|
||||
////
|
||||
//// Example
|
||||
//// man.li
|
||||
////
|
||||
//// Created by man 11/11/2018.
|
||||
//// Copyright © 2020 man. All rights reserved.
|
||||
////
|
||||
//
|
||||
//#import "GPBMessage+CocoaDebug.h"
|
||||
//#import "NSObject+CocoaDebug.h"
|
||||
//#import <objc/runtime.h>
|
||||
//#import <objc/message.h>
|
||||
//#import "GPBArray.h"
|
||||
//
|
||||
//@implementation GPBMessage (CocoaDebug)
|
||||
//
|
||||
//#pragma mark - Public Methods
|
||||
//- (id)initWithDictionary:(NSDictionary *)dict {
|
||||
// self = [self init];
|
||||
// if (dict && [dict isKindOfClass:[NSDictionary class]]) {
|
||||
// NSMutableDictionary<NSString *, NSString *> *keyMap = [NSMutableDictionary<NSString *, NSString *> dictionary];
|
||||
// NSDictionary *nameMap = [self nameMap];
|
||||
// for (NSString *keyName in nameMap) {
|
||||
// id keyNameObject = [nameMap objectForKey:keyName];
|
||||
// if ([keyNameObject isKindOfClass:[NSString class]]) {
|
||||
// [keyMap setObject:keyName forKey:keyNameObject];
|
||||
// }
|
||||
// if ([keyNameObject isKindOfClass:[NSArray class]]) {
|
||||
// for (id keyPath in (NSArray *)keyNameObject) {
|
||||
// [keyMap setObject:keyName forKey:keyPath];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// for (NSString *keyName in dict) {
|
||||
// NSString *keyPath = [keyMap _stringForKey:keyName default:keyName];
|
||||
// [self setKeyPath:keyPath value:[dict objectForKey:keyName]];
|
||||
// }
|
||||
// }
|
||||
// return self;
|
||||
//}
|
||||
//
|
||||
//- (NSDictionary *)containerType {
|
||||
// return @{};
|
||||
//}
|
||||
//
|
||||
//- (NSDictionary *)nameMap {
|
||||
// return @{};
|
||||
//}
|
||||
//
|
||||
//- (NSString *)_JSONStringWithIgnoreFields:(NSArray * _Nullable)ignoreFields {
|
||||
// NSData *data = [NSJSONSerialization dataWithJSONObject:[self dictionaryWithIgnoreFields:ignoreFields] options:kNilOptions error:nil];
|
||||
// return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
//}
|
||||
//
|
||||
//#pragma mark - Private Methods
|
||||
//- (NSDictionary *)dictionaryWithIgnoreFields:(NSArray * _Nullable)ignoreFields {
|
||||
// NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
||||
//
|
||||
// unsigned int count;
|
||||
// objc_property_t *properties = class_copyPropertyList([self class], &count);
|
||||
// for (unsigned int i = 0; i < count; i++) {
|
||||
// const char *propertyName = property_getName(properties[i]);
|
||||
// NSString *keyPath = [NSString stringWithUTF8String:propertyName];
|
||||
//
|
||||
// id serializeObject = [self serializeValueForKey:keyPath];
|
||||
// if (nil == serializeObject) {
|
||||
// continue;
|
||||
// }
|
||||
// id keyNameObject = [[self nameMap] objectForKey:keyPath];
|
||||
//
|
||||
// if (keyNameObject == nil && ![ignoreFields containsObject:keyPath]) {
|
||||
// [dict setObject:serializeObject forKey:keyPath];
|
||||
// }
|
||||
// if ([keyNameObject isKindOfClass:[NSString class]] && ![ignoreFields containsObject:keyNameObject]) {
|
||||
// [dict setObject:serializeObject forKey:keyNameObject];
|
||||
// }
|
||||
// if ([keyNameObject isKindOfClass:[NSArray class]] && ![ignoreFields containsObject:keyNameObject]) {
|
||||
// NSString *keyName = [keyNameObject objectAtIndex:0]; // Serialize only the first value
|
||||
// [dict setObject:serializeObject forKey:keyName];
|
||||
// }
|
||||
// }
|
||||
// free(properties);
|
||||
// return dict;
|
||||
//}
|
||||
//
|
||||
//- (NSDictionary *)dictionary {
|
||||
// return [self dictionaryWithIgnoreFields:nil];
|
||||
//}
|
||||
//
|
||||
//- (id)serializeValueForKey:(NSString *)keyPath {
|
||||
// id item = [self valueForKey:keyPath];
|
||||
// if ([item isKindOfClass:[NSNumber class]] || [item isKindOfClass:[NSString class]]) {
|
||||
// return item;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBMessage class]]) {
|
||||
// return [item dictionary];
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBInt32Array class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBInt32Array *itemArray = (GPBInt32Array *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBUInt32Array class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBUInt32Array *itemArray = (GPBUInt32Array *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBInt64Array class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBInt64Array *itemArray = (GPBInt64Array *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBUInt64Array class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBUInt64Array *itemArray = (GPBUInt64Array *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBFloatArray class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBFloatArray *itemArray = (GPBFloatArray *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBDoubleArray class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBDoubleArray *itemArray = (GPBDoubleArray *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBBoolArray class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBBoolArray *itemArray = (GPBBoolArray *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[GPBEnumArray class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// GPBEnumArray *itemArray = (GPBEnumArray *)item;
|
||||
// [itemArray enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// [array addObject:@(value)];
|
||||
// }];
|
||||
// return array;
|
||||
// }
|
||||
// if ([item isKindOfClass:[NSArray class]]) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// for (id arrayItem in item) {
|
||||
// if ([arrayItem isKindOfClass:[NSNumber class]] || [arrayItem isKindOfClass:[NSString class]]) {
|
||||
// [array addObject:arrayItem];
|
||||
// continue;
|
||||
// }
|
||||
// if ([arrayItem isKindOfClass:[GPBMessage class]]) {
|
||||
// [array addObject:[arrayItem dictionary]];
|
||||
// }
|
||||
// }
|
||||
// return array;
|
||||
// }
|
||||
// return nil;
|
||||
//}
|
||||
//
|
||||
//- (void)setKeyPath:(NSString *)keyPath value:(id)value {
|
||||
// NSMutableArray *propertiesNameArray = [NSMutableArray<NSString *> array];
|
||||
// NSMutableDictionary *propertiesTypeDic = [NSMutableDictionary<NSString *, NSString *> dictionary];
|
||||
// unsigned int count;
|
||||
// objc_property_t *properties = class_copyPropertyList([self class], &count);
|
||||
// for (NSUInteger i = 0; i < count; i++) {
|
||||
// objc_property_t property = properties[i];
|
||||
// NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
|
||||
// [propertiesNameArray addObject:propertyName];
|
||||
//
|
||||
// NSString *attr = [NSString stringWithUTF8String:&(property_getAttributes(property)[1])];
|
||||
// NSString *type = [[attr componentsSeparatedByString:@","] objectAtIndex:0];
|
||||
// [propertiesTypeDic setObject:type forKey:propertyName];
|
||||
// }
|
||||
// free(properties);
|
||||
//
|
||||
// NSString *type = [propertiesTypeDic _stringForKey:keyPath default:@""];
|
||||
// SEL setter = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:", [keyPath substringToIndex:1].uppercaseString, [keyPath substringFromIndex:1]]);
|
||||
//
|
||||
// if ([value isKindOfClass:[NSString class]] == YES) {
|
||||
// NSString *str = (NSString *)value;
|
||||
// if ([type isEqualToString:@"@\"NSString\""]) {
|
||||
// ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)self, setter, str);
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(bool)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require bool but string", self, keyPath);
|
||||
// ((void (*)(id, SEL, bool))(void *) objc_msgSend)(self, setter, str.boolValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(BOOL)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require BOOL but string", self, keyPath);
|
||||
// ((void (*)(id, SEL, BOOL))(void *) objc_msgSend)(self, setter, str.boolValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(int32_t)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require int32_t but string", self, keyPath);
|
||||
// ((void (*)(id, SEL, int32_t))(void *) objc_msgSend)(self, setter, (int32_t)str.intValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(uint32_t)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require uint32_t but string", self, keyPath);
|
||||
// NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
|
||||
// [numberFormatter setNumberStyle:NSNumberFormatterNoStyle];
|
||||
// NSNumber *num = [numberFormatter numberFromString:str];
|
||||
// ((void (*)(id, SEL, uint32_t))(void *) objc_msgSend)(self, setter, (uint32_t)num.unsignedIntValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(int64_t)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require int64_t but string", self, keyPath);
|
||||
// ((void (*)(id, SEL, int64_t))(void *) objc_msgSend)(self, setter, (int64_t)str.longLongValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(uint64_t)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require uint64_t but string", self, keyPath);
|
||||
// NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
|
||||
// [numberFormatter setNumberStyle:NSNumberFormatterNoStyle];
|
||||
// NSNumber *num = [numberFormatter numberFromString:str];
|
||||
// ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)(self, setter, (uint64_t)num.unsignedLongLongValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(float)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require float but string", self, keyPath);
|
||||
// float f = str.floatValue;
|
||||
// if (isnan(f) == NO && isinf(f) == NO) {
|
||||
// ((void (*)(id, SEL, float))(void *) objc_msgSend)(self, setter, f);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(double)]]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require double but string", self, keyPath);
|
||||
// double d = str.doubleValue;
|
||||
// if (isnan(d) == NO && isinf(d) == NO) {
|
||||
// ((void (*)(id, SEL, double))(void *) objc_msgSend)(self, setter, d);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ([value isKindOfClass:[NSNumber class]] == YES) {
|
||||
// NSNumber *number = (NSNumber *)value;
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(bool)]]) {
|
||||
// ((void (*)(id, SEL, bool))(void *) objc_msgSend)(self, setter, number.boolValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(BOOL)]]) {
|
||||
// ((void (*)(id, SEL, BOOL))(void *) objc_msgSend)(self, setter, number.boolValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(int32_t)]]) {
|
||||
// ((void (*)(id, SEL, int32_t))(void *) objc_msgSend)(self, setter, (int32_t)number.intValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(uint32_t)]]) {
|
||||
// ((void (*)(id, SEL, uint32_t))(void *) objc_msgSend)(self, setter, (uint32_t)number.unsignedIntValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(int64_t)]]) {
|
||||
// ((void (*)(id, SEL, int64_t))(void *) objc_msgSend)(self, setter, (int64_t)number.longLongValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(uint64_t)]]) {
|
||||
// ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)(self, setter, (uint64_t)number.longLongValue);
|
||||
// return;
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(float)]]) {
|
||||
// float f = number.floatValue;
|
||||
// if (isnan(f) == NO && isinf(f) == NO) {
|
||||
// ((void (*)(id, SEL, float))(void *) objc_msgSend)(self, setter, f);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// if ([type isEqualToString:[NSString stringWithUTF8String:@encode(double)]]) {
|
||||
// double d = number.doubleValue;
|
||||
// if (isnan(d) == NO && isinf(d) == NO) {
|
||||
// ((void (*)(id, SEL, double))(void *) objc_msgSend)(self, setter, d);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// if ([type isEqualToString:@"@\"NSString\""]) {
|
||||
// NSAssert([value isKindOfClass:[NSString class]], @"%@: property (%@) type mismatch, require string but number", self, keyPath);
|
||||
// ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)self, setter, [number stringValue]);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// if (([type isEqualToString:@"@\"NSMutableArray\""] || [type isEqualToString:@"@\"NSArray\""]) && [value isKindOfClass:[NSArray class]] == YES) {
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// for (id arrayValue in value) {
|
||||
// if ([arrayValue isKindOfClass:[NSNumber class]] == YES || [arrayValue isKindOfClass:[NSString class]] == YES) {
|
||||
// [array addObject:arrayValue];
|
||||
// continue;
|
||||
// }
|
||||
// if ([arrayValue isKindOfClass:[NSDictionary class]] == YES) {
|
||||
// NSString *arrayItemType = [[self containerType] _stringForKey:keyPath default:nil];
|
||||
// if (arrayItemType == nil) {
|
||||
// [array addObject:arrayValue];
|
||||
// break;
|
||||
// }
|
||||
// Class itemClass = NSClassFromString(arrayItemType);
|
||||
// if (!itemClass) {
|
||||
// //SSPWarning(@"Can't find class of %@", arrayItemType);
|
||||
// return;
|
||||
// }
|
||||
// Class parentClass = class_getSuperclass(itemClass);
|
||||
// if ([parentClass isEqual:[GPBMessage class]] == NO) {
|
||||
// //SSPWarning(@"%@ is not GPBMessage", arrayItemType);
|
||||
// return;
|
||||
// }
|
||||
// [array addObject:[[itemClass alloc] initWithDictionary:arrayValue]];
|
||||
// }
|
||||
// if ([arrayValue isKindOfClass:[NSArray class]] == YES) {
|
||||
// //SSPError(@"Not support NSArray in NSArray");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// ((void (*)(id, SEL, id))(void *) objc_msgSend)(self, setter, array);
|
||||
// return;
|
||||
// }
|
||||
// if ([type hasPrefix:@"@\""] && [value isKindOfClass:[NSDictionary class]] == YES) {
|
||||
// if ([type isEqualToString:@"@\"NSDictionary\""] || [type isEqualToString:@"@\"NSMutableDictionary\""]) {
|
||||
// NSMutableDictionary *dictValue = [NSMutableDictionary dictionary];
|
||||
// NSArray *dictTypes = [[self containerType] _arrayForKey:keyPath default:nil];
|
||||
// if (dictTypes && [dictTypes count] == 2) {
|
||||
// for (id dictKey in value) {
|
||||
// Class itemClass = NSClassFromString(dictTypes[1]);
|
||||
// if (!itemClass) {
|
||||
// //SSPWarning(@"Can't find class of %@", dictTypes[1]);
|
||||
// return;
|
||||
// }
|
||||
// if ([itemClass isEqual:[NSString class]]||[itemClass isEqual:[NSNumber class]]) {
|
||||
// [dictValue setObject:value[dictKey] forKey:dictKey];
|
||||
// continue;
|
||||
// }
|
||||
// Class parentClass = class_getSuperclass(itemClass);
|
||||
// if ([parentClass isEqual:[GPBMessage class]] == NO) {
|
||||
// //SSPWarning(@"%@ is not GPBMessage", dictTypes[1]);
|
||||
// return;
|
||||
// }
|
||||
// [dictValue setObject:[[itemClass alloc] initWithDictionary:value[dictKey]] forKey:dictKey];
|
||||
// }
|
||||
// } else if (dictTypes && [dictTypes count] == 3){
|
||||
// for (id dictKey in value) {
|
||||
// Class itemClass = NSClassFromString(dictTypes[1]);
|
||||
// if (!itemClass || ![itemClass isEqual:[NSArray class]] || ![value[dictKey] isKindOfClass:[NSArray class]]) {
|
||||
// //SSPWarning(@"Map<obj, Array> parse error!");
|
||||
// return;
|
||||
// }
|
||||
// NSMutableArray *array = [NSMutableArray array];
|
||||
// for (id arrayValue in value[dictKey]) {
|
||||
// if ([arrayValue isKindOfClass:[NSNumber class]] == YES || [arrayValue isKindOfClass:[NSString class]] == YES) {
|
||||
// [array addObject:arrayValue];
|
||||
// continue;
|
||||
// }
|
||||
// if ([arrayValue isKindOfClass:[NSDictionary class]] == YES) {
|
||||
// Class inItemClass = NSClassFromString(dictTypes[2]);
|
||||
// if (!inItemClass) {
|
||||
// //SSPWarning(@"Can't find class of %@", dictTypes[2]);
|
||||
// return;
|
||||
// }
|
||||
// Class parentClass = class_getSuperclass(inItemClass);
|
||||
// if ([parentClass isEqual:[GPBMessage class]] == NO) {
|
||||
// //SSPWarning(@"%@ is not GPBMessage", dictTypes[2]);
|
||||
// return;
|
||||
// }
|
||||
// [array addObject:[[inItemClass alloc] initWithDictionary:arrayValue]];
|
||||
// }
|
||||
// if ([arrayValue isKindOfClass:[NSArray class]] == YES) {
|
||||
// //SSPError(@"Not support NSArray in NSArray");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// [dictValue setObject:array forKey:dictKey];
|
||||
// }
|
||||
// }
|
||||
// ((void (*)(id, SEL, id))(void *) objc_msgSend)(self, setter, dictValue);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// NSString *itemType = [type substringWithRange:NSMakeRange(2, [type length]-3)];
|
||||
// Class itemClass = NSClassFromString(itemType);
|
||||
// if (!itemClass) {
|
||||
// //SSPWarning(@"Can't find class of %@", itemType);
|
||||
// return;
|
||||
// }
|
||||
// Class parentClass = class_getSuperclass(itemClass);
|
||||
// if ([parentClass isEqual:[GPBMessage class]] == NO) {
|
||||
// //SSPWarning(@"%@ is not GPBMessage", itemType);
|
||||
// return;
|
||||
// }
|
||||
// id item = [[itemClass alloc] initWithDictionary:value];
|
||||
// ((void (*)(id, SEL, id))(void *) objc_msgSend)(self, setter, item);
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//@end
|
||||
84
Pods/CocoaDebug/Sources/Categories/NSObject+CocoaDebug.h
generated
Normal file
84
Pods/CocoaDebug/Sources/Categories/NSObject+CocoaDebug.h
generated
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Example
|
||||
// man
|
||||
//
|
||||
// Created by man 11/11/2018.
|
||||
// Copyright © 2020 man. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@interface NSData (CocoaDebug)
|
||||
|
||||
+ (NSData *_Nullable)dataWithInputStream:(NSInputStream *_Nullable)stream;
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@interface NSString (CocoaDebug)
|
||||
|
||||
- (CGFloat)heightWithFont:(UIFont *_Nullable)font constraintToWidth:(CGFloat)width;
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@interface NSURLRequest (CocoaDebug)
|
||||
|
||||
- (NSString *_Nullable)requestId;
|
||||
- (void)setRequestId:(NSString *_Nullable)requestId;
|
||||
|
||||
- (NSNumber*_Nullable)startTime;
|
||||
- (void)setStartTime:(NSNumber*_Nullable)startTime;
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@interface UIColor (CocoaDebug)
|
||||
|
||||
+ (UIColor *_Nullable)colorFromHexString:(NSString *_Nullable)hexString;
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@interface NSDictionary (CocoaDebug)
|
||||
|
||||
- (NSString *_Nullable)_stringForKey:(id<NSCopying>_Nullable)key;
|
||||
- (NSArray *_Nullable)_arrayForKey:(id<NSCopying>_Nullable)key;
|
||||
- (NSDictionary *_Nullable)_dictionaryForKey:(id<NSCopying>_Nullable)key;
|
||||
- (NSInteger)_integerForKey:(id<NSCopying>_Nullable)key;
|
||||
- (int64_t)_int64ForKey:(id<NSCopying>_Nullable)key;
|
||||
- (int32_t)_int32ForKey:(id<NSCopying>_Nullable)key;
|
||||
- (float)_floatForKey:(id<NSCopying>_Nullable)key;
|
||||
- (double)_doubleForKey:(id<NSCopying>_Nullable)key;
|
||||
- (BOOL)_boolForKey:(id<NSCopying>_Nullable)key;
|
||||
|
||||
- (NSString *_Nullable)_stringForKey:(id<NSCopying>_Nullable)key default:(NSString * _Nullable)defaultValue;
|
||||
- (bool)_boolForKey:(id<NSCopying>_Nullable)key default:(bool)defaultValue;
|
||||
- (NSInteger)_integerForKey:(id<NSCopying>_Nullable)key default:(NSInteger)defaultValue;
|
||||
- (float)_floatForKey:(id<NSCopying>_Nullable)key default:(float)defaultValue;
|
||||
- (NSArray *_Nullable)_arrayForKey:(id<NSCopying>_Nullable)key default:(NSArray * _Nullable)defaultValue;
|
||||
- (NSDictionary *_Nullable)_dictionaryForKey:(id<NSCopying>_Nullable)key default:(NSDictionary * _Nullable)defaultValue;
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@interface UIImage (CocoaDebug)
|
||||
|
||||
//Obtain the GIF image object according to the data data of a GIF image
|
||||
+ (UIImage *_Nullable)imageWithGIFData:(NSData *_Nullable)data;
|
||||
|
||||
//Obtain the GIF image object according to the name of the local GIF image
|
||||
+ (UIImage *_Nullable)imageWithGIFNamed:(NSString *_Nullable)name;
|
||||
|
||||
//Obtain the GIF image object according to the URL of a GIF image
|
||||
+ (void)imageWithGIFUrl:(NSString *_Nullable)url gifImageBlock:(void(^_Nullable)(UIImage *_Nullable gifImage))gifImageBlock;
|
||||
|
||||
@end
|
||||
367
Pods/CocoaDebug/Sources/Categories/NSObject+CocoaDebug.m
generated
Normal file
367
Pods/CocoaDebug/Sources/Categories/NSObject+CocoaDebug.m
generated
Normal file
@@ -0,0 +1,367 @@
|
||||
//
|
||||
// Example
|
||||
// man
|
||||
//
|
||||
// Created by man 11/11/2018.
|
||||
// Copyright © 2020 man. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSObject+CocoaDebug.h"
|
||||
#import <objc/runtime.h>
|
||||
#import <ImageIO/ImageIO.h>
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@implementation NSData (CocoaDebug)
|
||||
|
||||
+ (NSData *)dataWithInputStream:(NSInputStream *)stream
|
||||
{
|
||||
NSMutableData * data = [NSMutableData data];
|
||||
[stream open];
|
||||
NSInteger result;
|
||||
uint8_t buffer[1024]; // BUFFER_LEN can be any positive integer
|
||||
|
||||
while((result = [stream read:buffer maxLength:1024]) != 0) {
|
||||
if (result > 0) {
|
||||
// buffer contains result bytes of data to be handled
|
||||
[data appendBytes:buffer length:result];
|
||||
} else {
|
||||
// The stream had an error. You can get an NSError object using [iStream streamError]
|
||||
if (result < 0) {
|
||||
// [NSException raise:@"STREAM_ERROR" format:@"%@", [stream streamError]];
|
||||
return nil;//liman
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@implementation NSString (CocoaDebug)
|
||||
|
||||
- (CGFloat)heightWithFont:(UIFont *)font constraintToWidth:(CGFloat)width
|
||||
{
|
||||
CGRect rect = [self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
|
||||
|
||||
return rect.size.height;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@implementation NSURLRequest (CocoaDebug)
|
||||
|
||||
- (NSString *)requestId {
|
||||
return objc_getAssociatedObject(self, @"requestId");
|
||||
}
|
||||
|
||||
- (void)setRequestId:(NSString *)requestId {
|
||||
objc_setAssociatedObject(self, @"requestId", requestId, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSNumber*)startTime {
|
||||
return objc_getAssociatedObject(self, @"startTime");
|
||||
}
|
||||
|
||||
- (void)setStartTime:(NSNumber*)startTime {
|
||||
objc_setAssociatedObject(self, @"startTime", startTime, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@implementation UIColor (CocoaDebug)
|
||||
|
||||
+ (UIColor *)colorFromHexString:(NSString *)hexString
|
||||
{
|
||||
unsigned rgbValue = 0;
|
||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||
[scanner setScanLocation:1];
|
||||
[scanner scanHexInt:&rgbValue];
|
||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@implementation NSDictionary (CocoaDebug)
|
||||
|
||||
- (NSString *)_stringForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if (![obj isKindOfClass:[NSString class]]) {
|
||||
return nil;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSArray *)_arrayForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if (![obj isKindOfClass:[NSArray class]]) {
|
||||
return nil;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSDictionary *)_dictionaryForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if (![obj isKindOfClass:[NSDictionary class]]) {
|
||||
return nil;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSInteger)_integerForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if ([obj isKindOfClass:[NSNumber class]]) {
|
||||
return [((NSNumber *)obj) integerValue];
|
||||
}
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return [((NSString *)obj) integerValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int64_t)_int64ForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if ([obj isKindOfClass:[NSNumber class]]) {
|
||||
return [((NSNumber *)obj) longLongValue];
|
||||
}
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return [((NSString *)obj) longLongValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int32_t)_int32ForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if ([obj isKindOfClass:[NSNumber class]]) {
|
||||
return [((NSNumber *)obj) intValue];
|
||||
}
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return [((NSString *)obj) intValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (float)_floatForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if ([obj isKindOfClass:[NSNumber class]]) {
|
||||
return [((NSNumber *)obj) floatValue];
|
||||
}
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return [((NSString *)obj) floatValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (double)_doubleForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if ([obj isKindOfClass:[NSNumber class]]) {
|
||||
return [((NSNumber *)obj) doubleValue];
|
||||
}
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return [((NSString *)obj) doubleValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (BOOL)_boolForKey:(id<NSCopying>)key {
|
||||
id obj = [self objectForKey:key];
|
||||
if ([obj isKindOfClass:[NSNumber class]]) {
|
||||
return [((NSNumber *)obj) boolValue];
|
||||
}
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return [((NSString *)obj) boolValue];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)_stringForKey:(id<NSCopying>)key default:(NSString * _Nullable)defaultValue {
|
||||
id obj = [self objectForKey:key];
|
||||
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
return obj;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
- (bool)_boolForKey:(id<NSCopying>)key default:(bool)defaultValue {
|
||||
id obj = [self objectForKey:key];
|
||||
|
||||
if ([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSString class]]) {
|
||||
return [obj boolValue];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
- (NSInteger)_integerForKey:(id<NSCopying>)key default:(NSInteger)defaultValue {
|
||||
id obj = [self objectForKey:key];
|
||||
|
||||
if ([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSString class]]) {
|
||||
return [obj integerValue];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
- (float)_floatForKey:(id<NSCopying>)key default:(float)defaultValue {
|
||||
id obj = [self objectForKey:key];
|
||||
|
||||
if ([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSString class]]) {
|
||||
return [obj floatValue];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
- (NSArray *)_arrayForKey:(id<NSCopying>)key default:(NSArray * _Nullable)defaultValue {
|
||||
id obj = [self objectForKey:key];
|
||||
|
||||
if ([obj isKindOfClass:[NSArray class]]) {
|
||||
return obj;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
- (NSDictionary *)_dictionaryForKey:(id<NSCopying>)key default:(NSDictionary * _Nullable)defaultValue {
|
||||
id obj = [self objectForKey:key];
|
||||
|
||||
if ([obj isKindOfClass:[NSDictionary class]]) {
|
||||
return obj;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************/
|
||||
|
||||
@implementation UIImage (CocoaDebug)
|
||||
|
||||
//Obtain the GIF image object according to the data data of a GIF image
|
||||
+ (UIImage *_Nullable)imageWithGIFData:(NSData *_Nullable)data {
|
||||
if (!data) return nil;
|
||||
|
||||
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
|
||||
size_t count = CGImageSourceGetCount(source);
|
||||
UIImage *animatedImage;
|
||||
|
||||
if (count <= 1) {
|
||||
animatedImage = [[UIImage alloc] initWithData:data];
|
||||
|
||||
} else {
|
||||
|
||||
NSMutableArray *images = [NSMutableArray array];
|
||||
NSTimeInterval duration = 0.0f;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
|
||||
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
|
||||
|
||||
NSTimeInterval frameDuration = [UIImage ssz_frameDurationAtIndex:i source:source];
|
||||
|
||||
duration += frameDuration;
|
||||
|
||||
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
|
||||
|
||||
CFRelease(image);
|
||||
}
|
||||
|
||||
if (!duration) {
|
||||
duration = (1.0f / 10.0f) * count;
|
||||
}
|
||||
|
||||
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
|
||||
}
|
||||
|
||||
CFRelease(source);
|
||||
|
||||
return animatedImage;
|
||||
}
|
||||
|
||||
//Obtain the GIF image object according to the name of the local GIF image
|
||||
+ (UIImage *_Nullable)imageWithGIFNamed:(NSString *_Nullable)name {
|
||||
NSUInteger scale = (NSUInteger)[UIScreen mainScreen].scale;
|
||||
return [self GIFName:name scale:scale];
|
||||
}
|
||||
|
||||
+ (UIImage *)GIFName:(NSString *)name scale:(NSUInteger)scale {
|
||||
NSString *imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@%zdx", name, scale] ofType:@"gif"];
|
||||
|
||||
if (!imagePath) {
|
||||
(scale + 1 > 3) ? (scale -= 1) : (scale += 1);
|
||||
imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@%zdx", name, scale] ofType:@"gif"];
|
||||
}
|
||||
|
||||
if (imagePath) {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
|
||||
return [UIImage imageWithGIFData:imageData];
|
||||
|
||||
} else {
|
||||
|
||||
imagePath = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
|
||||
|
||||
if (imagePath) {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
|
||||
return [UIImage imageWithGIFData:imageData];
|
||||
|
||||
} else {
|
||||
return [UIImage imageNamed:name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Obtain the GIF image object according to the URL of a GIF image
|
||||
+ (void)imageWithGIFUrl:(NSString *_Nullable)url gifImageBlock:(void(^_Nullable)(UIImage *_Nullable gifImage))gifImageBlock {
|
||||
NSURL *GIFUrl = [NSURL URLWithString:url];
|
||||
|
||||
if (!GIFUrl) return;
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
NSData *CIFData = [NSData dataWithContentsOfURL:GIFUrl];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
gifImageBlock([UIImage imageWithGIFData:CIFData]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+ (float)ssz_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
|
||||
float frameDuration = 0.1f;
|
||||
|
||||
CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
|
||||
NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
|
||||
NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
|
||||
NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
|
||||
|
||||
if (delayTimeUnclampedProp) {
|
||||
frameDuration = [delayTimeUnclampedProp floatValue];
|
||||
|
||||
} else {
|
||||
NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
|
||||
|
||||
if (delayTimeProp) {
|
||||
frameDuration = [delayTimeProp floatValue];
|
||||
}
|
||||
}
|
||||
|
||||
// Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
|
||||
// We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
|
||||
// a duration of <= 10 ms. See and
|
||||
// for more information.
|
||||
|
||||
if (frameDuration < 0.011f) {
|
||||
frameDuration = 0.100f;
|
||||
}
|
||||
|
||||
CFRelease(cfFrameProperties);
|
||||
|
||||
return frameDuration;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user