Compare commits

...

20 Commits

Author SHA1 Message Date
Tanner Bennett 2bfba6715e Fix indentation of these #if's
VS Code handles folding with regex so these need to be indented properly or it will not let you fold the surroudning context
2024-08-25 04:36:28 -05:00
Tanner Bennett 0c87d94b0d Fix some warnings 2024-08-25 04:33:09 -05:00
Sergio Sette 401a94f81b Fix cURL null payload for compressed HTTP bodies 2024-08-25 03:47:50 -05:00
Quan f92dd73442 Add Surmagic surfile 2024-08-25 03:45:07 -05:00
linzuhan 3ccf4b8c59 Fix #672 misaligned UITableView row height 2024-08-25 03:45:07 -05:00
Tanner Bennett e036f964d8 Fix #680, a crash when viewing nil HTTP body 2024-08-25 03:22:43 -05:00
Tanner Bennett a1c3e86ce7 Clean up deprecated APIs 2024-08-25 03:11:44 -05:00
helloworld 079f2d87a5 Fix main branch build error (#703)
Co-authored-by: lichenguang <chenguang.li@mail.dealmoon.com>
2024-06-27 02:53:24 -07:00
Nikolay Morev 462c507df9 Make FLEXFileBrowserController public (#702) 2024-06-19 21:30:34 -05:00
Ata Etgi a19f1acbed fix the crash when opening view debug hierarchy (#700) 2024-06-19 20:50:11 -05:00
Tanner Bennett 1b983160cc Attempt to fix crash in 3D view explorer
+[FHSView drawView:] may crash when the view has 0 width or height
2024-02-28 11:14:34 -08:00
Cao Doan 6616242d9c Migrate NSKeyedArchiver/NSKeyedUnarchiver deprecated APIs (#693) 2024-02-16 01:13:13 -06:00
Mykola (Nickolas) Pokhylets 377a9a5f3f Handle HTTP body which is not a UTF8 text (#684)
Co-authored-by: Mykola Pokhylets <mykola.pokhylets@gmail.com>
2024-02-12 03:38:05 -06:00
Brovko Roman 6f4d9c3ba1 Fix crash in FLEXNetworkObserver (#692)
Thanks @programming086!
2024-02-12 03:33:21 -06:00
Míng 56935533be Supports displaying and searching by accessibilityIdentifier in the Hierarchy view. (#690) 2024-02-05 11:22:46 -06:00
Rob Napier f0b2dc971e Ignore AVAssetDownloadURLSession to avoid crashing. (FLEXTool#276) (#677) 2024-02-03 12:52:06 -06:00
Enrique Garcia 346301b628 Fix Xcode 15 SPM warning related to iOS 12 support (#688) 2024-02-03 12:45:47 -06:00
Ingrid Wang 692146831e Use requiredProperties and optionalProperties in debug description (#687) 2024-01-30 17:31:25 -06:00
Ahmed Hamdy 81f748a33e Fix EXC_BAD_ACCESS in FLEXNetworkObserver (#660)
---------

Co-authored-by: ahmed hamdy <ahamdy@lavad.app>
2023-03-09 18:33:07 -06:00
KeepMoving 038106f954 Fix crash caused by metadata name being nil (#659)
Co-authored-by: linzuhan <lzh267448@alibaba-inc.com>
2023-03-07 21:05:59 -06:00
21 changed files with 213 additions and 83 deletions
@@ -96,7 +96,11 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
self.searchController.searchBar.placeholder = @"Filter";
self.searchController.searchResultsUpdater = (id)self;
self.searchController.delegate = (id)self;
self.searchController.dimsBackgroundDuringPresentation = NO;
if (@available(iOS 9.1, *)) {
self.searchController.obscuresBackgroundDuringPresentation = NO;
} else {
self.searchController.dimsBackgroundDuringPresentation = NO;
}
self.searchController.hidesNavigationBarDuringPresentation = NO;
/// Not necessary in iOS 13; remove this when iOS 13 is the minimum deployment target
self.searchController.searchBar.delegate = self;
@@ -210,6 +214,8 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.estimatedRowHeight = 10;
_shareToolbarItem = FLEXBarButtonItemSystem(Action, self, @selector(shareButtonPressed:));
_bookmarksToolbarItem = [UIBarButtonItem
flex_itemWithImage:FLEXResources.bookmarksIcon target:self action:@selector(showBookmarks)
@@ -46,7 +46,13 @@
UIPickerView *fontsPicker = [UIPickerView new];
fontsPicker.dataSource = self;
fontsPicker.delegate = self;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// Deprecated in iOS 13; from then on, selection is always shown
fontsPicker.showsSelectionIndicator = YES;
#pragma clang diagnostic pop
return fontsPicker;
}
@@ -8,7 +8,6 @@
#import "FLEXTableViewController.h"
#import "FLEXGlobalsEntry.h"
#import "FLEXFileBrowserSearchOperation.h"
@interface FLEXFileBrowserController : FLEXTableViewController <FLEXGlobalsEntry>
@@ -15,6 +15,7 @@
#import "FLEXObjectExplorerFactory.h"
#import "FLEXObjectExplorerViewController.h"
#import <mach-o/loader.h>
#import "FLEXFileBrowserSearchOperation.h"
@interface FLEXFileBrowserTableViewCell : UITableViewCell
@end
@@ -265,14 +266,19 @@ typedef NS_ENUM(NSUInteger, FLEXFileBrowserSortAttribute) {
if ([pathExtension isEqualToString:@"json"]) {
prettyString = [FLEXUtility prettyJSONStringFromData:fileData];
} else {
// Regardless of file extension...
id object = nil;
@try {
// Try to decode an archived object regardless of file extension
object = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
} @catch (NSException *e) { }
// Try to decode an archived object, regardless of file extension
NSKeyedUnarchiver *unarchiver = ({
NSKeyedUnarchiver *obj = nil;
if (@available(iOS 12.0, *)) {
obj = [[NSKeyedUnarchiver alloc] initForReadingFromData:fileData error:nil];
} else {
obj = [[NSKeyedUnarchiver alloc] initForReadingWithData:fileData];
}
obj.requiresSecureCoding = NO;
obj;
});
id object = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
// Try to decode other things instead
object = object ?: [NSPropertyListSerialization
propertyListWithData:fileData
@@ -28,25 +28,26 @@
if (status == errSecSuccess) {//item already exists, update it!
query = [[NSMutableDictionary alloc]init];
query[(__bridge id)kSecValueData] = self.passwordData;
#if __IPHONE_4_0 && TARGET_OS_IPHONE
#if __IPHONE_4_0 && TARGET_OS_IPHONE
CFTypeRef accessibilityType = FLEXKeychain.accessibilityType;
if (accessibilityType) {
query[(__bridge id)kSecAttrAccessible] = (__bridge id)accessibilityType;
}
#endif
#endif
status = SecItemUpdate((__bridge CFDictionaryRef)(searchQuery), (__bridge CFDictionaryRef)(query));
}else if (status == errSecItemNotFound){//item not found, create it!
}
else if (status == errSecItemNotFound){//item not found, create it!
query = [self query];
if (self.label) {
query[(__bridge id)kSecAttrLabel] = self.label;
}
query[(__bridge id)kSecValueData] = self.passwordData;
#if __IPHONE_4_0 && TARGET_OS_IPHONE
#if __IPHONE_4_0 && TARGET_OS_IPHONE
CFTypeRef accessibilityType = FLEXKeychain.accessibilityType;
if (accessibilityType) {
query[(__bridge id)kSecAttrAccessible] = (__bridge id)accessibilityType;
}
#endif
#endif
status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
}
@@ -69,9 +70,9 @@
}
NSMutableDictionary *query = [self query];
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE
status = SecItemDelete((__bridge CFDictionaryRef)query);
#else
#else
// On Mac OS, SecItemDelete will not delete a key created in a different
// app, nor in a different version of the same app.
//
@@ -88,7 +89,7 @@
status = SecKeychainItemDelete((SecKeychainItemRef)result);
CFRelease(result);
}
#endif
#endif
if (status != errSecSuccess && error != NULL) {
*error = [self errorWithCode:status];
@@ -102,12 +103,12 @@
NSMutableDictionary *query = [self query];
query[(__bridge id)kSecReturnAttributes] = @YES;
query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll;
#if __IPHONE_4_0 && TARGET_OS_IPHONE
#if __IPHONE_4_0 && TARGET_OS_IPHONE
CFTypeRef accessibilityType = FLEXKeychain.accessibilityType;
if (accessibilityType) {
query[(__bridge id)kSecAttrAccessible] = (__bridge id)accessibilityType;
}
#endif
#endif
CFTypeRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
@@ -149,19 +150,6 @@
#pragma mark - Accessors
- (void)setPasswordObject:(id<NSCoding>)object {
self.passwordData = [NSKeyedArchiver archivedDataWithRootObject:object];
}
- (id<NSCoding>)passwordObject {
if (self.passwordData.length) {
return [NSKeyedUnarchiver unarchiveObjectWithData:self.passwordData];
}
return nil;
}
- (void)setPassword:(NSString *)password {
self.passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
@@ -181,11 +169,11 @@
#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE
+ (BOOL)isSynchronizationAvailable {
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE
return YES;
#else
#else
return floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4;
#endif
#endif
}
#endif
@@ -204,15 +192,15 @@
dictionary[(__bridge id)kSecAttrAccount] = self.account;
}
#ifdef FLEXKEYCHAIN_ACCESS_GROUP_AVAILABLE
#if !TARGET_IPHONE_SIMULATOR
#ifdef FLEXKEYCHAIN_ACCESS_GROUP_AVAILABLE
#if !TARGET_IPHONE_SIMULATOR
if (self.accessGroup) {
dictionary[(__bridge id)kSecAttrAccessGroup] = self.accessGroup;
}
#endif
#endif
#endif
#endif
#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE
#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE
if ([[self class] isSynchronizationAvailable]) {
id value;
@@ -233,7 +221,7 @@
dictionary[(__bridge id)(kSecAttrSynchronizable)] = value;
}
#endif
#endif
return dictionary;
}
@@ -251,7 +239,7 @@
case errSecSuccess: return nil;
case FLEXKeychainErrorBadArguments: message = NSLocalizedStringFromTableInBundle(@"FLEXKeychainErrorBadArguments", @"FLEXKeychain", resourcesBundle, nil); break;
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE
case errSecUnimplemented: {
message = NSLocalizedStringFromTableInBundle(@"errSecUnimplemented", @"FLEXKeychain", resourcesBundle, nil);
break;
@@ -291,10 +279,10 @@
default: {
message = NSLocalizedStringFromTableInBundle(@"errSecDefault", @"FLEXKeychain", resourcesBundle, nil);
}
#else
#else
default:
message = (__bridge_transfer NSString *)SecCopyErrorMessageString(code, NULL);
#endif
#endif
}
NSDictionary *userInfo = message ? @{ NSLocalizedDescriptionKey : message } : nil;
+1
View File
@@ -0,0 +1 @@
../../Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h
@@ -290,7 +290,8 @@ typedef UIViewController *(^FLEXNetworkDetailRowSelectionFuture)(void);
postBodyRow.selectionFuture = ^UIViewController * () {
// Show the body if we can
NSString *contentType = [transaction.request valueForHTTPHeaderField:@"Content-Type"];
UIViewController *detailViewController = [self detailViewControllerForMIMEType:contentType data:[self postBodyDataForTransaction:transaction]];
NSData *body = [self postBodyDataForTransaction:transaction];
UIViewController *detailViewController = [self detailViewControllerForMIMEType:contentType data:body];
if (detailViewController) {
detailViewController.title = @"Request Body";
return detailViewController;
@@ -298,8 +299,13 @@ typedef UIViewController *(^FLEXNetworkDetailRowSelectionFuture)(void);
// We can't show the body, alert user
return [FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Can't View HTTP Body Data");
make.message(@"FLEX does not have a viewer for request body data with MIME type: ");
if (!body) {
make.title(@"Empty HTTP Body");
} else {
make.title(@"Cannot View HTTP Body Data");
make.message(@"FLEX does not have a viewer for request body data with MIME type: ");
}
make.message(contentType);
make.button(@"Dismiss").cancelStyle();
}];
@@ -482,6 +488,10 @@ typedef UIViewController *(^FLEXNetworkDetailRowSelectionFuture)(void);
}
+ (UIViewController *)detailViewControllerForMIMEType:(NSString *)mimeType data:(NSData *)data {
if (!data) {
return nil; // An alert will be presented in place of this screen
}
FLEXCustomContentViewerFuture makeCustomViewer = FLEXManager.sharedManager.customContentTypeViewers[mimeType.lowercaseString];
if (makeCustomViewer) {
@@ -519,11 +529,8 @@ typedef UIViewController *(^FLEXNetworkDetailRowSelectionFuture)(void);
+ (NSData *)postBodyDataForTransaction:(FLEXHTTPTransaction *)transaction {
NSData *bodyData = transaction.cachedRequestBody;
if (bodyData.length > 0) {
NSString *contentEncoding = [transaction.request valueForHTTPHeaderField:@"Content-Encoding"];
if ([contentEncoding rangeOfString:@"deflate" options:NSCaseInsensitiveSearch].length > 0 || [contentEncoding rangeOfString:@"gzip" options:NSCaseInsensitiveSearch].length > 0) {
bodyData = [FLEXUtility inflatedDataFromCompressedData:bodyData];
}
if (bodyData.length > 0 && [FLEXUtility hasCompressedContentEncoding:transaction.request]) {
bodyData = [FLEXUtility inflatedDataFromCompressedData:bodyData];
}
return bodyData;
}
+17 -2
View File
@@ -6,6 +6,7 @@
//
#import "FLEXNetworkCurlLogger.h"
#import "FLEXUtility.h"
@implementation FLEXNetworkCurlLogger
@@ -28,8 +29,22 @@
}
if (request.HTTPBody) {
NSString *body = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding];
[curlCommandString appendFormat:@"-d \'%@\'", body];
NSData *bodyData = request.HTTPBody;
if ([FLEXUtility hasCompressedContentEncoding:request]) {
bodyData = [FLEXUtility inflatedDataFromCompressedData:bodyData];
}
NSString *body = [[NSString alloc] initWithData:bodyData encoding:NSUTF8StringEncoding];
if (body != nil) {
[curlCommandString appendFormat:@"-d \'%@\'", body];
} else {
// Fallback to using base64 encoding
[curlCommandString appendString:@"--data-binary @-"];
NSString *base64 = [request.HTTPBody base64EncodedStringWithOptions:0];
NSString *prefix = [NSString stringWithFormat:@"echo -n '%@' | base64 -D | ", base64];
[curlCommandString insertString:prefix atIndex:0];
}
}
return curlCommandString;
+1 -1
View File
@@ -90,7 +90,7 @@ typedef NS_ENUM(NSUInteger, FLEXWebsocketMessageDirection) {
@property (nonatomic) NSTimeInterval latency;
@property (nonatomic) NSTimeInterval duration;
/// Populated lazily. Handles both normal HTTPBody data and HTTPBodyStreams.
/// Populated lazily, nullable. Handles both normal HTTPBody data and HTTPBodyStreams.
@property (nonatomic, readonly) NSData *cachedRequestBody;
@end
@@ -23,6 +23,7 @@
#import "FLEXMethod.h"
#import "Firestore.h"
#import <AVFoundation/AVFoundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
#import <dispatch/queue.h>
@@ -237,7 +238,9 @@ static void _logos_method$_ungrouped$FIRDocumentReference$getDocumentWithComplet
FIRDocumentSnapshotBlock orig = completion;
completion = ^(FIRDocumentSnapshot *document, NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRDocumentDidFetch:document error:error transactionID:requestID];
orig(document, error);
if (orig != nil) {
orig(document, error);
}
};
// Forward invocation
@@ -256,7 +259,9 @@ static void _logos_method$_ungrouped$FIRQuery$getDocumentsWithCompletion$(
FIRQuerySnapshotBlock orig = completion;
completion = ^(FIRQuerySnapshot *query, NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRQueryDidFetch:query error:error transactionID:requestID];
orig(query, error);
if (orig != nil) {
orig(query, error);
}
};
// Forward invocation
@@ -285,7 +290,9 @@ static void _logos_method$_ungrouped$FIRDocumentReference$setData$merge$completi
void (^orig)(NSError *) = completion;
completion = ^(NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRDidSetData:error transactionID:requestID];
orig(error);
if (orig != nil) {
orig(error);
}
};
// Forward invocation
@@ -313,7 +320,9 @@ static void _logos_method$_ungrouped$FIRDocumentReference$setData$mergeFields$co
void (^orig)(NSError *) = completion;
completion = ^(NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRDidSetData:error transactionID:requestID];
orig(error);
if (orig != nil) {
orig(error);
}
};
// Forward invocation
@@ -333,7 +342,9 @@ static void _logos_method$_ungrouped$FIRDocumentReference$updateData$completion$
void (^orig)(NSError *) = completion;
completion = ^(NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRDidUpdateData:error transactionID:requestID];
orig(error);
if (orig != nil) {
orig(error);
}
};
// Forward invocation
@@ -353,7 +364,9 @@ static void _logos_method$_ungrouped$FIRDocumentReference$deleteDocumentWithComp
void (^orig)(NSError *) = completion;
completion = ^(NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRDidDeleteDocument:error transactionID:requestID];
orig(error);
if (orig != nil) {
orig(error);
}
};
// Forward invocation
@@ -371,7 +384,9 @@ static FIRDocumentReference * _logos_method$_ungrouped$FIRCollectionReference$ad
void (^orig)(NSError *) = completion;
completion = ^(NSError *error) {
[FLEXNetworkRecorder.defaultRecorder recordFIRDidAddDocument:error transactionID:requestID];
orig(error);
if (orig != nil) {
orig(error);
}
};
// Forward invocation
@@ -652,15 +667,22 @@ static FIRDocumentReference * _logos_method$_ungrouped$FIRCollectionReference$ad
Method originalResume = class_getInstanceMethod(class, selector);
IMP implementation = imp_implementationWithBlock(^(NSURLSessionTask *slf) {
// iOS's internal HTTP parser finalization code is mysteriously not thread safe,
// invoking it asynchronously has a chance to cause a `double free` crash.
// This line below will ask for HTTPBody synchronously, make the HTTPParser
// parse the request, and cache them in advance. After that the HTTPParser
// will be finalized. Make sure other threads inspecting the request
// won't trigger a race to finalize the parser.
[slf.currentRequest HTTPBody];
if (@available(iOS 11.0, *)) {
// AVAggregateAssetDownloadTask deeply does not like to be looked at. Accessing -currentRequest or
// -originalRequest will crash. Do not try to observe these. https://github.com/FLEXTool/FLEX/issues/276
if (![slf isKindOfClass:[AVAggregateAssetDownloadTask class]]) {
// iOS's internal HTTP parser finalization code is mysteriously not thread safe,
// invoking it asynchronously has a chance to cause a `double free` crash.
// This line below will ask for HTTPBody synchronously, make the HTTPParser
// parse the request, and cache them in advance. After that the HTTPParser
// will be finalized. Make sure other threads inspecting the request
// won't trigger a race to finalize the parser.
[slf.currentRequest HTTPBody];
[FLEXNetworkObserver.sharedObserver URLSessionTaskWillResume:slf];
}
}
[FLEXNetworkObserver.sharedObserver URLSessionTaskWillResume:slf];
((void(*)(id, SEL))objc_msgSend)(
slf, swizzledSelector
);
@@ -1965,6 +1987,14 @@ didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data
}
- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task {
if (@available(iOS 11.0, *)) {
// AVAggregateAssetDownloadTask deeply does not like to be looked at. Accessing -currentRequest or
// -originalRequest will crash. Do not try to observe these. https://github.com/FLEXTool/FLEX/issues/276
if ([task isKindOfClass:[AVAggregateAssetDownloadTask class]]) {
return;
}
}
// Since resume can be called multiple times on the same task, only treat the first resume as
// the equivalent to connection:willSendRequest:...
[self performBlock:^{
@@ -353,6 +353,10 @@
if ([names containsObject:name]) {
return NO;
} else {
if (!name) {
return NO;
}
[names addObject:name];
// Skip methods and properties which are just overrides,
+1
View File
@@ -51,6 +51,7 @@
+ (NSString *)prettyJSONStringFromData:(NSData *)data;
+ (BOOL)isValidJSONData:(NSData *)data;
+ (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData;
+ (BOOL)hasCompressedContentEncoding:(NSURLRequest *)request;
// Swizzling utilities
+9 -3
View File
@@ -14,7 +14,7 @@
#import <objc/runtime.h>
#import <zlib.h>
BOOL FLEXConstructorsShouldRun() {
BOOL FLEXConstructorsShouldRun(void) {
#if FLEX_DISABLE_CTORS
return NO;
#else
@@ -100,8 +100,9 @@ BOOL FLEXConstructorsShouldRun() {
description = [description stringByAppendingFormat:@" %@", [self stringForCGRect:view.frame]];
}
if (view.accessibilityLabel.length > 0) {
description = [description stringByAppendingFormat:@" · %@", view.accessibilityLabel];
if (view.accessibilityLabel.length > 0 || view.accessibilityIdentifier.length > 0) {
description = [description stringByAppendingFormat:@" · %@",
view.accessibilityLabel.length > 0 ? view.accessibilityLabel : view.accessibilityIdentifier];
}
return description;
@@ -412,6 +413,11 @@ BOOL FLEXConstructorsShouldRun() {
return inflatedData;
}
+ (BOOL)hasCompressedContentEncoding:(NSURLRequest *)request {
NSString *contentEncoding = [request valueForHTTPHeaderField:@"Content-Encoding"];
return ([contentEncoding rangeOfString:@"deflate" options:NSCaseInsensitiveSearch].length > 0 || [contentEncoding rangeOfString:@"gzip" options:NSCaseInsensitiveSearch].length > 0);
}
+ (NSArray<UIWindow *> *)allWindows {
BOOL includeInternalWindows = YES;
BOOL onlyVisibleWindows = NO;
@@ -29,7 +29,7 @@
self.textView.backgroundColor = UIColor.blackColor;
self.textView.textColor = UIColor.whiteColor;
self.textView.font = [UIFont boldSystemFontOfSize:14.0];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.title = @"Simulator Shortcuts";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)];
@@ -19,7 +19,7 @@ CFSetRef FLEXKnownUnsafeIvars = nil;
(class_getInstanceVariable([cls class], name) ?: (void *)kCFNull)
__attribute__((constructor))
static void FLEXRuntimeSafteyInit() {
static void FLEXRuntimeSafteyInit(void) {
FLEXKnownUnsafeClasses = CFSetCreate(
kCFAllocatorDefault,
(const void **)(uintptr_t)FLEXKnownUnsafeClassList(),
@@ -39,7 +39,7 @@ static void FLEXRuntimeSafteyInit() {
);
}
const Class * FLEXKnownUnsafeClassList() {
const Class * FLEXKnownUnsafeClassList(void) {
if (!_UnsafeClasses) {
const Class ignored[] = {
FLEXClassPointerOrCFNull(@"__ARCLite__"),
@@ -74,7 +74,7 @@ const Class * FLEXKnownUnsafeClassList() {
return _UnsafeClasses;
}
NSSet * FLEXKnownUnsafeClassNames() {
NSSet * FLEXKnownUnsafeClassNames(void) {
static NSSet *set = nil;
if (!set) {
NSArray *ignored = @[
@@ -52,9 +52,15 @@
}
- (NSString *)debugDescription {
return [NSString stringWithFormat:@"<%@ name=%@, %lu properties, %lu required methods, %lu optional methods, %lu protocols>",
if (@available(iOS 10.0, *)) {
return [NSString stringWithFormat:@"<%@ name=%@, %lu required properties, %lu optional properties %lu required methods, %lu optional methods, %lu protocols>",
NSStringFromClass(self.class), self.name, (unsigned long)self.requiredProperties.count, (unsigned long)self.optionalProperties.count,
(unsigned long)self.requiredMethods.count, (unsigned long)self.optionalMethods.count, (unsigned long)self.protocols.count];
} else {
return [NSString stringWithFormat:@"<%@ name=%@, %lu properties, %lu required methods, %lu optional methods, %lu protocols>",
NSStringFromClass(self.class), self.name, (unsigned long)self.properties.count,
(unsigned long)self.requiredMethods.count, (unsigned long)self.optionalMethods.count, (unsigned long)self.protocols.count];
}
}
- (void)examine {
@@ -88,8 +88,19 @@
@implementation FHSView (Snapshotting)
+ (UIImage *)drawView:(UIView *)view {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
if (CGRectIsEmpty(view.bounds)) {
return [UIImage new];
}
CGSize size = view.bounds.size;
CGFloat minUnit = 1.f / UIScreen.mainScreen.scale;
// Every drawn view must not have 0 width or height
CGSize minsize = CGSizeMake(MAX(size.width, minUnit), MAX(size.height, minUnit));
CGRect minBounds = CGRectMake(0, 0, minsize.width, minsize.height);
UIGraphicsBeginImageContextWithOptions(minsize, NO, 0);
[view drawViewHierarchyInRect:minBounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
+2 -1
View File
@@ -53,6 +53,7 @@ Pod::Spec.new do |spec|
"Classes/Utility/FLEXResources.h",
"Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h",
"Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h",
"Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
"Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h",
"Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h"
]
end
+3 -1
View File
@@ -7,7 +7,9 @@ enum FLEXBuildOptions {
static let silenceWarnings = false
}
#if swift(>=5.7)
#if swift(>=5.9)
let platforms: [PackageDescription.SupportedPlatform] = [.iOS(.v12)]
#elseif swift(>=5.7)
let platforms: [PackageDescription.SupportedPlatform] = [.iOS(.v11)]
#else
let platforms: [PackageDescription.SupportedPlatform] = [.iOS(.v10)]
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>output_path</key>
<string>build</string>
<key>framework</key>
<string>FLEX</string>
<key>targets</key>
<array>
<dict>
<key>sdk</key>
<string>iOS</string>
<key>project</key>
<string>FLEX.xcodeproj</string>
<key>scheme</key>
<string>FLEX</string>
</dict>
<dict>
<key>sdk</key>
<string>iOSSimulator</string>
<key>project</key>
<string>FLEX.xcodeproj</string>
<key>scheme</key>
<string>FLEX</string>
</dict>
<!--
Remove this comment and add more targets for Simulators and the Devices.
-->
</array>
<key>finalActions</key>
<array>
<string>openDirectory</string>
</array>
</dict>
</plist>
+5
View File
@@ -33,6 +33,10 @@ generate_headers() {
# "Classes/ObjectExplorers/**/*.h", "Classes/Editing/**/*.h",
# "Classes/Utility/FLEXMacros.h", "Classes/Utility/Categories/*.h",
# "Classes/Utility/FLEXAlert.h", "Classes/Utility/FLEXResources.h"
# "Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h",
# "Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h",
# "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h",
# "Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h"
rm -rf Classes/Headers
mkdir -p Classes/Headers
@@ -58,6 +62,7 @@ makeheader "Classes/Utility/FLEXResources.h"
makeheader "Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h"
makeheader "Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h"
makeheader "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
makeheader "Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h"
# Print all folders in Classes for use in Package.swift
for folder in `find "Classes" -type d`; do