Compare commits

..

135 Commits

Author SHA1 Message Date
Tanner Bennett cf1c33a400 Gotta have this 2023-01-17 03:16:52 -08:00
Tanner Bennett 4bc797458a Hope this works!
Fix imports
2023-01-17 03:16:52 -08:00
Tanner Bennett 09570e3598 Update paths constructor code 2023-01-17 03:16:46 -08:00
Tanner Bennett 89d07a14e1 Add wip bazel support
Sigh
2023-01-17 02:41:17 -08:00
Emil Pedersen 1bbf8dbea1 Locale aware animation speed parsing (#642) 2022-12-09 03:33:07 -06:00
Tanner Bennett 343eba92b6 Finally fix the order of these buttons 2022-12-05 18:09:13 -06:00
Tanner Bennett d6232baf03 Give user opportunity to edit bad queries 2022-12-05 18:09:13 -06:00
Tanner Bennett 9808b89d6d Enable preferred actions with FLEXAlert 2022-12-05 17:55:40 -06:00
Asif de1cbfae4a Fix response body not in cache issue (#640) 2022-11-29 20:34:19 -08:00
Tanner Bennett b036fb18a5 Make class sizes only populate instansiated classes 2022-11-29 16:52:29 -06:00
Tanner Bennett c6ed5098cf Xcode 14 upgrade check 2022-11-22 04:02:40 -06:00
Tanner Bennett d7283cd22d Add FLEXHeapSnapshot 2022-11-22 04:02:14 -06:00
Tanner Bennett 785e181d75 Move subclassesOfClassWithName: to FLEXRuntimeUtility 2022-11-22 04:02:07 -06:00
Tanner Bennett dd66f46a7b Add docs to some APIs 2022-11-22 04:01:28 -06:00
Tanner Bennett 55bae8b53e Make some new headers public; fix #636 2022-11-22 03:14:39 -06:00
Tanner Bennett 5edca3fdad Update Reflex dependency URL; fix #617 2022-11-22 02:56:50 -06:00
Tanner Bennett 9bc319a38e Refine FLEXWindow level; fix #541 2022-11-22 02:47:03 -06:00
Tanner Bennett deac628b06 None of these should be optional 2022-11-04 21:19:16 -05:00
Tanner Bennett 8e44d88c36 Remove social_media_url 2022-10-30 03:09:14 -05:00
Tanner Bennett 73e4a712e8 Refine shouldReceiveTouchAtWindowPoint: logic 2022-10-20 12:50:48 -05:00
Tanner Bennett 9e1f60b2f4 "Recent" button should be disabled in presentation 2022-10-20 12:50:48 -05:00
Tanner Bennett 3c385143ee Use half sheet on iOS 15+ 2022-10-20 12:50:48 -05:00
Tanner Bennett e0acf59d06 Bump version; no longer using semantic versioning
Now versioned using `marketing-year-month`
2022-10-20 12:41:01 -05:00
Tanner Bennett f00af28418 Big brain refactor 2022-10-20 12:29:21 -05:00
Tanner Bennett 2bd809ae6c Xcode 14 2022-10-20 12:29:21 -05:00
Tanner Bennett 003b8f88e8 Add FLEXObjectRef.debugDescription 2022-10-20 12:29:21 -05:00
Tanner Bennett 5e780e6d0c Fix UIButton selection view on iOS 16 2022-10-20 12:29:21 -05:00
Tanner Bennett 17ea4976c1 Fix potential retain cycle 2022-10-10 23:10:51 -04:00
Tanner Bennett fbda722f11 Fix bug in supportedInterfaceOrientations 2022-10-09 02:39:44 -04:00
Iulian Onofrei b351b788d5 Fix error-prone FLEX exclusion from release instruction (#630) 2022-10-07 11:39:45 -04:00
Tanner Bennett a195840b67 I don't think this actually fixes anything but oh well 2022-10-06 23:01:31 -04:00
Tanner Bennett 9b946dda5d Fix crash when deleting last blacklisted host 2022-10-06 23:00:47 -04:00
Tanner Bennett 806cdc6acb Compatibility fix for new version of Theos 2022-10-06 00:13:10 -04:00
Tanner Bennett aadfc69f01 Add FLEXWindowShortcuts to project 2022-10-06 00:07:01 -04:00
Tanner Bennett 6e0135d4a0 Fix #627 2022-10-01 15:32:23 -05:00
Tanner Bennett 2599a1eb0d dogs.realm was not being included in example app 2022-10-01 15:32:23 -05:00
AnthoPak c96df6d35c Allow changing UIWindow's animation speed (#629) 2022-09-26 17:20:15 -05:00
Tanner Bennett fff3059099 Use keyboard WILL show events 🚀🚀🚀 2022-09-21 19:32:30 -05:00
Tanner Bennett 4bee6d17bc Silence some totally valid availability warnings 2022-09-21 19:26:43 -05:00
Tanner Bennett 3d8a12027b Ignore SPM build folder 2022-09-21 19:26:43 -05:00
Natheer bc96542856 Move FLEX out of the way of the keyboard (#623) 2022-09-21 19:02:01 -05:00
Jerry.Qiushi 24526a6a0a Podspec: update xcconfig to pod_target_xcconfig (#626) 2022-09-21 17:20:04 -05:00
Pierre-Yves B d33d909fa0 Add missing NSDateFormatter extension to SPM headers (#616) 2022-08-31 15:29:41 -05:00
Chaoshuai Lü 0a9db69419 Use queue instead of self.queue in FLEXNetworkRecorder.m 2022-08-30 11:58:56 -07:00
Tanner Bennett 2db78c3bef APNS: hook correct UNUNCenterDelegate method 2022-08-27 16:37:04 -05:00
Sergo Beruashvili 1b91bc963e Call missing websocket completion (#609)
Co-authored-by: Sergo Beruashvili <sergo.beruashvili@daimler.com>
2022-08-10 02:45:23 -07:00
Enrique Garcia 56d90748cb Fix Xcode 14 SPM warning related to iOS 11 support (#610) 2022-07-31 15:25:59 -05:00
Tanner Bennett 9997721e0a Display the device token as bytes, and tap to copy 2022-07-25 17:45:06 -05:00
Tanner Bennett bedbd0b8c8 FLEXAlert: shortcut to present a temporary alert 2022-07-25 17:44:50 -05:00
Tanner Bennett cb64c88c59 Polish notification hooks
They'll crash if the method is unimplemented; I forgot these methods are all optional
2022-07-25 17:28:16 -05:00
Tanner Bennett be733c30cb Use summary instead of description for remote notifs 2022-07-25 01:51:33 -05:00
Tanner Bennett e46d26034b Flatten intendations in descriptions 2022-07-25 01:51:19 -05:00
Tanner Bennett 3809ece1f9 Distinguish between remote and user notifications
Also change how we get app delegate class
2022-07-24 23:55:52 -05:00
Tanner Bennett b2410750fd Wrap NSDateFormatter 2022-07-24 23:55:52 -05:00
Tanner Bennett 72ccd007b3 APNS: hook Swift UIApplicationMain shim as well 2022-07-24 23:55:52 -05:00
helloworld 4375f1a67f Fix iOS 16 _statusBarWindow crash (#607)
Co-authored-by: ClownFish <15800960640@163.com>
2022-07-05 22:56:00 -05:00
Tanner Bennett 393a43754c Misc 2022-07-02 02:20:26 -05:00
Tanner Bennett b56d6f6d33 Add FLEXAPNSViewController for viewing push notifs 2022-07-02 02:20:26 -05:00
Tanner Bennett 0d985b504b Add auto keyword 2022-07-02 02:20:26 -05:00
Tanner Bennett 148890914d Add nullability specifiers to FLEXSingleRowSection 2022-06-27 18:39:49 -05:00
Tanner Bennett c734ad16e5 Just a lil something for the demo app 2022-06-27 18:39:25 -05:00
Tanner Bennett ac6301437b SPM project: _MSSafeMode env var 2022-06-27 18:39:07 -05:00
Tanner Bennett b45c655ba2 Hopefully fix #574 2022-06-27 18:38:05 -05:00
Tanner Bennett 83fe11210e Fix crash in FLEXFirebaseSetDataInfo 2022-06-12 01:26:42 -05:00
Tanner Bennett e80e3bb5b7 Add API to push explorer on any UINavigationController 2022-05-26 21:31:49 -05:00
Tanner Bennett 833b8e7534 Add APIs to programmatically present …
- an object explorer
- an arbitrary view controller

from FLEXManager
2022-05-26 14:45:18 -05:00
Tanner Bennett 56e8693c41 Add NSPhotoLibraryUsageDescription to example 2022-05-26 14:20:05 -05:00
Tanner Bennett 49eeb28464 Don't load tweaks when debugging the example app 2022-05-26 14:19:55 -05:00
Tanner Bennett a24d752313 Fix UIActivityViewController dismissing presenter 2022-05-26 14:19:35 -05:00
Tanner Bennett 643523a779 Add FLEXActivityViewController 2022-05-26 14:19:15 -05:00
Tanner Bennett 65744675db Fix tabs not being closed in some instances 2022-05-26 12:53:29 -05:00
Chaoshuai Lü f994346919 Match Availability versions for FLEXTableViewSection 2022-05-12 13:46:05 -07:00
Chaoshuai Lü a7a8b8e33e Fix warnings
* Fix -Wobjc-signed-char-bool-implicit-int-conversion in FLEXSwiftInternal
* Fix -Wparentheses
2022-05-11 23:19:37 -05:00
Tanner Bennett f254720408 Display dlopen errors 2022-04-27 23:45:32 -05:00
Tanner Bennett e6fd5ed24e Fix bug in new FLEXMirror usage 2022-04-27 13:45:42 -05:00
Tanner Bennett d13f263492 Update SPM example deps 2022-04-27 13:45:42 -05:00
Tanner Bennett ba36647398 Enable displaying ivar names for custom struct types
FLEXMetadataExtras.h
2022-04-27 13:45:42 -05:00
Tanner Bennett 9d97533649 Make CommitDetails a struct to demo Reflex 2022-04-27 13:45:42 -05:00
Tanner Bennett 96b13e66b6 Podspec: gnu++11 2022-04-27 13:45:42 -05:00
Tanner Bennett 9712a4c869 Delete modulemap 2022-04-27 13:45:42 -05:00
Tanner Bennett 8f9956308f Use Reflex instead of FLEX in SPM project 2022-04-27 13:45:42 -05:00
Tanner Bennett 69e88acbee Initialize FLEXObjectExplorer.reflexAvailable 2022-04-27 13:45:42 -05:00
Tanner Bennett 07587986df Use Reflex and FLEXMirror 2022-04-27 13:45:42 -05:00
Tanner Bennett e6641a5f9d Add FLEXSwiftInternal to check if object from Swift 2022-04-27 13:45:42 -05:00
Tanner Bennett 111fb6c9e6 Modernize FLEXMirror
Differentiate between class and instance props/methods
2022-04-27 13:45:42 -05:00
Tanner Bennett 995e7eadbe Add (unused) libflex modulemap file
For my own use case, I dynamically link FLEX, so I need to build Reflex using libflex.tbd as well as this modulemap file.
2022-04-27 13:45:42 -05:00
Tanner Bennett ac50a6d36b Bump version 2022-04-27 13:45:41 -05:00
Tanner Bennett af40ce0909 Fix annoying divider color in editor screens 2022-04-27 13:43:40 -05:00
matrush fb2a33876e Add FLEXTableRowDataViewController for viewing DB rows 2022-04-24 16:30:43 -07:00
Tanner Bennett a42efe17a1 Use host instead of self here 2022-04-24 16:30:43 -07:00
Tanner Bennett 4bc2d1c7a9 Shorten some line lengths 2022-04-24 14:48:47 -07:00
weiminghuaa c7ebecfcb3 Re-filter system log when new messages arrive 2022-04-24 14:48:47 -07:00
weiminghuaa 208f0a31e4 Pin seach bar in system log 2022-04-24 14:48:47 -07:00
Tanner Bennett 2aeb34a67e Cherry pick #592 2022-04-24 16:23:15 -05:00
Tanner Bennett 39f16bd039 Make properties atomic in hopes of resolving #574 2022-04-24 16:23:00 -05:00
Tanner Bennett eea681d6c5 Consolidate duplicate code 2022-04-24 16:22:08 -05:00
Tanner Bennett a8768da4b9 Fix crash where FIRDocumentSnapshot response is nil 2022-04-24 16:15:34 -05:00
Tanner Bennett 4f6fd29d38 Clean up FLEXMITMDataSource interface 2022-04-23 18:45:24 -05:00
Canius Chu ba9cb43b6a Fix compile errors and warnings (#597)
* Update INSTALL_PATH
* Update run path
* Add FLEXFirebaseTransaction.mm into project which break in commit: d2e0db8773
* Fix header imports
* Rollback LD_RUNPATH_SEARCH_PATHS
2022-04-23 18:12:17 -05:00
Tanner Bennett 3af6da8554 Format _manuallyDeactivateSearchOnDisappear 2022-04-23 18:12:17 -05:00
Chaoshuai Lü 6c21395ac8 Fix self.allTransactions race condition in FLEXMITMDataSource
There is a crash caused by this because of race condition. Here we can simply make a copy of the transaction and it will be used and released properly even within the block.
2022-03-30 20:55:19 -07:00
Chaoshuai Lü 456fda31cd Add fallback column query support when PRAGMA table_info is not working (#573)
* Add fallback column queries support when PRAGMA table_info is not working

* Switch to check columnCount instead of rowsAffected

* Use SELECT * FROM pragma_table_info('%@')

Fallback to SELECT * FROM table where 0=1

Co-authored-by: Tanner Bennett <tannerbennett@me.com>
2022-03-30 20:23:55 -07:00
Chaoshuai Lü 9fc8735925 Check rowIDs instead of rowIDs.count to validate input 2022-03-30 23:16:07 -04:00
Tanner Bennett 9683acbe4f Ignore workspace files 2022-03-28 20:55:31 -07:00
Tanner Bennett 86a1cc9324 Remove DEVELOPMENT_TEAM 2022-03-28 20:55:15 -07:00
Tanner Bennett 88b14b3a92 Escape text for webview on a background thread 2022-03-28 20:54:34 -07:00
Tanner Bennett b9cd2682a7 Clean up web vc file 2022-03-28 20:43:48 -07:00
Nick Holub 64d1534fae Add accessibilityIdentifier and accessibilityLabel to views properties 2022-03-22 15:53:57 -07:00
Chaoshuai Lü 8318902826 Fix -Wobjc-signed-char-bool-implicit-int-conversion issue in FLEXNavigationController
This should be checked explicitly to shut up the warning.
2022-03-08 03:16:34 -08:00
Chaoshuai Lu a7f41fe5fc Mark some firebase related functions as static to avoid warnings 2022-03-03 03:14:38 -06:00
Tanner Bennett 2983649cdb Show descriptions of complex FIRQuery objects 2021-12-25 03:27:58 -06:00
Tanner Bennett d2e0db8773 Move FLEXFirebaseTransaction to own file 2021-12-24 22:03:55 -06:00
Tanner Bennett fd98070166 Fix #499, thank you @zhaogyrain 2021-12-24 19:41:52 -06:00
Hossam Ghareeb 4a9fd00eda Add option to copy row as CSV
This will make it easier to insert a new row
2021-12-24 19:35:53 -06:00
Tanner Bennett 97205fc808 Fix bug in rowid selection
`SELECT rowid` returns rowids corresponding to rows in a different order than `SELECT *`. We will now order the rowids in ascending order to match the order of `SELECT *`.

Previously, the mismatched order would mean deleting a row in the UI might delete a different row.
2021-12-24 19:32:01 -06:00
Tanner Bennett 0cffe72a8f Add more assertions to FLEXTableContentVC 2021-12-24 19:32:01 -06:00
Tanner Bennett d5ab2ee916 Revise copy for FLEXTableContentVC add row screen 2021-12-24 19:32:01 -06:00
Tanner Bennett 90c9a48694 Only allow deleting rows if we have a table name 2021-12-24 19:32:01 -06:00
Tanner Bennett 0222c682a0 Improve FLEXTableContentVC toolbar button logic
Only allow adding rows or deleting rows if we have a table name
2021-12-24 19:32:01 -06:00
Tanner Bennett 1e6f6ee110 Clean up FLEXTableContentVC initializers 2021-12-24 19:32:01 -06:00
Hossam Ghareeb 00d6b348f0 Adding an option to add a row in DB table
Added a new toolbar button to insert a new row. Tapping on the button will show an alert to write the values as a comma separated string which will be added in an INSERT statement to be executed.
2021-12-24 19:32:01 -06:00
Tanner Bennett 5404f37d0f Remember the last selected network observer tab 2021-12-24 19:30:18 -06:00
Tanner Bennett 1e539c7129 Pin network history search bar
This works around an ugly visual glitch that happens when the segmented control is visible
2021-12-24 19:30:18 -06:00
Tanner Bennett ca1b202949 For now, just show the transaction object directly 2021-12-24 19:30:18 -06:00
Tanner Bennett 62220a9a65 Record Firebase document creation 2021-12-24 19:30:18 -06:00
Tanner Bennett 02730c6c86 Allow clearing only filtered requests 2021-12-24 19:30:18 -06:00
Tanner Bennett 68789fbe1d Allow filtering Firebase requests with push/pull 2021-12-24 19:30:18 -06:00
Tanner Bennett b4261f8647 Add description for Firebase transaction "push" type 2021-12-24 19:30:18 -06:00
Tanner Bennett 94bf4eac2a Record "push" Firebase network transaction types 2021-12-23 01:35:17 -06:00
Tanner Bennett bed52392e5 Add new Firebase network transaction types 2021-12-23 01:35:17 -06:00
Tanner Bennett c4891840bd Wrap some method names 2021-12-23 01:35:17 -06:00
Tanner Bennett 9720227ac7 Fix logic in network observer mode property 2021-12-23 01:35:17 -06:00
Tanner Bennett 74622aaf10 Initial work for Firebase 2021-12-23 01:35:17 -06:00
Tanner Bennett 0cb5ad8453 Restore -Wno-deprecated-declarations 2021-12-23 01:35:09 -06:00
Chaoshuai Lu def68eae48 Remove unneeded edgesForExtendedLayout setting
Update FLEXTableContentViewController.m

Remove empty lines/spaces changes
2021-12-05 15:29:30 -08:00
317 changed files with 3927 additions and 1314 deletions
+3
View File
@@ -20,3 +20,6 @@ DerivedData
/Example/Pods
Podfile.lock
IDEWorkspaceChecks.plist
*.xcworkspace
.build
bazel-*
+51
View File
@@ -0,0 +1,51 @@
FLEX_PUBLIC_HDRS = glob([
"Classes/*.h",
"Classes/Manager/*.h",
"Classes/Toolbar/*.h",
"Classes/Core/**/*.h",
"Classes/Utility/Runtime/Objc/**/*.h",
"Classes/Utility/Runtime/Objc/*.h",
"Classes/ObjectExplorers/**/*.h",
"Classes/Editing/**/*.h",
"Classes/GlobalStateExplorers/**/*.h",
"Classes/Utility/Categories/*.h",
], [
"**/FLEX.h"
], allow_empty = False
) + [
"Classes/Utility/FLEXMacros.h",
"Classes/Utility/FLEXAlert.h",
"Classes/Utility/FLEXResources.h",
"Classes/Utility/FLEXHeapEnumerator.h"
]
objc_library(
name = "FLEX",
module_name = "FLEX",
hdrs = FLEX_PUBLIC_HDRS,
srcs = glob([
"Classes/**/*.m",
"Classes/**/*.mm",
"Classes/**/*.c",
"Classes/**/*.h"
], FLEX_PUBLIC_HDRS, allow_empty = False),
sdk_dylibs = [
"libz",
"libsqlite3"
],
sdk_frameworks = [
"Foundation",
"UIKit",
"CoreGraphics",
"ImageIO",
"QuartzCore",
"WebKit",
"Security",
"SceneKit"
],
copts = [
"-Wno-deprecated-declarations",
"-Wno-unsupported-availability-guard"
],
visibility = ["//visibility:public"]
)
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
#import "Classes/Headers/FLEXTableViewController.h"
#pragma mark - FLEXTableViewFiltering
@protocol FLEXTableViewFiltering <FLEXSearchResultsUpdating>
@@ -6,10 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXFilteringTableViewController.h"
#import "FLEXTableViewSection.h"
#import "NSArray+FLEX.h"
#import "FLEXMacros.h"
#import "Classes/Headers/FLEXFilteringTableViewController.h"
#import "Classes/Headers/FLEXTableViewSection.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/Utility/FLEXMacros.h"
@interface FLEXFilteringTableViewController ()
@@ -16,4 +16,13 @@ NS_ASSUME_NONNULL_BEGIN
@end
@interface UINavigationController (FLEXObjectExploring)
/// Push an object explorer view controller onto the navigation stack
- (void)pushExplorerForObject:(id)object;
/// Push an object explorer view controller onto the navigation stack
- (void)pushExplorerForObject:(id)object animated:(BOOL)animated;
@end
NS_ASSUME_NONNULL_END
@@ -6,9 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXNavigationController.h"
#import "FLEXExplorerViewController.h"
#import "FLEXTabList.h"
#import "Classes/Headers/FLEXNavigationController.h"
#import "Classes/ExplorerInterface/FLEXExplorerViewController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabList.h"
@interface UINavigationController (Private) <UIGestureRecognizerDelegate>
- (void)_gestureRecognizedInteractiveHide:(UIGestureRecognizer *)sender;
@@ -28,7 +29,8 @@
@implementation FLEXNavigationController
+ (instancetype)withRootViewController:(UIViewController *)rootVC {
return [[self alloc] initWithRootViewController:rootVC];
FLEXNavigationController *nav = [[self alloc] initWithRootViewController:rootVC];
return nav;
}
- (void)viewDidLoad {
@@ -65,6 +67,17 @@
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (@available(iOS 15.0, *)) {
UISheetPresentationController *presenter = self.sheetPresentationController;
presenter.detents = @[
UISheetPresentationControllerDetent.mediumDetent,
UISheetPresentationControllerDetent.largeDetent,
];
presenter.prefersScrollingExpandsWhenScrolledToEdge = NO;
presenter.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge;
presenter.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge;
}
if (self.beingPresented && !self.didSetupPendingDismissButtons) {
for (UIViewController *vc in self.viewControllers) {
[self addNavigationBarItemsToViewController:vc.navigationItem];
@@ -93,6 +106,13 @@
[self addNavigationBarItemsToViewController:viewController.navigationItem];
}
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
// Workaround for UIActivityViewController trying to dismiss us for some reason
if (![self.viewControllers.lastObject.presentedViewController isKindOfClass:UIActivityViewController.self]) {
[super dismissViewControllerAnimated:flag completion:completion];
}
}
- (void)dismissAnimated {
// Tabs are only closed if the done button is pressed; this
// allows you to leave a tab open by dragging down to dismiss
@@ -104,7 +124,7 @@
}
- (BOOL)canShowToolbar {
return self.topViewController.toolbarItems.count;
return self.topViewController.toolbarItems.count > 0;
}
- (void)addNavigationBarItemsToViewController:(UINavigationItem *)navigationItem {
@@ -194,3 +214,18 @@
}
@end
@implementation UINavigationController (FLEXObjectExploring)
- (void)pushExplorerForObject:(id)object {
[self pushExplorerForObject:object animated:YES];
}
- (void)pushExplorerForObject:(id)object animated:(BOOL)animated {
UIViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:object];
if (explorer) {
[self pushViewController:explorer animated:animated];
}
}
@end
@@ -7,7 +7,7 @@
//
#import <UIKit/UIKit.h>
#import "FLEXTableView.h"
#import "Classes/Headers/FLEXTableView.h"
@class FLEXScopeCarousel, FLEXWindow, FLEXTableViewSection;
typedef CGFloat FLEXDebounceInterval;
@@ -6,15 +6,15 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
#import "FLEXExplorerViewController.h"
#import "FLEXBookmarksViewController.h"
#import "FLEXTabsViewController.h"
#import "FLEXScopeCarousel.h"
#import "FLEXTableView.h"
#import "FLEXUtility.h"
#import "FLEXResources.h"
#import "UIBarButtonItem+FLEX.h"
#import "Classes/Headers/FLEXTableViewController.h"
#import "Classes/ExplorerInterface/FLEXExplorerViewController.h"
#import "Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabsViewController.h"
#import "Classes/Core/Views/Carousel/FLEXScopeCarousel.h"
#import "Classes/Headers/FLEXTableView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/FLEXResources.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
#import <objc/runtime.h>
@interface Block : NSObject
@@ -66,9 +66,9 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
_searchBarDebounceInterval = kFLEXDebounceFast;
_showSearchBarInitially = YES;
_style = style;
_manuallyDeactivateSearchOnDisappear = ({
NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11;
});
_manuallyDeactivateSearchOnDisappear = (
NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11
);
// We will be our own search delegate if we implement this method
if ([self respondsToSelector:@selector(updateSearchResults:)]) {
+9 -5
View File
@@ -6,7 +6,9 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewSection.h"
#import "Classes/Headers/FLEXTableViewSection.h"
NS_ASSUME_NONNULL_BEGIN
/// A section providing a specific single row.
///
@@ -16,13 +18,15 @@
@interface FLEXSingleRowSection : FLEXTableViewSection
/// @param reuseIdentifier if nil, kFLEXDefaultCell is used.
+ (instancetype)title:(NSString *)sectionTitle
reuse:(NSString *)reuseIdentifier
+ (instancetype)title:(nullable NSString *)sectionTitle
reuse:(nullable NSString *)reuseIdentifier
cell:(void(^)(__kindof UITableViewCell *cell))cellConfiguration;
@property (nonatomic) UIViewController *pushOnSelection;
@property (nonatomic) void (^selectionAction)(UIViewController *host);
@property (nullable, nonatomic) UIViewController *pushOnSelection;
@property (nullable, nonatomic) void (^selectionAction)(UIViewController *host);
/// Called to determine whether the single row should display itself or not.
@property (nonatomic) BOOL (^filterMatcher)(NSString *filterText);
@end
NS_ASSUME_NONNULL_END
+4 -2
View File
@@ -6,8 +6,8 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXSingleRowSection.h"
#import "FLEXTableView.h"
#import "Classes/Headers/FLEXSingleRowSection.h"
#import "Classes/Headers/FLEXTableView.h"
@interface FLEXSingleRowSection ()
@property (nonatomic, readonly) NSString *reuseIdentifier;
@@ -30,6 +30,8 @@
- (id)initWithTitle:(NSString *)sectionTitle
reuse:(NSString *)reuseIdentifier
cell:(void (^)(__kindof UITableViewCell *))cellConfiguration {
NSParameterAssert(cellConfiguration);
self = [super init];
if (self) {
_title = sectionTitle;
+1 -1
View File
@@ -7,7 +7,7 @@
//
#import <UIKit/UIKit.h>
#import "NSArray+FLEX.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
@class FLEXTableView;
NS_ASSUME_NONNULL_BEGIN
+5 -5
View File
@@ -6,10 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewSection.h"
#import "FLEXTableView.h"
#import "FLEXUtility.h"
#import "UIMenu+FLEX.h"
#import "Classes/Headers/FLEXTableViewSection.h"
#import "Classes/Headers/FLEXTableView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/Categories/UIMenu+FLEX.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
@@ -79,7 +79,7 @@
return @"";
}
- (NSArray<UIMenuElement *> *)menuItemsForRow:(NSInteger)row sender:(UIViewController *)sender API_AVAILABLE(ios(13)) {
- (NSArray<UIMenuElement *> *)menuItemsForRow:(NSInteger)row sender:(UIViewController *)sender API_AVAILABLE(ios(13.0)) {
NSArray<NSString *> *copyItems = [self copyMenuItemsForRow:row];
NSAssert(copyItems.count % 2 == 0, @"copyMenuItemsForRow: should return an even list");
@@ -6,9 +6,9 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXCarouselCell.h"
#import "FLEXColor.h"
#import "UIView+FLEX_Layout.h"
#import "Classes/Core/Views/Carousel/FLEXCarouselCell.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Utility/Categories/Private/UIView+FLEX_Layout.h"
@interface FLEXCarouselCell ()
@property (nonatomic, readonly) UILabel *titleLabel;
@@ -6,11 +6,11 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXScopeCarousel.h"
#import "FLEXCarouselCell.h"
#import "FLEXColor.h"
#import "FLEXMacros.h"
#import "UIView+FLEX_Layout.h"
#import "Classes/Core/Views/Carousel/FLEXScopeCarousel.h"
#import "Classes/Core/Views/Carousel/FLEXCarouselCell.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Utility/FLEXMacros.h"
#import "Classes/Utility/Categories/Private/UIView+FLEX_Layout.h"
const CGFloat kCarouselItemSpacing = 0;
NSString * const kCarouselCellReuseIdentifier = @"kCarouselCellReuseIdentifier";
+1 -1
View File
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXMultilineTableViewCell.h"
#import "Classes/Headers/FLEXMultilineTableViewCell.h"
NS_ASSUME_NONNULL_BEGIN
+2 -2
View File
@@ -6,8 +6,8 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXCodeFontCell.h"
#import "UIFont+FLEX.h"
#import "Classes/Headers/FLEXCodeFontCell.h"
#import "Classes/Utility/Categories/UIFont+FLEX.h"
@implementation FLEXCodeFontCell
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
#import "Classes/Headers/FLEXTableViewCell.h"
@interface FLEXKeyValueTableViewCell : FLEXTableViewCell
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXKeyValueTableViewCell.h"
#import "Classes/Headers/FLEXKeyValueTableViewCell.h"
@implementation FLEXKeyValueTableViewCell
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
#import "Classes/Headers/FLEXTableViewCell.h"
/// A cell with both labels set to be multi-line capable.
@interface FLEXMultilineTableViewCell : FLEXTableViewCell
@@ -6,9 +6,9 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXMultilineTableViewCell.h"
#import "UIView+FLEX_Layout.h"
#import "FLEXUtility.h"
#import "Classes/Headers/FLEXMultilineTableViewCell.h"
#import "Classes/Utility/Categories/Private/UIView+FLEX_Layout.h"
#import "Classes/Utility/FLEXUtility.h"
@interface FLEXMultilineTableViewCell ()
@property (nonatomic, readonly) UILabel *_titleLabel;
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
#import "Classes/Headers/FLEXTableViewCell.h"
/// A cell initialized with \c UITableViewCellStyleSubtitle
@interface FLEXSubtitleTableViewCell : FLEXTableViewCell
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXSubtitleTableViewCell.h"
#import "Classes/Headers/FLEXSubtitleTableViewCell.h"
@implementation FLEXSubtitleTableViewCell
+4 -4
View File
@@ -6,10 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
#import "FLEXUtility.h"
#import "FLEXColor.h"
#import "FLEXTableView.h"
#import "Classes/Headers/FLEXTableViewCell.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Headers/FLEXTableView.h"
@interface UITableView (Internal)
// Exists at least since iOS 5
+6 -6
View File
@@ -6,12 +6,12 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableView.h"
#import "FLEXUtility.h"
#import "FLEXSubtitleTableViewCell.h"
#import "FLEXMultilineTableViewCell.h"
#import "FLEXKeyValueTableViewCell.h"
#import "FLEXCodeFontCell.h"
#import "Classes/Headers/FLEXTableView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Headers/FLEXSubtitleTableViewCell.h"
#import "Classes/Headers/FLEXMultilineTableViewCell.h"
#import "Classes/Headers/FLEXKeyValueTableViewCell.h"
#import "Classes/Headers/FLEXCodeFontCell.h"
FLEXTableViewCellReuseIdentifier const kFLEXDefaultCell = @"kFLEXDefaultCell";
FLEXTableViewCellReuseIdentifier const kFLEXDetailCell = @"kFLEXDetailCell";
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
@interface FLEXArgumentInputColorView : FLEXArgumentInputView
@@ -6,9 +6,9 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputColorView.h"
#import "FLEXUtility.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
@protocol FLEXColorComponentInputViewDelegate;
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
@interface FLEXArgumentInputDateView : FLEXArgumentInputView
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputDateView.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
@interface FLEXArgumentInputDateView ()
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
@interface FLEXArgumentInputFontView : FLEXArgumentInputView
@@ -6,10 +6,10 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputFontView.h"
#import "FLEXArgumentInputViewFactory.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXArgumentInputFontsPickerView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h"
@interface FLEXArgumentInputFontView ()
@@ -6,7 +6,7 @@
// Copyright (c) 2014年 f. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h"
@interface FLEXArgumentInputFontsPickerView : FLEXArgumentInputTextView <UIPickerViewDataSource, UIPickerViewDelegate>
@end
@@ -6,8 +6,8 @@
// Copyright (c) 2014年 f. All rights reserved.
//
#import "FLEXArgumentInputFontsPickerView.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
@interface FLEXArgumentInputFontsPickerView ()
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h"
@interface FLEXArgumentInputNotSupportedView : FLEXArgumentInputTextView
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputNotSupportedView.h"
#import "FLEXColor.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h"
#import "Classes/Utility/FLEXColor.h"
@implementation FLEXArgumentInputNotSupportedView
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h"
@interface FLEXArgumentInputNumberView : FLEXArgumentInputTextView
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputNumberView.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
@implementation FLEXArgumentInputNumberView
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h"
@interface FLEXArgumentInputObjectView : FLEXArgumentInputTextView
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputObjectView.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
static const CGFloat kSegmentInputMargin = 10;
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h"
@interface FLEXArgumentInputStringView : FLEXArgumentInputTextView
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputStringView.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
@implementation FLEXArgumentInputStringView
@@ -6,8 +6,11 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
@interface FLEXArgumentInputStructView : FLEXArgumentInputView
/// Enable displaying ivar names for custom struct types
+ (void)registerFieldNames:(NSArray<NSString *> *)names forTypeEncoding:(NSString *)typeEncoding;
@end
@@ -6,10 +6,10 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputStructView.h"
#import "FLEXArgumentInputViewFactory.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXTypeEncodingParser.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.h"
@interface FLEXArgumentInputStructView ()
@@ -19,6 +19,41 @@
@implementation FLEXArgumentInputStructView
static NSMutableDictionary<NSString *, NSArray<NSString *> *> *structFieldNameRegistrar = nil;
+ (void)initialize {
if (self == [FLEXArgumentInputStructView class]) {
structFieldNameRegistrar = [NSMutableDictionary new];
[self registerDefaultFieldNames];
}
}
+ (void)registerDefaultFieldNames {
NSDictionary *defaults = @{
@(@encode(CGRect)): @[@"CGPoint origin", @"CGSize size"],
@(@encode(CGPoint)): @[@"CGFloat x", @"CGFloat y"],
@(@encode(CGSize)): @[@"CGFloat width", @"CGFloat height"],
@(@encode(CGVector)): @[@"CGFloat dx", @"CGFloat dy"],
@(@encode(UIEdgeInsets)): @[@"CGFloat top", @"CGFloat left", @"CGFloat bottom", @"CGFloat right"],
@(@encode(UIOffset)): @[@"CGFloat horizontal", @"CGFloat vertical"],
@(@encode(NSRange)): @[@"NSUInteger location", @"NSUInteger length"],
@(@encode(CATransform3D)): @[@"CGFloat m11", @"CGFloat m12", @"CGFloat m13", @"CGFloat m14",
@"CGFloat m21", @"CGFloat m22", @"CGFloat m23", @"CGFloat m24",
@"CGFloat m31", @"CGFloat m32", @"CGFloat m33", @"CGFloat m34",
@"CGFloat m41", @"CGFloat m42", @"CGFloat m43", @"CGFloat m44"],
@(@encode(CGAffineTransform)): @[@"CGFloat a", @"CGFloat b",
@"CGFloat c", @"CGFloat d",
@"CGFloat tx", @"CGFloat ty"],
};
[structFieldNameRegistrar addEntriesFromDictionary:defaults];
if (@available(iOS 11.0, *)) {
structFieldNameRegistrar[@(@encode(NSDirectionalEdgeInsets))] = @[
@"CGFloat top", @"CGFloat leading", @"CGFloat bottom", @"CGFloat trailing"
];
}
}
- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding {
self = [super initWithArgumentTypeEncoding:typeEncoding];
if (self) {
@@ -181,40 +216,13 @@
return NO;
}
+ (void)registerFieldNames:(NSArray<NSString *> *)names forTypeEncoding:(NSString *)typeEncoding {
NSParameterAssert(typeEncoding); NSParameterAssert(names);
structFieldNameRegistrar[typeEncoding] = names;
}
+ (NSArray<NSString *> *)customFieldTitlesForTypeEncoding:(const char *)typeEncoding {
NSArray<NSString *> *customTitles = nil;
if (strcmp(typeEncoding, @encode(CGRect)) == 0) {
customTitles = @[@"CGPoint origin", @"CGSize size"];
} else if (strcmp(typeEncoding, @encode(CGPoint)) == 0) {
customTitles = @[@"CGFloat x", @"CGFloat y"];
} else if (strcmp(typeEncoding, @encode(CGSize)) == 0) {
customTitles = @[@"CGFloat width", @"CGFloat height"];
} else if (strcmp(typeEncoding, @encode(CGVector)) == 0) {
customTitles = @[@"CGFloat dx", @"CGFloat dy"];
} else if (strcmp(typeEncoding, @encode(UIEdgeInsets)) == 0) {
customTitles = @[@"CGFloat top", @"CGFloat left", @"CGFloat bottom", @"CGFloat right"];
} else if (strcmp(typeEncoding, @encode(UIOffset)) == 0) {
customTitles = @[@"CGFloat horizontal", @"CGFloat vertical"];
} else if (strcmp(typeEncoding, @encode(NSRange)) == 0) {
customTitles = @[@"NSUInteger location", @"NSUInteger length"];
} else if (strcmp(typeEncoding, @encode(CATransform3D)) == 0) {
customTitles = @[@"CGFloat m11", @"CGFloat m12", @"CGFloat m13", @"CGFloat m14",
@"CGFloat m21", @"CGFloat m22", @"CGFloat m23", @"CGFloat m24",
@"CGFloat m31", @"CGFloat m32", @"CGFloat m33", @"CGFloat m34",
@"CGFloat m41", @"CGFloat m42", @"CGFloat m43", @"CGFloat m44"];
} else if (strcmp(typeEncoding, @encode(CGAffineTransform)) == 0) {
customTitles = @[@"CGFloat a", @"CGFloat b",
@"CGFloat c", @"CGFloat d",
@"CGFloat tx", @"CGFloat ty"];
} else {
if (@available(iOS 11.0, *)) {
if (strcmp(typeEncoding, @encode(NSDirectionalEdgeInsets)) == 0) {
customTitles = @[@"CGFloat top", @"CGFloat leading",
@"CGFloat bottom", @"CGFloat trailing"];
}
}
}
return customTitles;
return structFieldNameRegistrar[@(typeEncoding)];
}
@end
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
@interface FLEXArgumentInputSwitchView : FLEXArgumentInputView
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputSwitchView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h"
@interface FLEXArgumentInputSwitchView ()
@@ -6,7 +6,7 @@
//
//
#import "FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
@interface FLEXArgumentInputTextView : FLEXArgumentInputView <UITextViewDelegate>
@@ -6,9 +6,9 @@
//
//
#import "FLEXColor.h"
#import "FLEXArgumentInputTextView.h"
#import "FLEXUtility.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h"
#import "Classes/Utility/FLEXUtility.h"
@interface FLEXArgumentInputTextView ()
@@ -6,9 +6,9 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import "FLEXUtility.h"
#import "FLEXColor.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/FLEXColor.h"
@interface FLEXArgumentInputView ()
@@ -7,7 +7,7 @@
//
#import <Foundation/Foundation.h>
#import "FLEXArgumentInputSwitchView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h"
@interface FLEXArgumentInputViewFactory : NSObject
@@ -21,4 +21,7 @@
/// Useful when deciding whether to edit or explore a property, ivar, or NSUserDefaults value.
+ (BOOL)canEditFieldWithTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue;
/// Enable displaying ivar names for custom struct types
+ (void)registerFieldNames:(NSArray<NSString *> *)names forTypeEncoding:(NSString *)typeEncoding;
@end
+17 -12
View File
@@ -6,18 +6,18 @@
//
//
#import "FLEXArgumentInputViewFactory.h"
#import "FLEXArgumentInputView.h"
#import "FLEXArgumentInputObjectView.h"
#import "FLEXArgumentInputNumberView.h"
#import "FLEXArgumentInputSwitchView.h"
#import "FLEXArgumentInputStructView.h"
#import "FLEXArgumentInputNotSupportedView.h"
#import "FLEXArgumentInputStringView.h"
#import "FLEXArgumentInputFontView.h"
#import "FLEXArgumentInputColorView.h"
#import "FLEXArgumentInputDateView.h"
#import "FLEXRuntimeUtility.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
@implementation FLEXArgumentInputViewFactory
@@ -67,4 +67,9 @@
return [self argumentInputViewSubclassForTypeEncoding:typeEncoding currentValue:currentValue] != nil;
}
/// Enable displaying ivar names for custom struct types
+ (void)registerFieldNames:(NSArray<NSString *> *)names forTypeEncoding:(NSString *)typeEncoding {
[FLEXArgumentInputStructView registerFieldNames:names forTypeEncoding:typeEncoding];
}
@end
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXFieldEditorViewController.h"
#import "Classes/Editing/FLEXFieldEditorViewController.h"
NS_ASSUME_NONNULL_BEGIN
@@ -6,11 +6,11 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXDefaultEditorViewController.h"
#import "FLEXFieldEditorView.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXArgumentInputView.h"
#import "FLEXArgumentInputViewFactory.h"
#import "Classes/Editing/FLEXDefaultEditorViewController.h"
#import "Classes/Editing/FLEXFieldEditorView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
@interface FLEXDefaultEditorViewController ()
+5 -4
View File
@@ -6,9 +6,10 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXFieldEditorView.h"
#import "FLEXArgumentInputView.h"
#import "FLEXUtility.h"
#import "Classes/Editing/FLEXFieldEditorView.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/FLEXColor.h"
@interface FLEXFieldEditorView ()
@@ -122,7 +123,7 @@
}
+ (UIColor *)dividerColor {
return UIColor.lightGrayColor;
return FLEXColor.tertiaryBackgroundColor;
}
+ (CGFloat)horizontalPadding {
@@ -6,9 +6,9 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXVariableEditorViewController.h"
#import "FLEXProperty.h"
#import "FLEXIvar.h"
#import "Classes/Editing/FLEXVariableEditorViewController.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.h"
NS_ASSUME_NONNULL_BEGIN
+29 -10
View File
@@ -6,17 +6,19 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXFieldEditorViewController.h"
#import "FLEXFieldEditorView.h"
#import "FLEXArgumentInputViewFactory.h"
#import "FLEXPropertyAttributes.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXUtility.h"
#import "FLEXColor.h"
#import "UIBarButtonItem+FLEX.h"
#import "Classes/Editing/FLEXFieldEditorViewController.h"
#import "Classes/Editing/FLEXFieldEditorView.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXMetadataExtras.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
@interface FLEXFieldEditorViewController () <FLEXArgumentInputViewDelegate>
@property (nonatomic, readonly) id<FLEXMetadataAuxiliaryInfo> auxiliaryInfoProvider;
@property (nonatomic) FLEXProperty *property;
@property (nonatomic) FLEXIvar *ivar;
@@ -30,14 +32,14 @@
#pragma mark - Initialization
+ (instancetype)target:(id)target property:(nonnull FLEXProperty *)property commitHandler:(void(^_Nullable)(void))onCommit {
+ (instancetype)target:(id)target property:(nonnull FLEXProperty *)property commitHandler:(void(^)(void))onCommit {
FLEXFieldEditorViewController *editor = [self target:target data:property commitHandler:onCommit];
editor.title = [@"Property: " stringByAppendingString:property.name];
editor.property = property;
return editor;
}
+ (instancetype)target:(id)target ivar:(nonnull FLEXIvar *)ivar commitHandler:(void(^_Nullable)(void))onCommit {
+ (instancetype)target:(id)target ivar:(nonnull FLEXIvar *)ivar commitHandler:(void(^)(void))onCommit {
FLEXFieldEditorViewController *editor = [self target:target data:ivar commitHandler:onCommit];
editor.title = [@"Ivar: " stringByAppendingString:ivar.name];
editor.ivar = ivar;
@@ -61,6 +63,8 @@
self.toolbarItems = @[
UIBarButtonItem.flex_flexibleSpace, self.getterButton, self.actionButton
];
[self registerAuxiliaryInfo];
// Configure input view
self.fieldEditorView.fieldDescription = self.fieldDescription;
@@ -122,6 +126,17 @@
#pragma mark - Private
- (void)registerAuxiliaryInfo {
// This is how Reflex will get Swift struct field names into the editor at runtime
NSDictionary<NSString *, NSArray *> *labels = [self.auxiliaryInfoProvider
auxiliaryInfoForKey:FLEXAuxiliarynfoKeyFieldLabels
];
for (NSString *type in labels) {
[FLEXArgumentInputViewFactory registerFieldNames:labels[type] forTypeEncoding:type];
}
}
- (id)currentValue {
if (self.property) {
return [self.property getValue:self.target];
@@ -130,6 +145,10 @@
}
}
- (id<FLEXMetadataAuxiliaryInfo>)auxiliaryInfoProvider {
return self.ivar ?: self.property;
}
- (const FLEXTypeEncoding *)typeEncoding {
if (self.property) {
return self.property.attributes.typeEncoding.UTF8String;
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXVariableEditorViewController.h"
#import "FLEXMethod.h"
#import "Classes/Editing/FLEXVariableEditorViewController.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.h"
@interface FLEXMethodCallingViewController : FLEXVariableEditorViewController
@@ -6,14 +6,14 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXMethodCallingViewController.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXFieldEditorView.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXObjectExplorerViewController.h"
#import "FLEXArgumentInputView.h"
#import "FLEXArgumentInputViewFactory.h"
#import "FLEXUtility.h"
#import "Classes/Editing/FLEXMethodCallingViewController.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Editing/FLEXFieldEditorView.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Headers/FLEXObjectExplorerViewController.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
#import "Classes/Utility/FLEXUtility.h"
@interface FLEXMethodCallingViewController ()
@property (nonatomic, readonly) FLEXMethod *method;
@@ -6,16 +6,16 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXColor.h"
#import "FLEXVariableEditorViewController.h"
#import "FLEXFieldEditorView.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXUtility.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXArgumentInputView.h"
#import "FLEXArgumentInputViewFactory.h"
#import "FLEXObjectExplorerViewController.h"
#import "UIBarButtonItem+FLEX.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Editing/FLEXVariableEditorViewController.h"
#import "Classes/Editing/FLEXFieldEditorView.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h"
#import "Classes/Editing/FLEXArgumentInputViewFactory.h"
#import "Classes/Headers/FLEXObjectExplorerViewController.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
@interface FLEXVariableEditorViewController () <UIScrollViewDelegate>
@property (nonatomic) UIScrollView *scrollView;
@@ -37,7 +37,7 @@
_commitHandler = onCommit;
[NSNotificationCenter.defaultCenter
addObserver:self selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil
name:UIKeyboardWillShowNotification object:nil
];
[NSNotificationCenter.defaultCenter
addObserver:self selector:@selector(keyboardWillHide:)
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXBookmarkManager.h"
#import "Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.h"
static NSMutableArray *kFLEXBookmarkManagerBookmarks = nil;
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
#import "Classes/Headers/FLEXTableViewController.h"
NS_ASSUME_NONNULL_BEGIN
@@ -6,16 +6,16 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXBookmarksViewController.h"
#import "FLEXExplorerViewController.h"
#import "FLEXNavigationController.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXBookmarkManager.h"
#import "UIBarButtonItem+FLEX.h"
#import "FLEXColor.h"
#import "FLEXUtility.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXTableView.h"
#import "Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.h"
#import "Classes/ExplorerInterface/FLEXExplorerViewController.h"
#import "Classes/Headers/FLEXNavigationController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Headers/FLEXTableView.h"
@interface FLEXBookmarksViewController ()
@property (nonatomic, copy) NSArray *bookmarks;
@@ -6,7 +6,7 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXExplorerToolbar.h"
#import "Classes/Headers/FLEXExplorerToolbar.h"
@class FLEXWindow;
@protocol FLEXExplorerViewControllerDelegate;
@@ -6,21 +6,21 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXExplorerViewController.h"
#import "FLEXExplorerToolbarItem.h"
#import "FLEXUtility.h"
#import "FLEXWindow.h"
#import "FLEXTabList.h"
#import "FLEXNavigationController.h"
#import "FLEXHierarchyViewController.h"
#import "FLEXGlobalsViewController.h"
#import "FLEXObjectExplorerViewController.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXNetworkMITMViewController.h"
#import "FLEXTabsViewController.h"
#import "FLEXWindowManagerController.h"
#import "FLEXViewControllersViewController.h"
#import "NSUserDefaults+FLEX.h"
#import "Classes/ExplorerInterface/FLEXExplorerViewController.h"
#import "Classes/Headers/FLEXExplorerToolbarItem.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/ExplorerInterface/FLEXWindow.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabList.h"
#import "Classes/Headers/FLEXNavigationController.h"
#import "Classes/ViewHierarchy/FLEXHierarchyViewController.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.h"
#import "Classes/Headers/FLEXObjectExplorerViewController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Network/FLEXNetworkMITMViewController.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabsViewController.h"
#import "Classes/ExplorerInterface/FLEXWindowManagerController.h"
#import "Classes/ExplorerInterface/FLEXViewControllersViewController.h"
#import "Classes/Utility/Categories/NSUserDefaults+FLEX.h"
typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
FLEXExplorerModeDefault,
@@ -129,6 +129,14 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
if (@available(iOS 10.0, *)) {
_selectionFBG = [UISelectionFeedbackGenerator new];
}
// Observe keyboard to move self out of the way
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(keyboardShown:)
name:UIKeyboardWillShowNotification
object:nil
];
}
- (void)viewWillAppear:(BOOL)animated {
@@ -162,7 +170,10 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
UIViewController *viewControllerToAsk = [self viewControllerForRotationAndOrientation];
UIInterfaceOrientationMask supportedOrientations = FLEXUtility.infoPlistSupportedInterfaceOrientationsMask;
if (viewControllerToAsk && ![viewControllerToAsk isKindOfClass:[self class]]) {
// We check its class by name because using isKindOfClass will fail for the same class defined
// twice in the runtime; and the goal here is to avoid calling -supportedInterfaceOrientations
// recursively when I'm inspecting FLEX with itself from a tweak dylib
if (viewControllerToAsk && ![NSStringFromClass([viewControllerToAsk class]) hasPrefix:@"FLEX"]) {
supportedOrientations = [viewControllerToAsk supportedInterfaceOrientations];
}
@@ -375,6 +386,21 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
return [self.view convertRect:frameInWindow fromView:nil];
}
- (void)keyboardShown:(NSNotification *)notif {
CGRect keyboardFrame = [notif.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect toolbarFrame = self.explorerToolbar.frame;
if (CGRectGetMinY(keyboardFrame) < CGRectGetMaxY(toolbarFrame)) {
toolbarFrame.origin.y = keyboardFrame.origin.y - toolbarFrame.size.height;
// Subtract a little more, to ignore accessory input views
toolbarFrame.origin.y -= 50;
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0.5
options:UIViewAnimationOptionCurveEaseOut animations:^{
[self updateToolbarPositionWithUnconstrainedFrame:toolbarFrame];
} completion:nil];
}
}
#pragma mark - Toolbar Buttons
@@ -403,8 +429,12 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
}
- (UIWindow *)statusWindow {
NSString *statusBarString = [NSString stringWithFormat:@"%@arWindow", @"_statusB"];
return [UIApplication.sharedApplication valueForKey:statusBarString];
if (!@available(iOS 16, *)) {
NSString *statusBarString = [NSString stringWithFormat:@"%@arWindow", @"_statusB"];
return [UIApplication.sharedApplication valueForKey:statusBarString];
}
return nil;
}
- (void)recentButtonTapped:(FLEXExplorerToolbarItem *)sender {
@@ -436,7 +466,11 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
toolbar.moveItem.selected = self.currentMode == FLEXExplorerModeMove;
// Recent only enabled when we have a last active tab
toolbar.recentItem.enabled = FLEXTabList.sharedList.activeTab != nil;
if (!self.presentedViewController) {
toolbar.recentItem.enabled = FLEXTabList.sharedList.activeTab != nil;
} else {
toolbar.recentItem.enabled = NO;
}
}
@@ -818,31 +852,34 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
#pragma mark - Touch Handling
- (BOOL)shouldReceiveTouchAtWindowPoint:(CGPoint)pointInWindowCoordinates {
BOOL shouldReceiveTouch = NO;
CGPoint pointInLocalCoordinates = [self.view convertPoint:pointInWindowCoordinates fromView:nil];
// Always if it's on the toolbar
if (CGRectContainsPoint(self.explorerToolbar.frame, pointInLocalCoordinates)) {
shouldReceiveTouch = YES;
// If we have a modal presented, is it in the modal?
if (self.presentedViewController) {
UIView *presentedView = self.presentedViewController.view;
CGPoint pipvc = [presentedView convertPoint:pointInLocalCoordinates fromView:self.view];
UIView *hit = [presentedView hitTest:pipvc withEvent:nil];
if (hit != nil) {
return YES;
}
}
// Always if we're in selection mode
if (!shouldReceiveTouch && self.currentMode == FLEXExplorerModeSelect) {
shouldReceiveTouch = YES;
if (self.currentMode == FLEXExplorerModeSelect) {
return YES;
}
// Always in move mode too
if (!shouldReceiveTouch && self.currentMode == FLEXExplorerModeMove) {
shouldReceiveTouch = YES;
if (self.currentMode == FLEXExplorerModeMove) {
return YES;
}
// Always if we have a modal presented
if (!shouldReceiveTouch && self.presentedViewController) {
shouldReceiveTouch = YES;
// Always if it's on the toolbar
if (CGRectContainsPoint(self.explorerToolbar.frame, pointInLocalCoordinates)) {
return YES;
}
return shouldReceiveTouch;
return NO;
}
@@ -888,8 +925,14 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
// up in case we start replacing them again in the future
self.appMenuItems = UIMenuController.sharedMenuController.menuItems;
[self updateButtonStates];
// Show the view controller
[super presentViewController:toPresent animated:animated completion:completion];
[super presentViewController:toPresent animated:animated completion:^{
[self updateButtonStates];
if (completion) completion();
}];
}
- (void)dismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion {
@@ -910,7 +953,11 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
[self updateButtonStates];
[super dismissViewControllerAnimated:animated completion:completion];
[super dismissViewControllerAnimated:animated completion:^{
[self updateButtonStates];
if (completion) completion();
}];
}
- (BOOL)wantsWindowToBecomeKey {
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXFilteringTableViewController.h"
#import "Classes/Headers/FLEXFilteringTableViewController.h"
NS_ASSUME_NONNULL_BEGIN
@@ -6,10 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXViewControllersViewController.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXMutableListSection.h"
#import "FLEXUtility.h"
#import "Classes/ExplorerInterface/FLEXViewControllersViewController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Headers/FLEXMutableListSection.h"
#import "Classes/Utility/FLEXUtility.h"
@interface FLEXViewControllersViewController ()
@property (nonatomic, readonly) FLEXMutableListSection *section;
+4 -9
View File
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXWindow.h"
#import "FLEXUtility.h"
#import "Classes/ExplorerInterface/FLEXWindow.h"
#import "Classes/Utility/FLEXUtility.h"
#import <objc/runtime.h>
@implementation FLEXWindow
@@ -18,18 +18,13 @@
// Some apps have windows at UIWindowLevelStatusBar + n.
// If we make the window level too high, we block out UIAlertViews.
// There's a balance between staying above the app's windows and staying below alerts.
// UIWindowLevelStatusBar + 100 seems to hit that balance.
self.windowLevel = UIWindowLevelStatusBar + 100.0;
self.windowLevel = UIWindowLevelAlert - 1;
}
return self;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
BOOL pointInside = NO;
if ([self.eventDelegate shouldHandleTouchAtPoint:point]) {
pointInside = [super pointInside:point withEvent:event];
}
return pointInside;
return [self.eventDelegate shouldHandleTouchAtPoint:point];
}
- (BOOL)shouldAffectStatusBarAppearance {
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
#import "Classes/Headers/FLEXTableViewController.h"
NS_ASSUME_NONNULL_BEGIN
@@ -6,10 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXWindowManagerController.h"
#import "FLEXManager+Private.h"
#import "FLEXUtility.h"
#import "FLEXObjectExplorerFactory.h"
#import "Classes/ExplorerInterface/FLEXWindowManagerController.h"
#import "Classes/Manager/Private/FLEXManager+Private.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
@interface FLEXWindowManagerController ()
@property (nonatomic) UIWindow *keyWindow;
+12 -2
View File
@@ -6,8 +6,8 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTabList.h"
#import "FLEXUtility.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabList.h"
#import "Classes/Utility/FLEXUtility.h"
@interface FLEXTabList () {
NSMutableArray *_openTabs;
@@ -84,6 +84,16 @@
if (idx != NSNotFound) {
[self closeTabAtIndex:idx];
}
// Not sure how this is possible, but it happens sometimes
if (self.activeTab == tab) {
[self chooseNewActiveTab];
}
// It is possible for an object explorer to form a retain cycle
// with its own navigation controller; clearing the view controllers
// manually when closing a tab breaks the cycle
tab.viewControllers = @[];
}
- (void)closeTabAtIndex:(NSInteger)idx {
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
#import "Classes/Headers/FLEXTableViewController.h"
@interface FLEXTabsViewController : FLEXTableViewController
@@ -6,17 +6,17 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTabsViewController.h"
#import "FLEXNavigationController.h"
#import "FLEXTabList.h"
#import "FLEXBookmarkManager.h"
#import "FLEXTableView.h"
#import "FLEXUtility.h"
#import "FLEXColor.h"
#import "UIBarButtonItem+FLEX.h"
#import "FLEXExplorerViewController.h"
#import "FLEXGlobalsViewController.h"
#import "FLEXBookmarksViewController.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabsViewController.h"
#import "Classes/Headers/FLEXNavigationController.h"
#import "Classes/ExplorerInterface/Tabs/FLEXTabList.h"
#import "Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.h"
#import "Classes/Headers/FLEXTableView.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
#import "Classes/ExplorerInterface/FLEXExplorerViewController.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.h"
#import "Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.h"
@interface FLEXTabsViewController ()
@property (nonatomic, copy) NSArray<UINavigationController *> *openTabs;
+12 -13
View File
@@ -6,17 +6,16 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
#import "Classes/Utility/Categories/CALayer+FLEX.h"
#import "Classes/Utility/Categories/UIFont+FLEX.h"
#import "Classes/Utility/Categories/UIGestureRecognizer+Blocks.h"
#import "Classes/Utility/Categories/UIPasteboard+FLEX.h"
#import "Classes/Utility/Categories/UIMenu+FLEX.h"
#import "Classes/Utility/Categories/UITextField+Range.h"
#import <UIBarButtonItem+FLEX.h>
#import <CALayer+FLEX.h>
#import <UIFont+FLEX.h>
#import <UIGestureRecognizer+Blocks.h>
#import <UIPasteboard+FLEX.h>
#import <UIMenu+FLEX.h>
#import <UITextField+Range.h>
#import <NSObject+FLEX_Reflection.h>
#import <NSArray+FLEX.h>
#import <NSUserDefaults+FLEX.h>
#import <NSTimer+FLEX.h>
#import "Classes/Utility/Categories/NSObject+FLEX_Reflection.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/Utility/Categories/NSUserDefaults+FLEX.h"
#import "Classes/Utility/Categories/NSTimer+FLEX.h"
#import "Classes/Utility/Categories/NSDateFormatter+FLEX.h"
+11 -11
View File
@@ -6,17 +6,17 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <FLEXFilteringTableViewController.h>
#import <FLEXNavigationController.h>
#import <FLEXTableViewController.h>
#import <FLEXTableView.h>
#import "Classes/Headers/FLEXFilteringTableViewController.h"
#import "Classes/Headers/FLEXNavigationController.h"
#import "Classes/Headers/FLEXTableViewController.h"
#import "Classes/Headers/FLEXTableView.h"
#import <FLEXSingleRowSection.h>
#import <FLEXTableViewSection.h>
#import "Classes/Headers/FLEXSingleRowSection.h"
#import "Classes/Headers/FLEXTableViewSection.h"
#import <FLEXCodeFontCell.h>
#import <FLEXSubtitleTableViewCell.h>
#import <FLEXTableViewCell.h>
#import <FLEXMultilineTableViewCell.h>
#import <FLEXKeyValueTableViewCell.h>
#import "Classes/Headers/FLEXCodeFontCell.h"
#import "Classes/Headers/FLEXSubtitleTableViewCell.h"
#import "Classes/Headers/FLEXTableViewCell.h"
#import "Classes/Headers/FLEXMultilineTableViewCell.h"
#import "Classes/Headers/FLEXKeyValueTableViewCell.h"
+11 -11
View File
@@ -6,17 +6,17 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <FLEXObjectExplorerFactory.h>
#import <FLEXObjectExplorerViewController.h>
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Headers/FLEXObjectExplorerViewController.h"
#import <FLEXObjectExplorer.h>
#import "Classes/Headers/FLEXObjectExplorer.h"
#import <FLEXShortcut.h>
#import <FLEXShortcutsSection.h>
#import "Classes/Headers/FLEXShortcut.h"
#import "Classes/Headers/FLEXShortcutsSection.h"
#import <FLEXCollectionContentSection.h>
#import <FLEXColorPreviewSection.h>
#import <FLEXDefaultsContentSection.h>
#import <FLEXMetadataSection.h>
#import <FLEXMutableListSection.h>
#import <FLEXObjectInfoSection.h>
#import "Classes/Headers/FLEXCollectionContentSection.h"
#import "Classes/Headers/FLEXColorPreviewSection.h"
#import "Classes/Headers/FLEXDefaultsContentSection.h"
#import "Classes/Headers/FLEXMetadataSection.h"
#import "Classes/Headers/FLEXMutableListSection.h"
#import "Classes/Headers/FLEXObjectInfoSection.h"
+17 -16
View File
@@ -6,21 +6,22 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <FLEXObjcInternal.h>
#import <FLEXSwiftInternal.h>
#import <FLEXRuntimeSafety.h>
#import <FLEXBlockDescription.h>
#import <FLEXTypeEncodingParser.h>
#import "Classes/Utility/Runtime/Objc/FLEXObjcInternal.h"
#import "Classes/Utility/Runtime/Objc/FLEXSwiftInternal.h"
#import "Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.h"
#import "Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.h"
#import <FLEXMirror.h>
#import <FLEXProtocol.h>
#import <FLEXProperty.h>
#import <FLEXIvar.h>
#import <FLEXMethodBase.h>
#import <FLEXMethod.h>
#import <FLEXPropertyAttributes.h>
#import <FLEXRuntime+Compare.h>
#import <FLEXRuntime+UIKitHelpers.h>
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.h"
#import "Classes/Utility/Categories/FLEXRuntime+Compare.h"
#import "Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXMetadataExtras.h"
#import <FLEXProtocolBuilder.h>
#import <FLEXClassBuilder.h>
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.h"
#import "Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.h"
+14 -13
View File
@@ -7,19 +7,20 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <FLEXManager.h>
#import <FLEXManager+Extensibility.h>
#import <FLEXManager+Networking.h>
#import "Classes/Headers/FLEXManager.h"
#import "Classes/Headers/FLEXManager+Extensibility.h"
#import "Classes/Headers/FLEXManager+Networking.h"
#import <FLEXExplorerToolbar.h>
#import <FLEXExplorerToolbarItem.h>
#import <FLEXGlobalsEntry.h>
#import "Classes/Headers/FLEXExplorerToolbar.h"
#import "Classes/Headers/FLEXExplorerToolbarItem.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
#import <FLEX-Core.h>
#import <FLEX-Runtime.h>
#import <FLEX-Categories.h>
#import <FLEX-ObjectExploring.h>
#import "Classes/Headers/FLEX-Core.h"
#import "Classes/Headers/FLEX-Runtime.h"
#import "Classes/Headers/FLEX-Categories.h"
#import "Classes/Headers/FLEX-ObjectExploring.h"
#import <FLEXMacros.h>
#import <FLEXAlert.h>
#import <FLEXResources.h>
#import "Classes/Utility/FLEXMacros.h"
#import "Classes/Utility/FLEXAlert.h"
#import "Classes/Utility/FLEXResources.h"
#import "Classes/Utility/FLEXHeapEnumerator.h"
@@ -6,11 +6,11 @@
// Copyright © 2015年 f. All rights reserved.
//
#import "FLEXDBQueryRowCell.h"
#import "FLEXMultiColumnTableView.h"
#import "NSArray+FLEX.h"
#import "UIFont+FLEX.h"
#import "FLEXColor.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/Utility/Categories/UIFont+FLEX.h"
#import "Classes/Utility/FLEXColor.h"
NSString * const kFLEXDBQueryRowCellReuse = @"kFLEXDBQueryRowCellReuse";
@@ -12,7 +12,7 @@
// which Flying Meat Inc. licenses this file to you.
#import <Foundation/Foundation.h>
#import "FLEXSQLResult.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h"
/// Conformers should automatically open and close the database
@protocol FLEXDatabaseManager <NSObject>
@@ -7,7 +7,7 @@
//
#import <UIKit/UIKit.h>
#import "FLEXTableColumnHeader.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h"
@class FLEXMultiColumnTableView;
@@ -6,11 +6,11 @@
// Copyright © 2015年 Peng Tao. All rights reserved.
//
#import "FLEXMultiColumnTableView.h"
#import "FLEXDBQueryRowCell.h"
#import "FLEXTableLeftCell.h"
#import "NSArray+FLEX.h"
#import "FLEXColor.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/Utility/FLEXColor.h"
@interface FLEXMultiColumnTableView () <
UITableViewDataSource, UITableViewDelegate,
@@ -7,7 +7,7 @@
//
#import <Foundation/Foundation.h>
#import "FLEXDatabaseManager.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h"
@interface FLEXRealmDatabaseManager : NSObject <FLEXDatabaseManager>
@@ -6,15 +6,15 @@
// Copyright © 2016 Realm. All rights reserved.
//
#import "FLEXRealmDatabaseManager.h"
#import "NSArray+FLEX.h"
#import "FLEXSQLResult.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h"
#if __has_include(<Realm/Realm.h>)
#import <Realm/Realm.h>
#import <Realm/RLMRealm_Dynamic.h>
#else
#import "FLEXRealmDefines.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h"
#endif
@interface FLEXRealmDatabaseManager ()
@@ -6,14 +6,14 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXSQLResult.h"
#import "NSArray+FLEX.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
@implementation FLEXSQLResult
@synthesize keyedRows = _keyedRows;
+ (instancetype)message:(NSString *)message {
return [[self alloc] initWithmessage:message columns:nil rows:nil];
return [[self alloc] initWithMessage:message columns:nil rows:nil];
}
+ (instancetype)error:(NSString *)message {
@@ -23,12 +23,12 @@
}
+ (instancetype)columns:(NSArray<NSString *> *)columnNames rows:(NSArray<NSArray<NSString *> *> *)rowData {
return [[self alloc] initWithmessage:nil columns:columnNames rows:rowData];
return [[self alloc] initWithMessage:nil columns:columnNames rows:rowData];
}
- (id)initWithmessage:(NSString *)message columns:(NSArray *)columns rows:(NSArray<NSArray *> *)rows {
- (instancetype)initWithMessage:(NSString *)message columns:(NSArray<NSString *> *)columns rows:(NSArray<NSArray<NSString *> *> *)rows {
NSParameterAssert(message || (columns && rows));
NSParameterAssert(columns.count == rows.firstObject.count);
NSParameterAssert(rows.count == 0 || columns.count == rows.firstObject.count);
self = [super init];
if (self) {
@@ -12,8 +12,8 @@
// which Flying Meat Inc. licenses this file to you.
#import <Foundation/Foundation.h>
#import "FLEXDatabaseManager.h"
#import "FLEXSQLResult.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h"
@interface FLEXSQLiteDatabaseManager : NSObject <FLEXDatabaseManager>
@@ -6,13 +6,16 @@
// Copyright © 2015年 Peng Tao. All rights reserved.
//
#import "FLEXSQLiteDatabaseManager.h"
#import "FLEXManager.h"
#import "NSArray+FLEX.h"
#import "FLEXRuntimeConstants.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h"
#import "Classes/Headers/FLEXManager.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.h"
#import <sqlite3.h>
static NSString * const QUERY_TABLENAMES = @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
#define kQuery(name, str) static NSString * const QUERY_##name = str
kQuery(TABLENAMES, @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name");
kQuery(ROWIDS, @"SELECT rowid FROM \"%@\" ORDER BY rowid ASC");
@interface FLEXSQLiteDatabaseManager ()
@property (nonatomic) sqlite3 *db;
@@ -107,7 +110,19 @@ static NSString * const QUERY_TABLENAMES = @"SELECT name FROM sqlite_master WHER
- (NSArray<NSString *> *)queryAllColumnsOfTable:(NSString *)tableName {
NSString *sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')",tableName];
FLEXSQLResult *results = [self executeStatement:sql];
// https://github.com/FLEXTool/FLEX/issues/554
if (!results.keyedRows.count) {
sql = [NSString stringWithFormat:@"SELECT * FROM pragma_table_info('%@')", tableName];
results = [self executeStatement:sql];
// Fallback to empty query
if (!results.keyedRows.count) {
sql = [NSString stringWithFormat:@"SELECT * FROM \"%@\" where 0=1", tableName];
return [self executeStatement:sql].columns ?: @[];
}
}
return [results.keyedRows flex_mapped:^id(NSDictionary *column, NSUInteger idx) {
return column[@"name"];
}] ?: @[];
@@ -119,7 +134,7 @@ static NSString * const QUERY_TABLENAMES = @"SELECT name FROM sqlite_master WHER
}
- (NSArray<NSString *> *)queryRowIDsInTable:(NSString *)tableName {
NSString *command = [NSString stringWithFormat:@"SELECT rowid FROM \"%@\"", tableName];
NSString *command = [NSString stringWithFormat:QUERY_ROWIDS, tableName];
NSArray<NSArray<NSString *> *> *data = [self executeStatement:command].rows ?: @[];
return [data flex_mapped:^id(NSArray<NSString *> *obj, NSUInteger idx) {
@@ -146,7 +161,7 @@ static NSString * const QUERY_TABLENAMES = @"SELECT name FROM sqlite_master WHER
return self.lastResult;
}
// Grab columns
// Grab columns (columnCount will be 0 for insert/update/delete)
int columnCount = sqlite3_column_count(pstmt);
NSArray<NSString *> *columns = [NSArray flex_forEachUpTo:columnCount map:^id(NSUInteger i) {
return @(sqlite3_column_name(pstmt, (int)i));
@@ -164,8 +179,9 @@ static NSString * const QUERY_TABLENAMES = @"SELECT name FROM sqlite_master WHER
}
if (status == SQLITE_DONE) {
if (rows.count) {
// We selected some rows
// columnCount will be 0 for insert/update/delete
if (rows.count || columnCount > 0) {
// We executed a SELECT query
result = _lastResult = [FLEXSQLResult columns:columns rows:rows];
} else {
// We executed a query like INSERT, UDPATE, or DELETE
@@ -6,10 +6,10 @@
// Copyright © 2015年 f. All rights reserved.
//
#import "FLEXTableColumnHeader.h"
#import "FLEXColor.h"
#import "UIFont+FLEX.h"
#import "FLEXUtility.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h"
#import "Classes/Utility/FLEXColor.h"
#import "Classes/Utility/Categories/UIFont+FLEX.h"
#import "Classes/Utility/FLEXUtility.h"
static const CGFloat kMargin = 5;
static const CGFloat kArrowWidth = 20;
@@ -7,19 +7,29 @@
//
#import <UIKit/UIKit.h>
#import "FLEXDatabaseManager.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLEXTableContentViewController : UIViewController
/// Display a table with the given columns, rows, and name.
/// Display a mutable table with the given columns, rows, and name.
///
/// @param columnNames self explanatory.
/// @param rowData an array of rows, where each row is an array of column data.
/// @param rowIDs an array of stringy row IDs. Required for deleting rows.
/// @param tableName an optional name of the table being viewed, if any. Enables adding rows.
/// @param databaseManager an optional manager to allow modifying the table.
/// Required for deleting rows. Required for adding rows if \c tableName is supplied.
+ (instancetype)columns:(NSArray<NSString *> *)columnNames
rows:(NSArray<NSArray<NSString *> *> *)rowData
rowIDs:(nullable NSArray<NSString *> *)rowIds
rowIDs:(NSArray<NSString *> *)rowIDs
tableName:(NSString *)tableName
database:(nullable id<FLEXDatabaseManager>)databaseManager;
database:(id<FLEXDatabaseManager>)databaseManager;
/// Display an immutable table with the given columns and rows.
+ (instancetype)columns:(NSArray<NSString *> *)columnNames
rows:(NSArray<NSArray<NSString *> *> *)rowData;
@end
@@ -6,11 +6,12 @@
// Copyright © 2015年 Peng Tao. All rights reserved.
//
#import "FLEXTableContentViewController.h"
#import "FLEXMultiColumnTableView.h"
#import "FLEXWebViewController.h"
#import "FLEXUtility.h"
#import "UIBarButtonItem+FLEX.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableRowDataViewController.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h"
#import "Classes/GlobalStateExplorers/FLEXWebViewController.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
@interface FLEXTableContentViewController () <
FLEXMultiColumnTableViewDataSource, FLEXMultiColumnTableViewDelegate
@@ -21,6 +22,8 @@
@property (nonatomic, nullable) NSMutableArray<NSString *> *rowIDs;
@property (nonatomic, readonly, nullable) id<FLEXDatabaseManager> databaseManager;
@property (nonatomic, readonly) BOOL canRefresh;
@property (nonatomic) FLEXMultiColumnTableView *multiColumnView;
@end
@@ -28,16 +31,43 @@
+ (instancetype)columns:(NSArray<NSString *> *)columnNames
rows:(NSArray<NSArray<NSString *> *> *)rowData
rowIDs:(nullable NSArray<NSString *> *)rowIDs
rowIDs:(NSArray<NSString *> *)rowIDs
tableName:(NSString *)tableName
database:(nullable id<FLEXDatabaseManager>)databaseManager {
FLEXTableContentViewController *controller = [self new];
controller->_columns = columnNames.copy;
controller->_rows = rowData.mutableCopy;
controller->_rowIDs = rowIDs.mutableCopy;
controller->_tableName = tableName.copy;
controller->_databaseManager = databaseManager;
return controller;
database:(id<FLEXDatabaseManager>)databaseManager {
return [[self alloc]
initWithColumns:columnNames
rows:rowData
rowIDs:rowIDs
tableName:tableName
database:databaseManager
];
}
+ (instancetype)columns:(NSArray<NSString *> *)cols
rows:(NSArray<NSArray<NSString *> *> *)rowData {
return [[self alloc] initWithColumns:cols rows:rowData rowIDs:nil tableName:nil database:nil];
}
- (instancetype)initWithColumns:(NSArray<NSString *> *)columnNames
rows:(NSArray<NSArray<NSString *> *> *)rowData
rowIDs:(nullable NSArray<NSString *> *)rowIDs
tableName:(nullable NSString *)tableName
database:(nullable id<FLEXDatabaseManager>)databaseManager {
// Must supply all optional parameters as one, or none
BOOL all = rowIDs && tableName && databaseManager;
BOOL none = !rowIDs && !tableName && !databaseManager;
NSParameterAssert(all || none);
self = [super init];
if (self) {
self->_columns = columnNames.copy;
self->_rows = rowData.mutableCopy;
self->_rowIDs = rowIDs.mutableCopy;
self->_tableName = tableName.copy;
self->_databaseManager = databaseManager;
}
return self;
}
- (void)loadView {
@@ -49,7 +79,6 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.title = self.tableName;
self.edgesForExtendedLayout = UIRectEdgeNone;
[self.multiColumnView reloadData];
[self setupToolbarItems];
}
@@ -67,6 +96,10 @@
return _multiColumnView;
}
- (BOOL)canRefresh {
return self.databaseManager && self.tableName;
}
#pragma mark MultiColumnTableView DataSource
- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView {
@@ -122,6 +155,10 @@
return [NSString stringWithFormat:@"%@:\n%@", self.columns[idx], field];
}];
NSArray<NSString *> *values = [self.rows[row] flex_mapped:^id(NSString *value, NSUInteger idx) {
return [NSString stringWithFormat:@"'%@'", value];
}];
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title([@"Row " stringByAppendingString:@(row).stringValue]);
NSString *message = [fields componentsJoinedByString:@"\n\n"];
@@ -129,10 +166,19 @@
make.button(@"Copy").handler(^(NSArray<NSString *> *strings) {
UIPasteboard.generalPasteboard.string = message;
});
make.button(@"Copy as CSV").handler(^(NSArray<NSString *> *strings) {
UIPasteboard.generalPasteboard.string = [values componentsJoinedByString:@", "];
});
make.button(@"Focus on Row").handler(^(NSArray<NSString *> *strings) {
UIViewController *focusedRow = [FLEXTableRowDataViewController
rows:[NSDictionary dictionaryWithObjects:self.rows[row] forKeys:self.columns]
];
[self.navigationController pushViewController:focusedRow animated:YES];
});
// Option to delete row
BOOL hasRowID = self.rows.count && row < self.rows.count;
if (hasRowID) {
if (hasRowID && self.canRefresh) {
make.button(@"Delete").destructiveStyle().handler(^(NSArray<NSString *> *strings) {
NSString *deleteRow = [NSString stringWithFormat:
@"DELETE FROM %@ WHERE rowid = %@",
@@ -142,9 +188,7 @@
[self executeStatementAndShowResult:deleteRow completion:^(BOOL success) {
// Remove deleted row and reload view
if (success) {
[self.rowIDs removeObjectAtIndex:row];
[self.rows removeObjectAtIndex:row];
[self.multiColumnView reloadData];
[self reloadTableDataFromDB];
}
}];
});
@@ -216,14 +260,24 @@
return;
}
UIBarButtonItem *trashButton = [FLEXBarButtonItemSystem(Trash, self, @selector(trashPressed))
flex_withTintColor:UIColor.redColor
UIBarButtonItem *trashButton = FLEXBarButtonItemSystem(Trash, self, @selector(trashPressed));
UIBarButtonItem *addButton = FLEXBarButtonItemSystem(Add, self, @selector(addPressed));
// Only allow adding rows or deleting rows if we have a table name
trashButton.enabled = self.canRefresh;
addButton.enabled = self.canRefresh;
self.toolbarItems = @[
UIBarButtonItem.flex_flexibleSpace,
addButton,
UIBarButtonItem.flex_flexibleSpace,
[trashButton flex_withTintColor:UIColor.redColor],
];
trashButton.enabled = self.databaseManager && self.rows.count;
self.toolbarItems = @[UIBarButtonItem.flex_flexibleSpace, trashButton];
}
- (void)trashPressed {
NSParameterAssert(self.tableName);
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Delete All Rows");
make.message(@"All rows in this table will be permanently deleted.\nDo you want to proceed?");
@@ -241,9 +295,35 @@
} showFrom:self];
}
- (void)addPressed {
NSParameterAssert(self.tableName);
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Add a New Row");
make.message(@"Comma separate values to use in an INSERT statement.\n\n");
make.message(@"INSERT INTO [table] VALUES (your_input)");
make.textField(@"5, 'John Smith', 14,...");
make.button(@"Insert").handler(^(NSArray<NSString *> *strings) {
NSString *statement = [NSString stringWithFormat:
@"INSERT INTO %@ VALUES (%@)", self.tableName, strings[0]
];
[self executeStatementAndShowResult:statement completion:^(BOOL success) {
if (success) {
[self reloadTableDataFromDB];
}
}];
});
make.button(@"Cancel").cancelStyle();
} showFrom:self];
}
#pragma mark - Helpers
- (void)executeStatementAndShowResult:(NSString *)statement completion:(void (^_Nullable)(BOOL success))completion {
- (void)executeStatementAndShowResult:(NSString *)statement
completion:(void (^_Nullable)(BOOL success))completion {
NSParameterAssert(self.databaseManager);
FLEXSQLResult *result = [self.databaseManager executeStatement:statement];
[FLEXAlert makeAlert:^(FLEXAlert *make) {
@@ -260,5 +340,20 @@
} showFrom:self];
}
- (void)reloadTableDataFromDB {
if (!self.canRefresh) {
return;
}
NSArray<NSArray *> *rows = [self.databaseManager queryAllDataInTable:self.tableName];
NSArray<NSString *> *rowIDs = nil;
if ([self.databaseManager respondsToSelector:@selector(queryRowIDsInTable:)]) {
rowIDs = [self.databaseManager queryRowIDsInTable:self.tableName];
}
self.rows = rows.mutableCopy;
self.rowIDs = rowIDs.mutableCopy;
[self.multiColumnView reloadData];
}
@end
@@ -6,7 +6,7 @@
// Copyright © 2015年 f. All rights reserved.
//
#import "FLEXTableLeftCell.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h"
@implementation FLEXTableLeftCell
@@ -6,7 +6,7 @@
// Copyright © 2015年 Peng Tao. All rights reserved.
//
#import "FLEXFilteringTableViewController.h"
#import "Classes/Headers/FLEXFilteringTableViewController.h"
@interface FLEXTableListViewController : FLEXFilteringTableViewController
@@ -6,15 +6,15 @@
// Copyright © 2015年 Peng Tao. All rights reserved.
//
#import "FLEXTableListViewController.h"
#import "FLEXDatabaseManager.h"
#import "FLEXSQLiteDatabaseManager.h"
#import "FLEXRealmDatabaseManager.h"
#import "FLEXTableContentViewController.h"
#import "FLEXMutableListSection.h"
#import "NSArray+FLEX.h"
#import "FLEXAlert.h"
#import "FLEXMacros.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h"
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h"
#import "Classes/Headers/FLEXMutableListSection.h"
#import "Classes/Utility/Categories/NSArray+FLEX.h"
#import "Classes/Utility/FLEXAlert.h"
#import "Classes/Utility/FLEXMacros.h"
@interface FLEXTableListViewController ()
@property (nonatomic, readonly) id<FLEXDatabaseManager> dbm;
@@ -93,19 +93,40 @@
}
- (void)queryButtonPressed {
[self showQueryInput:nil];
}
- (void)showQueryInput:(NSString *)prefillQuery {
FLEXSQLiteDatabaseManager *database = self.dbm;
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Execute an SQL query");
make.textField(nil);
make.configuredTextField(^(UITextField *textField) {
textField.text = prefillQuery;
});
make.button(@"Run").handler(^(NSArray<NSString *> *strings) {
FLEXSQLResult *result = [database executeStatement:strings[0]];
NSString *query = strings[0];
FLEXSQLResult *result = [database executeStatement:query];
if (result.message) {
[FLEXAlert showAlert:@"Message" message:result.message from:self];
// Allow users to edit their last query if it had an error
if ([result.message containsString:@"error"]) {
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Error").message(result.message);
make.button(@"Edit Query").preferred().handler(^(NSArray<NSString *> *_) {
// Show query editor again with our last input
[self showQueryInput:query];
});
make.button(@"Cancel").cancelStyle();
} showFrom:self];
} else {
[FLEXAlert showAlert:@"Message" message:result.message from:self];
}
} else {
UIViewController *resultsScreen = [FLEXTableContentViewController
columns:result.columns rows:result.rows rowIDs:nil tableName:@"" database:nil
columns:result.columns rows:result.rows
];
[self.navigationController pushViewController:resultsScreen animated:YES];
@@ -0,0 +1,14 @@
//
// FLEXTableRowDataViewController.h
// FLEX
//
// Created by Chaoshuai Lu on 7/8/20.
//
#import "Classes/Headers/FLEXFilteringTableViewController.h"
@interface FLEXTableRowDataViewController : FLEXFilteringTableViewController
+ (instancetype)rows:(NSDictionary<NSString *, id> *)rowData;
@end
@@ -0,0 +1,54 @@
//
// FLEXTableRowDataViewController.m
// FLEX
//
// Created by Chaoshuai Lu on 7/8/20.
//
#import "Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableRowDataViewController.h"
#import "Classes/Headers/FLEXMutableListSection.h"
#import "Classes/Utility/FLEXAlert.h"
@interface FLEXTableRowDataViewController ()
@property (nonatomic) NSDictionary<NSString *, NSString *> *rowsByColumn;
@end
@implementation FLEXTableRowDataViewController
#pragma mark - Initialization
+ (instancetype)rows:(NSDictionary<NSString *, id> *)rowData {
FLEXTableRowDataViewController *controller = [self new];
controller.rowsByColumn = rowData;
return controller;
}
#pragma mark - Overrides
- (NSArray<FLEXTableViewSection *> *)makeSections {
NSDictionary<NSString *, NSString *> *rowsByColumn = self.rowsByColumn;
FLEXMutableListSection<NSString *> *section = [FLEXMutableListSection list:self.rowsByColumn.allKeys
cellConfiguration:^(UITableViewCell *cell, NSString *column, NSInteger row) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = column;
cell.detailTextLabel.text = rowsByColumn[column].description;
} filterMatcher:^BOOL(NSString *filterText, NSString *column) {
return [column localizedCaseInsensitiveContainsString:filterText] ||
[rowsByColumn[column] localizedCaseInsensitiveContainsString:filterText];
}
];
section.selectionHandler = ^(UIViewController *host, NSString *column) {
UIPasteboard.generalPasteboard.string = rowsByColumn[column].description;
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Column Copied to Clipboard");
make.message(rowsByColumn[column].description);
make.button(@"Dismiss").cancelStyle();
} showFrom:host];
};
return @[section];
}
@end
@@ -0,0 +1,14 @@
//
// FLEXAPNSViewController.h
// FLEX
//
// Created by Tanner Bennett on 6/28/22.
// Copyright © 2022 FLEX Team. All rights reserved.
//
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
#import "Classes/Headers/FLEXFilteringTableViewController.h"
@interface FLEXAPNSViewController : FLEXFilteringTableViewController <FLEXGlobalsEntry>
@end
@@ -0,0 +1,372 @@
//
// FLEXAPNSViewController.m
// FLEX
//
// Created by Tanner Bennett on 6/28/22.
// Copyright © 2022 FLEX Team. All rights reserved.
//
#import "Classes/GlobalStateExplorers/FLEXAPNSViewController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Headers/FLEXMutableListSection.h"
#import "Classes/Headers/FLEXSingleRowSection.h"
#import "Classes/Utility/Categories/NSUserDefaults+FLEX.h"
#import "Classes/Utility/Categories/UIBarButtonItem+FLEX.h"
#import "Classes/Utility/Categories/NSDateFormatter+FLEX.h"
#import "Classes/Utility/FLEXResources.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Utility/Runtime/flex_fishhook.h"
#import <dlfcn.h>
#import <UserNotifications/UserNotifications.h>
#define orig(method, ...) if (orig_##method) { orig_##method(__VA_ARGS__); }
#define method_lookup(__selector, __cls, __return, ...) \
([__cls instancesRespondToSelector:__selector] ? \
(__return(*)(__VA_ARGS__))class_getMethodImplementation(__cls, __selector) : nil)
@interface FLEXAPNSViewController ()
@property (nonatomic, readonly, class) Class appDelegateClass;
@property (nonatomic, class) NSData *deviceToken;
@property (nonatomic, class) NSError *registrationError;
@property (nonatomic, readonly, class) NSString *deviceTokenString;
@property (nonatomic, readonly, class) NSMutableArray<NSDictionary *> *remoteNotifications;
@property (nonatomic, readonly, class) NSMutableArray<UNNotification *> *userNotifications API_AVAILABLE(ios(10.0));
@property (nonatomic) FLEXSingleRowSection *deviceToken;
@property (nonatomic) FLEXMutableListSection<NSDictionary *> *remoteNotifications;
@property (nonatomic) FLEXMutableListSection<UNNotification *> *userNotifications API_AVAILABLE(ios(10.0));
@end
@implementation FLEXAPNSViewController
#pragma mark Swizzles
/// Hook User Notifications related methods on the app delegate
/// and UNUserNotificationCenter delegate classes
+ (void)load { FLEX_EXIT_IF_NO_CTORS()
if (!NSUserDefaults.standardUserDefaults.flex_enableAPNSCapture) {
return;
}
//──────────────────────//
// App Delegate //
//──────────────────────//
// Hook UIApplication to intercept app delegate
Class uiapp = UIApplication.self;
auto orig_uiapp_setDelegate = (void(*)(id, SEL, id))class_getMethodImplementation(
uiapp, @selector(setDelegate:)
);
IMP uiapp_setDelegate = imp_implementationWithBlock(^(id _, id delegate) {
[self hookAppDelegateClass:[delegate class]];
orig_uiapp_setDelegate(_, @selector(setDelegate:), delegate);
});
class_replaceMethod(
uiapp,
@selector(setDelegate:),
uiapp_setDelegate,
"v@:@"
);
//───────────────────────────────────────────//
// UNUserNotificationCenter Delegate //
//───────────────────────────────────────────//
if (@available(iOS 10.0, *)) {
Class unusernc = UNUserNotificationCenter.self;
auto orig_unusernc_setDelegate = (void(*)(id, SEL, id))class_getMethodImplementation(
unusernc, @selector(setDelegate:)
);
IMP unusernc_setDelegate = imp_implementationWithBlock(^(id _, id delegate) {
[self hookUNUserNotificationCenterDelegateClass:[delegate class]];
orig_unusernc_setDelegate(_, @selector(setDelegate:), delegate);
});
class_replaceMethod(
unusernc,
@selector(setDelegate:),
unusernc_setDelegate,
"v@:@"
);
}
}
+ (void)hookAppDelegateClass:(Class)appDelegate {
// Abort if we already hooked something
if (_appDelegateClass) {
return;
}
_appDelegateClass = appDelegate;
// Better documentation for what's happening is in hookUNUserNotificationCenterDelegateClass: below
auto types_didRegisterForRemoteNotificationsWithDeviceToken = "v@:@@";
auto types_didFailToRegisterForRemoteNotificationsWithError = "v@:@@";
auto types_didReceiveRemoteNotification = "v@:@@@?";
auto sel_didRegisterForRemoteNotifications = @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:);
auto sel_didFailToRegisterForRemoteNotifs = @selector(application:didFailToRegisterForRemoteNotificationsWithError:);
auto sel_didReceiveRemoteNotification = @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:);
auto orig_didRegisterForRemoteNotificationsWithDeviceToken = method_lookup(
sel_didRegisterForRemoteNotifications, appDelegate, void, id, SEL, id, id);
auto orig_didFailToRegisterForRemoteNotificationsWithError = method_lookup(
sel_didFailToRegisterForRemoteNotifs, appDelegate, void, id, SEL, id, id);
auto orig_didReceiveRemoteNotification = method_lookup(
sel_didReceiveRemoteNotification, appDelegate, void, id, SEL, id, id, id);
IMP didRegisterForRemoteNotificationsWithDeviceToken = imp_implementationWithBlock(^(id _, id app, NSData *token) {
self.deviceToken = token;
orig(didRegisterForRemoteNotificationsWithDeviceToken, _, nil, app, token);
});
IMP didFailToRegisterForRemoteNotificationsWithError = imp_implementationWithBlock(^(id _, id app, NSError *error) {
self.registrationError = error;
orig(didFailToRegisterForRemoteNotificationsWithError, _, nil, app, error);
});
IMP didReceiveRemoteNotification = imp_implementationWithBlock(^(id _, id app, NSDictionary *payload, id handler) {
// TODO: notify when new notifications are added
[self.remoteNotifications addObject:payload];
orig(didReceiveRemoteNotification, _, nil, app, payload, handler);
});
class_replaceMethod(
appDelegate,
sel_didRegisterForRemoteNotifications,
didRegisterForRemoteNotificationsWithDeviceToken,
types_didRegisterForRemoteNotificationsWithDeviceToken
);
class_replaceMethod(
appDelegate,
sel_didFailToRegisterForRemoteNotifs,
didFailToRegisterForRemoteNotificationsWithError,
types_didFailToRegisterForRemoteNotificationsWithError
);
class_replaceMethod(
appDelegate,
sel_didReceiveRemoteNotification,
didReceiveRemoteNotification,
types_didReceiveRemoteNotification
);
}
+ (void)hookUNUserNotificationCenterDelegateClass:(Class)delegate API_AVAILABLE(ios(10.0)) {
// Selector
auto sel_didReceiveNotification =
@selector(userNotificationCenter:willPresentNotification:withCompletionHandler:);
// Original implementation (or nil if unimplemented)
auto orig_didReceiveNotification = method_lookup(
sel_didReceiveNotification, delegate, void, id, SEL, id, id, id);
// Our hook (ignores self and other unneeded parameters)
IMP didReceiveNotification = imp_implementationWithBlock(^(id _, id __, UNNotification *notification, id ___) {
[self.userNotifications addObject:notification];
// This macro is a no-op if there is no original implementation
orig(didReceiveNotification, _, nil, __, notification, ___);
});
// Set the hook
class_replaceMethod(
delegate,
sel_didReceiveNotification,
didReceiveNotification,
"v@:@@@?"
);
}
#pragma mark Class Properties
static Class _appDelegateClass = nil;
+ (Class)appDelegateClass {
return _appDelegateClass;
}
static NSData *_apnsDeviceToken = nil;
+ (NSData *)deviceToken {
return _apnsDeviceToken;
}
+ (void)setDeviceToken:(NSData *)deviceToken {
_apnsDeviceToken = deviceToken;
}
+ (NSString *)deviceTokenString {
static NSString *_deviceTokenString = nil;
if (!_deviceTokenString && self.deviceToken) {
NSData *token = self.deviceToken;
NSUInteger capacity = token.length * 2;
NSMutableString *tokenString = [NSMutableString stringWithCapacity:capacity];
const UInt8 *tokenData = token.bytes;
for (NSUInteger idx = 0; idx < token.length; ++idx) {
[tokenString appendFormat:@"%02X", (int)tokenData[idx]];
}
_deviceTokenString = tokenString;
}
return _deviceTokenString;
}
static NSError *_apnsRegistrationError = nil;
+ (NSError *)registrationError {
return _apnsRegistrationError;
}
+ (void)setRegistrationError:(NSError *)error {
_apnsRegistrationError = error;
}
+ (NSMutableArray<NSDictionary *> *)userNotifications {
static NSMutableArray *_userNotifications = nil;
if (!_userNotifications) {
_userNotifications = [NSMutableArray new];
}
return _userNotifications;
}
+ (NSMutableArray<NSDictionary *> *)remoteNotifications {
static NSMutableArray *_remoteNotifications = nil;
if (!_remoteNotifications) {
_remoteNotifications = [NSMutableArray new];
}
return _remoteNotifications;
}
#pragma mark Instance stuff
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Push Notifications";
self.refreshControl = [UIRefreshControl new];
[self.refreshControl addTarget:self action:@selector(reloadData) forControlEvents:UIControlEventValueChanged];
[self addToolbarItems:@[
[UIBarButtonItem
flex_itemWithImage:FLEXResources.gearIcon
target:self
action:@selector(settingsButtonTapped)
],
]];
}
- (NSArray<FLEXTableViewSection *> *)makeSections {
self.deviceToken = [FLEXSingleRowSection title:@"APNS Device Token" reuse:nil cell:^(UITableViewCell *cell) {
NSString *tokenString = FLEXAPNSViewController.deviceTokenString;
if (tokenString) {
cell.textLabel.text = tokenString;
cell.textLabel.numberOfLines = 0;
}
else if (!NSUserDefaults.standardUserDefaults.flex_enableAPNSCapture) {
cell.textLabel.text = @"APNS capture disabled";
}
else {
cell.textLabel.text = @"Not yet registered";
}
}];
self.deviceToken.selectionAction = ^(UIViewController *host) {
UIPasteboard.generalPasteboard.string = FLEXAPNSViewController.deviceTokenString;
[FLEXAlert showQuickAlert:@"Copied to Clipboard" from:host];
};
// Remote Notifications //
self.remoteNotifications = [FLEXMutableListSection list:FLEXAPNSViewController.remoteNotifications
cellConfiguration:^(UITableViewCell *cell, NSDictionary *notif, NSInteger row) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// TODO: date received
cell.detailTextLabel.text = [FLEXRuntimeUtility summaryForObject:notif];
}
filterMatcher:^BOOL(NSString *filterText, NSDictionary *notif) {
return [notif.description localizedCaseInsensitiveContainsString:filterText];
}
];
self.remoteNotifications.customTitle = @"Remote Notifications";
self.remoteNotifications.selectionHandler = ^(UIViewController *host, NSDictionary *notif) {
[host.navigationController pushViewController:[
FLEXObjectExplorerFactory explorerViewControllerForObject:notif
] animated:YES];
};
// User Notifications //
if (@available(iOS 10.0, *)) {
self.userNotifications = [FLEXMutableListSection list:FLEXAPNSViewController.userNotifications
cellConfiguration:^(UITableViewCell *cell, UNNotification *notif, NSInteger row) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Subtitle is 'subtitle \n date'
NSString *dateString = [NSDateFormatter flex_stringFrom:notif.date format:FLEXDateFormatPreciseClock];
NSString *subtitle = notif.request.content.subtitle;
subtitle = subtitle ? [NSString stringWithFormat:@"%@\n%@", subtitle, dateString] : dateString;
cell.textLabel.text = notif.request.content.title;
cell.detailTextLabel.text = subtitle;
}
filterMatcher:^BOOL(NSString *filterText, NSDictionary *notif) {
return [notif.description localizedCaseInsensitiveContainsString:filterText];
}
];
self.userNotifications.customTitle = @"Push Notifications";
self.userNotifications.selectionHandler = ^(UIViewController *host, UNNotification *notif) {
[host.navigationController pushViewController:[
FLEXObjectExplorerFactory explorerViewControllerForObject:notif.request
] animated:YES];
};
return @[self.deviceToken, self.remoteNotifications, self.userNotifications];
}
else {
return @[self.deviceToken, self.remoteNotifications];
}
}
- (void)reloadData {
[self.refreshControl endRefreshing];
self.remoteNotifications.customTitle = [NSString stringWithFormat:
@"%@ notifications", @(self.remoteNotifications.filteredList.count)
];
[super reloadData];
}
- (void)settingsButtonTapped {
NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
BOOL enabled = defaults.flex_enableAPNSCapture;
NSString *apnsToggle = enabled ? @"Disable Capture" : @"Enable Capture";
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Settings")
.message(@"Enable or disable the capture of push notifications.\n\n")
.message(@"This will hook UIApplicationMain on launch until it is disabled, ")
.message(@"and swizzle some app delegate methods. Restart the app for changes to take effect.");
make.button(apnsToggle).destructiveStyle().handler(^(NSArray<NSString *> *strings) {
[defaults flex_toggleBoolForKey:kFLEXDefaultsAPNSCaptureEnabledKey];
});
make.button(@"Dismiss").cancelStyle();
} showFrom:self];
}
#pragma mark - FLEXGlobalsEntry
+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row {
return @"📌 Push Notifications";
}
+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row {
return [self new];
}
@end
@@ -6,7 +6,7 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXGlobalsEntry.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
@interface FLEXAddressExplorerCoordinator : NSObject <FLEXGlobalsEntry>
@@ -6,12 +6,12 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXAddressExplorerCoordinator.h"
#import "FLEXGlobalsViewController.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXObjectExplorerViewController.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXUtility.h"
#import "Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Headers/FLEXObjectExplorerViewController.h"
#import "Classes/Utility/Runtime/FLEXRuntimeUtility.h"
#import "Classes/Utility/FLEXUtility.h"
@interface UITableViewController (FLEXAddressExploration)
- (void)deselectSelectedRow;
@@ -6,8 +6,8 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXGlobalsEntry.h"
#import "FLEXFilteringTableViewController.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
#import "Classes/Headers/FLEXFilteringTableViewController.h"
@interface FLEXCookiesViewController : FLEXFilteringTableViewController <FLEXGlobalsEntry>
@@ -6,10 +6,10 @@
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXCookiesViewController.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXMutableListSection.h"
#import "FLEXUtility.h"
#import "Classes/GlobalStateExplorers/FLEXCookiesViewController.h"
#import "Classes/Headers/FLEXObjectExplorerFactory.h"
#import "Classes/Headers/FLEXMutableListSection.h"
#import "Classes/Utility/FLEXUtility.h"
@interface FLEXCookiesViewController ()
@property (nonatomic, readonly) FLEXMutableListSection<NSHTTPCookie *> *cookies;
@@ -26,6 +26,14 @@
self.title = @"Cookies";
}
- (NSString *)headerTitle {
return self.cookies.title;
}
- (void)setHeaderTitle:(NSString *)headerTitle {
self.cookies.customTitle = headerTitle;
}
- (NSArray<FLEXTableViewSection *> *)makeSections {
NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)
@@ -6,8 +6,8 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
#import "FLEXGlobalsEntry.h"
#import "Classes/Headers/FLEXTableViewController.h"
#import "Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h"
@interface FLEXLiveObjectsController : FLEXTableViewController <FLEXGlobalsEntry>
@@ -6,12 +6,12 @@
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXLiveObjectsController.h"
#import "FLEXHeapEnumerator.h"
#import "FLEXObjectListViewController.h"
#import "FLEXUtility.h"
#import "FLEXScopeCarousel.h"
#import "FLEXTableView.h"
#import "Classes/GlobalStateExplorers/FLEXLiveObjectsController.h"
#import "Classes/Utility/FLEXHeapEnumerator.h"
#import "Classes/GlobalStateExplorers/FLEXObjectListViewController.h"
#import "Classes/Utility/FLEXUtility.h"
#import "Classes/Core/Views/Carousel/FLEXScopeCarousel.h"
#import "Classes/Headers/FLEXTableView.h"
#import <objc/runtime.h>
static const NSInteger kFLEXLiveObjectsSortAlphabeticallyIndex = 0;

Some files were not shown because too many files have changed in this diff Show More