tldr: Changing the "Optimize for Speed" Swift Compiler setting from "No Optimization [-Onone]
" to "Optimize for Speed [-O]
" causes a string typecast to fail
Background
I am using a function from this StackOverflow answer in a program that I am making. It finds the url of an open TextEdit document
Problem
When I try to run my program with optimization turned on it crashes on this line
let filePath = result as! String
I am trying to find out how to get the String
from the result
variable.
The strange thing is that I can print the result
variable to the console even if Optimize for Speed [-O]
is on
How to reproduce
- Download the project here
- Ensure the app is not sandboxed
- Give the app accessibility permissions
- Open a TextEdit document and save it to disk
- Run app
Image of XCode with the No Optimization [-Onone]
setting
Image of XCode with the
Optimize for Speed [-O]
setting on
AppDelegate.swift Code
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
getOpenTextEditDocument()
}
}
func getOpenTextEditDocument() -> URL? {
// https://stackoverflow.com/questions/49076103/swift-get-file-path-of-currently-opened-document-in-another-application
if AXIsProcessTrusted() == false {
print("No Accesability Permissions")
return nil
}
let textEditIdentifier = "com.apple.TextEdit"
let TextEditApp : NSRunningApplication? = NSRunningApplication
.runningApplications(withBundleIdentifier: textEditIdentifier).last as NSRunningApplication?
if let pid = TextEditApp?.processIdentifier {
var result = [AXUIElement]()
var windowList: AnyObject? = nil // [AXUIElement]
let appRef = AXUIElementCreateApplication(pid)
if AXUIElementCopyAttributeValue(appRef, "AXWindows" as CFString, &windowList) == .success {
result = windowList as! [AXUIElement]
}
var docRef: AnyObject? = nil
guard let result_first = result.first else { return nil }
if AXUIElementCopyAttributeValue(result_first, "AXDocument" as CFString, &docRef) == .success {
let result = docRef as! AXUIElement
let filePath = result as! String
print("filePath = \(result)")
let filePathURL = URL(string: filePath)
return filePathURL
}
}
return nil
}