2

I am trying to get the urls that a browser like safari has open (for each window). Currently, I get all of the running apps on my Mac and pull out the safari app, so I can get it as an 'NSRunningApplication'. Further, I am trying to find the file that an app like Final Cut Pro has open for all of its instances.

Then I use the following code to try and get the urls from the Safari browser:

if AXUIElementCopyAttributeValue(appReference, "AXURL" as CFString, &urls) == .success {
                        let url = urls as! [AXUIElement]
                    print("url = \(url)")
                }

The code that I use to try and get the document of Final Cut Pro instance is (not sure how to get the document for each instance of the program):

if AXUIElementCopyAttributeValue(appReference, "AXDocument" as CFString, &doc) == .success {
                        let docReference = doc as! [AXUIElement]
                    print("docReference = \(docReference)")
                }

this code only returns an array of 'AXUIElement' that I am not sure how to get a url out of it.

Any ideas on what I might be missing to pull the current urls that the safari browser has open? Also any idea on what I might be missing to pull the file for each instance (window) of a given program? I would like to get all of the urls from each window and somehow distinguish which window is which (E.g., use an array of arrays with urls in them).

Please note that I was trying not to use apple script, but if you know of a good solution and how I might integrate it into my swift app I would love to hear about it.

Nighthawk
  • 772
  • 11
  • 21
  • Tip 1: use the accessibility Inspector (Developer Tool) to inspect the hierarchy. You'll see BrowserApplication -> BrowserWindow -> TabBarView -> TabButton and no URL. Maybe it's not possible to get the URL this way. – Willeke Mar 14 '22 at 11:54
  • Tip 2: Use `kAXURLAttribute` instead of `"AXURL"`. See the definition in `AXAttributeConstants.h`: "Value: A CFURLRef. Required for elements that represent a disk or network item.". `urls` would be a `UnsafeMutablePointer` – Willeke Mar 14 '22 at 12:02
  • Tip 3: Play around with the Process Suite (uses the Accessibility API) of System Events in ScriptEditor. `get properties` and `get entire contents` can help to figure out the path of an element. – Willeke Mar 14 '22 at 12:13
  • AppleScript solution: [Get current URL from browser in macOS](https://stackoverflow.com/questions/42369202/get-current-url-from-browser-in-macos) – Willeke Mar 14 '22 at 12:16
  • Thank you @Willeke. Any ideas on how I would get all of the urls for a given window using either swift or apple script? – Nighthawk Mar 14 '22 at 23:52
  • 1
    All urls will be something like `set myURLs to the URL of the tabs of window x`. – Willeke Mar 15 '22 at 08:32
  • Thank you @Willeke. Would you know how I would be able to make an array of arrays made up of the urls for each window (where each window has its own array of urls inside of an array) with apple script? – Nighthawk Mar 15 '22 at 23:38
  • What are you trying to accomplish? Do you want to mimic Saved Application State? – Willeke Mar 16 '22 at 07:21
  • @Willeke yes I would like to mimic the saved application state so if needed I can open those same apps later with their same state (windows and tabs/files) – Nighthawk Mar 16 '22 at 11:42
  • If you don't mind a hacky solution for personal use then it might be easier to switch saved state files – Willeke Mar 17 '22 at 10:16
  • @Willeke what do you mean by switching saved state files? – Nighthawk Mar 17 '22 at 12:24
  • The Saved Application State is saved in files. Files can be moved, duplicated, deleted, replaced. Take a look at `~/Library/Containers/com.apple.Safari/Data/Library/Saved Application State/com.apple.Safari.savedState/` – Willeke Mar 17 '22 at 12:55
  • I would look into the property kAXURLAttrubte. It is better to use than "AXURL" – Red Lion Mar 22 '22 at 01:07

1 Answers1

-1

With AppleScript, You can use NSAppleScript in Swift.

Example:

set r to "" -- an empty variable for appending a string
tell application "Safari"
    repeat with w in windows -- loop for each window, w is a variable which contain the window object
        if exists current tab of w then --  is a valid browser window
            repeat with t in tabs of w -- loop for each tab of this window, , t is a variable which contain the tab object
                -- get the title (name) of this tab and get the url of this tab
                tell t to set r to r & "Title : " & name & ", URL : " & URL & linefeed -- append a line to the variable (r)
                (*
                 'linefeed'  mean a line break
                 'tell t' mean a tab of w (window)
                 '&'  is for  concatenate strings, same as the + operator in Swift
                *)
            end repeat
        end if
    end repeat
end tell
return r -- return the string (each line contains a title and an URL)

The AppleScript will return a string, like this:

Title : the title of the first tab, URL : the url of the first tab
Title : the title of the second tab, URL : the url of the second tab
Title : the title of the third tab, URL : the url of the third tab
....

Sreeram Nair
  • 2,369
  • 12
  • 27
  • 2
    Thank you, however, this apple script does not seem to be giving a similar output as above when put into a swift program and using NSAppleScript – Nighthawk Mar 16 '22 at 23:12