diff --git a/BuildTimeAnalyzer.xcodeproj/project.pbxproj b/BuildTimeAnalyzer.xcodeproj/project.pbxproj
index 1b6afa6..da2e3ab 100644
--- a/BuildTimeAnalyzer.xcodeproj/project.pbxproj
+++ b/BuildTimeAnalyzer.xcodeproj/project.pbxproj
@@ -454,9 +454,17 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ AUTOMATION_APPLE_EVENTS = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
+ ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
+ ENABLE_RESOURCE_ACCESS_CAMERA = NO;
+ ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
+ ENABLE_RESOURCE_ACCESS_LOCATION = NO;
+ ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO;
INFOPLIST_FILE = BuildTimeAnalyzer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -465,6 +473,12 @@
MACOSX_DEPLOYMENT_TARGET = 26.0;
PRODUCT_BUNDLE_IDENTIFIER = uk.co.canemedia.BuildTimeAnalyzer;
PRODUCT_NAME = "$(TARGET_NAME)";
+ RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO;
+ RUNTIME_EXCEPTION_ALLOW_JIT = NO;
+ RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO;
+ RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO;
+ RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO;
+ RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = NO;
SWIFT_OBJC_BRIDGING_HEADER = "";
};
name = Debug;
@@ -473,9 +487,17 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ AUTOMATION_APPLE_EVENTS = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
+ ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
+ ENABLE_RESOURCE_ACCESS_CAMERA = NO;
+ ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
+ ENABLE_RESOURCE_ACCESS_LOCATION = NO;
+ ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO;
INFOPLIST_FILE = BuildTimeAnalyzer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -484,6 +506,12 @@
MACOSX_DEPLOYMENT_TARGET = 26.0;
PRODUCT_BUNDLE_IDENTIFIER = uk.co.canemedia.BuildTimeAnalyzer;
PRODUCT_NAME = "$(TARGET_NAME)";
+ RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO;
+ RUNTIME_EXCEPTION_ALLOW_JIT = NO;
+ RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO;
+ RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO;
+ RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO;
+ RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = NO;
SWIFT_OBJC_BRIDGING_HEADER = "";
};
name = Release;
diff --git a/BuildTimeAnalyzer/Info.plist b/BuildTimeAnalyzer/Info.plist
index 7f529ac..84e5d89 100644
--- a/BuildTimeAnalyzer/Info.plist
+++ b/BuildTimeAnalyzer/Info.plist
@@ -26,6 +26,10 @@
$(MACOSX_DEPLOYMENT_TARGET)
NSHumanReadableCopyright
Copyright © 2016 Cane Media Ltd. All rights reserved.
+ NSAppleEventsUsageDescription
+ BuildTimeAnalyzer needs to control Xcode to jump to the selected file and line.
+ NSAccessibilityUsageDescription
+ BuildTimeAnalyzer needs Accessibility to jump to the selected file and line.
NSMainStoryboardFile
Main
NSPrincipalClass
diff --git a/BuildTimeAnalyzer/ViewController.swift b/BuildTimeAnalyzer/ViewController.swift
index 2bae11d..bc2abfc 100644
--- a/BuildTimeAnalyzer/ViewController.swift
+++ b/BuildTimeAnalyzer/ViewController.swift
@@ -76,7 +76,9 @@ class ViewController: NSViewController {
}
@objc func windowWillClose(notification: NSNotification) {
- guard let object = notification.object, !(object is NSPanel) else { return }
+ guard let closingWindow = notification.object as? NSWindow,
+ closingWindow == view.window else { return }
+
NotificationCenter.default.removeObserver(self)
processor.shouldCancel = true
@@ -307,25 +309,35 @@ extension ViewController: NSTableViewDataSource {
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
guard let item = dataSource.measure(index: row) else { return false }
- let url = URL(fileURLWithPath: item.path, isDirectory: true)
- NSWorkspace.shared.open(url)
+ let escapedPath = item.path.replacingOccurrences(of: "\"", with: "\\\"")
let gotoLineScript =
"tell application \"Xcode\"\n" +
" activate\n" +
+ " open POSIX file \"\(escapedPath)\"\n" +
"end tell\n" +
"tell application \"System Events\"\n" +
- " keystroke \"l\" using command down\n" +
- " keystroke \"\(item.location)\"\n" +
- " keystroke return\n" +
+ " repeat until (frontmost of process \"Xcode\")\n" +
+ " delay 0.05\n" +
+ " end repeat\n" +
+ " tell process \"Xcode\"\n" +
+ " keystroke \"l\" using command down\n" +
+ " delay 0.2\n" +
+ " keystroke \"\(item.location)\"\n" +
+ " keystroke return\n" +
+ " end tell\n" +
"end tell"
DispatchQueue.global().async {
+ var error: NSDictionary?
if let script = NSAppleScript(source: gotoLineScript) {
- script.executeAndReturnError(nil)
+ script.executeAndReturnError(&error)
+ }
+ if let error = error {
+ print("Failed to jump to line in Xcode: \(error)")
}
}
-
+
return true
}
}