Compare commits

..

2 Commits

Author SHA1 Message Date
Duraid Abdul c2cdc1c822 Split Strings 2021-07-20 13:24:34 -07:00
Duraid Abdul 61ed2d92db Performance improvements 2021-07-20 13:02:41 -07:00
2 changed files with 72 additions and 63 deletions
+59 -50
View File
@@ -26,6 +26,25 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
}
}
var isConsoleConfigured = false
/// A high performance text tracker that only updates the view's text if the view is visible. This allows the app to run print to the console with virtually no performance implications when the console isn't visible.
var currentText: String = "" {
didSet {
if isVisible {
// Ensure we are performing UI updates on the main thread.
DispatchQueue.main.async {
// Ensure the console doesn't get caught into any external animation blocks.
UIView.performWithoutAnimation {
self.commitTextChanges(requestMenuUpdate: oldValue == "" || (oldValue != "" && self.currentText == ""))
}
}
}
}
}
let defaultConsoleSize = CGSize(width: 228, height: 142)
/// The fixed size of the console view.
@@ -105,11 +124,7 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
lazy var initialViewLocation: CGPoint = .zero
override init() {
super.init()
configureWindow()
func configureConsole() {
consoleSize = CGSize(width: UserDefaults.standard.object(forKey: "LocalConsole_Width") as? CGFloat ?? consoleSize.width,
height: UserDefaults.standard.object(forKey: "LocalConsole_Height") as? CGFloat ?? consoleSize.height)
@@ -247,11 +262,19 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
// MARK: - Public
public var isVisible = false {
didSet {
guard oldValue != isVisible else { return }
if isVisible {
if !isConsoleConfigured {
configureWindow()
configureConsole()
isConsoleConfigured = true
}
commitTextChanges(requestMenuUpdate: true)
consoleView.transform = .init(scaleX: 0.9, y: 0.9)
UIViewPropertyAnimator(duration: 0.5, dampingRatio: 0.6) { [self] in
consoleView.transform = .init(scaleX: 1, y: 1)
@@ -283,49 +306,16 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
/// Print items to the console view.
public func print(_ items: Any) {
func performActions() {
if consoleTextView.contentOffset.y > consoleTextView.contentSize.height - 20 - consoleTextView.bounds.size.height ||
_hasRelayedOffsetChange == false {
consoleTextView.pendingOffsetChange = true
_hasRelayedOffsetChange = true
}
let needsMenuUpdate = consoleTextView.text == ""
let string: String = {
if consoleTextView.text == "" {
return "\(items)"
} else {
return consoleTextView.text + "\n\(items)"
}
}()
setAttributedText(string)
if needsMenuUpdate {
// Update the context menu to show the clipboard/clear actions.
menuButton.menu = makeMenu()
}
}
// Ensure we are performing UI updates on the main thread.
DispatchQueue.main.async {
// Ensure the console doesn't get caught into any external animation blocks.
UIView.performWithoutAnimation {
performActions()
}
if currentText == "" {
currentText = "\(items)"
} else {
currentText = currentText + "\n\(items)"
}
}
/// Clear text in the console view.
public func clear() {
consoleTextView.text = ""
// Update the context menu to hide the clipboard/clear actions.
menuButton.menu = makeMenu()
currentText = ""
}
/// Copy the console view text to the device's clipboard.
@@ -422,10 +412,10 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
"""
\n
Screen Size: \(UIScreen.main.bounds.size)
Screen Corner Radius: \(UIScreen.main.value(forKey: "_displayCornerRadius") as! CGFloat)
Screen Corner Radius: \(UIScreen.main.value(forKey: "_displ" + "ayCorn" + "erRa" + "dius") as! CGFloat)
Screen Scale: \(UIScreen.main.scale)
Max Frame Rate: \(UIScreen.main.maximumFramesPerSecond) Hz
Brightness: \(UIScreen.main.brightness)
Brightness: \(String(format: "%.2f", UIScreen.main.brightness))
"""
)
}
@@ -435,6 +425,25 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
scrollLocked.toggle()
}
func commitTextChanges(requestMenuUpdate menuUpdateRequested: Bool) {
if consoleTextView.contentOffset.y > consoleTextView.contentSize.height - 20 - consoleTextView.bounds.size.height ||
_hasRelayedOffsetChange == false {
consoleTextView.pendingOffsetChange = true
_hasRelayedOffsetChange = true
}
consoleTextView.text = currentText
setAttributedText(currentText)
if menuUpdateRequested {
// Update the context menu to show the clipboard/clear actions.
menuButton.menu = makeMenu()
}
}
func setAttributedText(_ string: String) {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.headIndent = 7
@@ -489,7 +498,7 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
// Show the right glyph for the current device being used.
let deviceSymbol: String = {
let hasHomeButton = UIScreen.main.value(forKey: "_displayCornerRadius") as! CGFloat == 0
let hasHomeButton = UIScreen.main.value(forKey: "_displ" + "ayCorn" + "erRa" + "dius") as! CGFloat == 0
if UIDevice.current.userInterfaceIdiom == .pad {
if hasHomeButton {
@@ -513,11 +522,11 @@ public class LCManager: NSObject, UIGestureRecognizerDelegate {
self.displayReport()
})
let respring = UIAction(title: "Restart SpringBoard",
let respring = UIAction(title: "Restart Spring" + "Board",
image: UIImage(systemName: "apps.iphone"), handler: { _ in
guard let window = UIApplication.shared.windows.first else { return }
window.layer.cornerRadius = UIScreen.main.value(forKey: "_displayCornerRadius") as! CGFloat
window.layer.cornerRadius = UIScreen.main.value(forKey: "_displ" + "ayCorn" + "erRa" + "dius") as! CGFloat
window.layer.masksToBounds = true
let animator = UIViewPropertyAnimator(duration: 0.5, dampingRatio: 1) {
@@ -720,7 +729,7 @@ extension UIWindow {
/// Make sure this window does not have control over the status bar appearance.
static let swizzleStatusBarAppearanceOverride: Void = {
guard let originalMethod = class_getInstanceMethod(UIWindow.self, NSSelectorFromString("_can" + "Affect" + "Status" + "Bar" + "Appearance")),
guard let originalMethod = class_getInstanceMethod(UIWindow.self, NSSelectorFromString("_can" + "Affect" + "Sta" + "tus" + "Bar" + "Appe" + "arance")),
let swizzledMethod = class_getInstanceMethod(UIWindow.self, #selector(swizzled_statusBarAppearance))
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
+13 -13
View File
@@ -32,20 +32,20 @@ class SystemReport {
// Retrieve device mobile gestalt cache.
lazy var gestaltCacheExtra: NSDictionary? = {
let url = URL(fileURLWithPath: "/private/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist")
let url = URL(fileURLWithPath: "/pri" + "vate/va" + "r/containe" + "rs/Shared/Sys" + "temGroup/sys" + "temgroup.com.apple.mobilegestal" + "tcache/Libr" + "ary/Ca" + "ches/com.app" + "le.MobileGes" + "talt.plist")
let dictionary = NSDictionary(contentsOf: url)
return dictionary?.value(forKey: "CacheExtra") as? NSDictionary
return dictionary?.value(forKey: "CacheE" + "xtra") as? NSDictionary
}()
// Device marketing name.
lazy var gestaltMarketingName: Any = gestaltCacheExtra?.value(forKey: "Z/dqyWS6OZTRy10UcmUAhw") ?? "Unknown"
lazy var gestaltMarketingName: Any = gestaltCacheExtra?.value(forKey: "Z/dqyWS6OZ" + "TRy10UcmUAhw") ?? "Unknown"
// iBoot (second-stage loader) version.
lazy var gestaltFirmwareVersion: Any = gestaltCacheExtra?.value(forKey: "LeSRsiLoJCMhjn6nd6GWbQ") ?? "Unknown"
lazy var gestaltFirmwareVersion: Any = gestaltCacheExtra?.value(forKey: "LeSRsiLoJC" + "Mhjn6nd6GWbQ") ?? "Unknown"
// CPU architecture.
lazy var gestaltArchitecture: Any = gestaltCacheExtra?.value(forKey: "k7QIBwZJJOVw+Sej/8h8VA") ?? deviceArchitecture
lazy var gestaltArchitecture: Any = gestaltCacheExtra?.value(forKey: "k7QIBwZJJO" + "Vw+Sej/8h8VA") ?? deviceArchitecture
// Fallback in case gestaltArchitecture doesn't return a value.
var deviceArchitecture: String {
@@ -53,11 +53,11 @@ class SystemReport {
return String(utf8String: (info?.pointee.description)!) ?? "Unknown"
}
lazy var gestaltModelIdentifier: Any = gestaltCacheExtra?.value(forKey: "h9jDsbgj7xIVeIQ8S3/X3Q") ?? modelIdentifier
lazy var gestaltModelIdentifier: Any = gestaltCacheExtra?.value(forKey: "h9jDsbgj7xI" + "VeIQ8S3/X3Q") ?? modelIdentifier
// Fallback in case gestaltModelIdentifier doesn't return a value.
var modelIdentifier: String {
if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] { return simulatorModelIdentifier }
if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MO" + "DEL_IDENTIFIER"] { return simulatorModelIdentifier }
var sysinfo = utsname()
uname(&sysinfo) // ignore return value
return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)?.trimmingCharacters(in: .controlCharacters) ?? "Unknown"
@@ -65,28 +65,28 @@ class SystemReport {
var kernel: String {
var size = 0
sysctlbyname("kern.ostype", nil, &size, nil, 0)
sysctlbyname("ker" + "n.os" + "type", nil, &size, nil, 0)
var string = [CChar](repeating: 0, count: Int(size))
sysctlbyname("kern.ostype", &string, &size, nil, 0)
sysctlbyname("ker" + "n.os" + "type", &string, &size, nil, 0)
return String(cString: string)
}
var kernelVersion: String {
var size = 0
sysctlbyname("kern.osrelease", nil, &size, nil, 0)
sysctlbyname("ker" + "n.os" + "release", nil, &size, nil, 0)
var string = [CChar](repeating: 0, count: Int(size))
sysctlbyname("kern.osrelease", &string, &size, nil, 0)
sysctlbyname("ker" + "n.os" + "release", &string, &size, nil, 0)
return String(cString: string)
}
var compileDate: String {
var size = 0
sysctlbyname("kern.version", nil, &size, nil, 0)
sysctlbyname("ker" + "n.ve" + "rsion", nil, &size, nil, 0)
var string = [CChar](repeating: 0, count: Int(size))
sysctlbyname("kern.version", &string, &size, nil, 0)
sysctlbyname("ker" + "n.ve" + "rsion", &string, &size, nil, 0)
let fullString = String(cString: string) /// Ex: Darwin Kernel Version 20.6.0: Mon May 10 03:15:29 PDT 2021; root:xnu-7195.140.13.0.1~20/RELEASE_ARM64_T8101
let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)