Monday, December 9, 2019

#1 2009-11-08 08:30:32 pm

bensonang
Member
Registered: 2008-06-03
Posts: 50

Help: Using AppleScript to remove dock icon

I'm currently stuck, to remove a Dock icon, I know I need to edit the dock.plist. Problem is, I dont know how.
What is the easiest way to remove the dock icon with applescript? I cannot find any sources on the internet.

I used this code to add a folder to the dock

Applescript:


do shell script "defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Applications/myApp.app/</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'"

I wonder if I can just alter this code to remove it?  is so, how?

I've been stuck with this problem for almost a week. any help will be very much appreciated.
Thanks


Filed under: applescript, dock, remove

Offline

 

#2 2019-08-09 07:59:16 am

KniazidisR
Member
Registered: 2019-03-03
Posts: 764

Re: Help: Using AppleScript to remove dock icon

Here is the AppleScriptObjC code, but it has 1 error and don't work yet:

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property NSString : a reference to NSString of current application
property NSUserDefaults : a reference to NSUserDefaults of current application
property NSDictionary : a reference to NSDictionary of current application

set DockIconLabel to "VLC"
set DockIconLabel to NSString's stringWithString:DockIconLabel

set userDefaults to NSUserDefaults's standardUserDefaults()
set dockDict to userDefaults's persistentDomainForName:"com.apple.dock"
set dockApps to dockDict's valueForKey:"persistent-apps"

repeat with anApp in dockApps
   set fileDict to (anApp's valueForKey:"tile-data")
   set iconLabel to (fileDict's valueForKey:"file-label")
   if DockIconLabel = iconLabel then
       (dockApps's removeObject:anApp)
       NSUserDefaults's resetStandardUserDefaults
       exit repeat
   end if
end repeat

This code is my first attempt to convert Objective C code to AppleScriptObjC. The Objective C source is HERE. The error is related to this code line (something with mutable array):

Applescript:

(dockApps's removeObject:anApp)

I don't know how to fix that. Need help.
Other Objective-C example is without repeat loop, but I don't know preidcate's syntax as well:

Applescript:

(BOOL)removeApplicationFromDock:(NSString *)name {
NSDictionary *domain = [self persistentDomainForName:@"com.apple.dock"];
NSArray *apps = [domain objectForKey:@"persistent-apps"];
NSArray *newApps = [apps filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"not %K CONTAINS %@", @"tile-data.file-data._CFURLString", name]];
if (![apps isEqualToArray:newApps]) {
NSMutableDictionary *newDomain = [domain mutableCopy];
[newDomain setObject:newApps forKey:@"persistent-apps"];
[self setPersistentDomain:newDomain forName:@"com.apple.dock"];
return [self synchronize];
}

Last edited by KniazidisR (2019-08-09 08:28:08 am)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#3 2019-08-09 08:37:37 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3670

Re: Help: Using AppleScript to remove dock icon

@KniazidisR

Not sure but maybe you would have to trigger
userDefaults's registerDefaults

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 9 aout 2019  16:36:05

Offline

 

#4 2019-08-09 09:42:55 am

KniazidisR
Member
Registered: 2019-03-03
Posts: 764

Re: Help: Using AppleScript to remove dock icon

I fixed the script but the icon remains in the Dock:

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property NSString : a reference to NSString of current application
property NSUserDefaults : a reference to NSUserDefaults of current application
property NSDictionary : a reference to NSDictionary of current application

set DockIconLabel to "VLC"
set DockIconLabel to NSString's stringWithString:DockIconLabel

set userDefaults to NSUserDefaults's standardUserDefaults()
set dockDict to userDefaults's persistentDomainForName:"com.apple.dock"
set dockApps to dockDict's valueForKey:"persistent-apps"
set newDockApps to dockApps's mutableCopy()

repeat with anApp in dockApps
   set fileDict to (anApp's valueForKey:"tile-data")
   set theLabel to (fileDict's valueForKey:"file-label")
   if (theLabel's isEqualTo:DockIconLabel) then
       (newDockApps's removeObject:anApp)
       exit repeat
   end if
end repeat

NSUserDefaults's resetStandardUserDefaults()

What else am I missing? Please, help.

Last edited by KniazidisR (2019-08-09 10:13:09 am)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#5 2019-08-09 10:29:49 am

KniazidisR
Member
Registered: 2019-03-03
Posts: 764

Re: Help: Using AppleScript to remove dock icon

Yvan Koenig wrote:

@KniazidisR

Not sure but maybe you would have to trigger
userDefaults's registerDefaults

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 9 aout 2019  16:36:05


Thanks for reply, but what should be syntax in my script? This throws error:

Applescript:

userDefaults's registerDefaults

Last edited by KniazidisR (2019-08-09 10:30:20 am)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#6 2019-08-09 11:24:12 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3670

Re: Help: Using AppleScript to remove dock icon

Look at message #12 in:
https://macscripter.net/viewtopic.php?id=30476

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 9 aout 2019  19:24:08

Offline

 

#7 2019-08-09 12:34:42 pm

KniazidisR
Member
Registered: 2019-03-03
Posts: 764

Re: Help: Using AppleScript to remove dock icon

Yvan Koenig wrote:

Look at message #12 in:
https://macscripter.net/viewtopic.php?id=30476

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 9 aout 2019  19:24:08


I registered dictionary changes - I replaced the last code line with the following, but the icon remains on the Dock. 

Applescript:


dockDict's setObject:newDockApps forKey:"persistent-apps"
userDefaults's registerDefaults:dockDict

So. There is only one way to solve the problem - the GUI sctipting ... I will provide a solution soon, although this is not what I was hoping for ...

Last edited by KniazidisR (2019-08-09 01:11:44 pm)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#8 2019-08-09 02:19:07 pm

KniazidisR
Member
Registered: 2019-03-03
Posts: 764

Re: Help: Using AppleScript to remove dock icon

GUI scripting variant (work fine):

Applescript:


set theAppToRemoveName to "VLC" -- for testing purposes

tell application "System Events"
   
   if (application process theAppToRemoveName exists) then
       set theMenuItemName to "Keep in Dock"
   else
       set theMenuItemName to "Remove from Dock"
   end if
   
   tell application process "Dock"
       try
           tell list 1 to tell UI element theAppToRemoveName
               perform action "AXShowMenu"
               click menu item "Options" of menu 1
               click menu item theMenuItemName of menu 1 of menu item "Options" of menu 1
           end tell
       on error
           display dialog "The Script should be terminated.
        The App with specified name doesn't exist on the Dock."
buttons "OK"
           return
       end try
   end tell
   
end tell

NOTE:  if the app is running, then its icon will be removed when you quit this app.

Last edited by KniazidisR (2019-08-09 02:28:11 pm)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#9 2019-08-09 06:35:06 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6064

Re: Help: Using AppleScript to remove dock icon

KniazidisR wrote:

What else am I missing?



You're missing the way defaults work. The defaults system is like a database. You can make changes, but you have no control over when apps read it. Some values they might read repeatedly, and others they just read the first time they need them.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#10 2019-08-09 08:11:22 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5118

Re: Help: Using AppleScript to remove dock icon

KniazidisR wrote:

I fixed the script but the icon remains in the Dock:

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property NSString : a reference to NSString of current application
property NSUserDefaults : a reference to NSUserDefaults of current application
property NSDictionary : a reference to NSDictionary of current application

set DockIconLabel to "VLC"
set DockIconLabel to NSString's stringWithString:DockIconLabel

set userDefaults to NSUserDefaults's standardUserDefaults()
set dockDict to userDefaults's persistentDomainForName:"com.apple.dock"
set dockApps to dockDict's valueForKey:"persistent-apps"
set newDockApps to dockApps's mutableCopy()

repeat with anApp in dockApps
   set fileDict to (anApp's valueForKey:"tile-data")
   set theLabel to (fileDict's valueForKey:"file-label")
   if (theLabel's isEqualTo:DockIconLabel) then
       (newDockApps's removeObject:anApp)
       exit repeat
   end if
end repeat

NSUserDefaults's resetStandardUserDefaults()

What else am I missing? Please, help.


Hi KniazidisR .

The current Xcode documentation says that resetStandardUserDefaults() has no effect and shouldn't be used.

Here's my own literal translation and correction of the Objective C source to which you linked. It seems to work:

Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

on removeDockItem(dockItemName)
   set dockItemName to current application's class "NSString"'s stringWithString:(dockItemName)
   
   set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
   set dockDict to (userDefaults's persistentDomainForName:("com.apple.dock"))'s mutableCopy() -- Seems to be mutable anyway.
   set apps to (dockDict's valueForKey:("persistent-apps"))
   if (apps's |count|() > 0) then -- More likely than 'if (apps is not missing value) …' ?
       set appsCopy to apps's mutableCopy()
       set |modified| to false
       repeat with anApp in appsCopy
           set fileDict to (anApp's valueForKey:("tile-data"))
           if (fileDict is not missing value) then
               set appName to (fileDict's valueForKey:("file-label"))
               if (appName's isEqualToString:(dockItemName)) then
                   tell appsCopy to removeObject:(anApp)

                   set |modified| to true
                   exit repeat
               end if
           end if
       end repeat
       
       if (|modified|) then
           tell dockDict to setValue:(appsCopy) forKey:("persistent-apps") -- Added.
           tell userDefaults to setPersistentDomain:(dockDict) forName:("com.apple.dock")
           -- current application's class "NSUserDefaults"'s resetStandardUserDefaults() -- Legacy. Shouldn't be used.
           tell application "Dock" to quit -- Possibly a bit extreme.
       end if
   end if    
end removeDockItem

removeDockItem("Launchpad")

However, less literally, it's possible to use a predicate instead of a repeat:

Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

on removeDockItem(dockItemName)
   set dockItemName to current application's class "NSString"'s stringWithString:(dockItemName)
   
   set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
   set dockDict to (userDefaults's persistentDomainForName:("com.apple.dock"))'s mutableCopy() -- Seems to be mutable anyway.
   set apps to (dockDict's valueForKey:("persistent-apps"))
   if (apps's |count|() > 0) then
       set filter to current application's class "NSPredicate"'s predicateWithFormat:("%K != %@") argumentArray:({"tile-data.file-label", dockItemName})
       set appsCopy to apps's filteredArrayUsingPredicate:(filter)
       
       if (appsCopy's |count|() < apps's |count|()) then
           tell dockDict to setValue:(appsCopy) forKey:("persistent-apps")
           tell userDefaults to setPersistentDomain:(dockDict) forName:("com.apple.dock")
           tell application "Dock" to quit -- Possibly a bit extreme.
       end if
   end if
end removeDockItem

removeDockItem("Launchpad")


NG

Offline

 

#11 2019-08-09 08:58:28 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6064

Re: Help: Using AppleScript to remove dock icon

Nigel,

The predicate in your last script is problematic -- it's a sort of double negative. Try removing the first !. As it stands, it's a bit on the destructive side.

(Off to rebuild my Dock...)


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#12 2019-08-09 09:14:47 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6064

Re: Help: Using AppleScript to remove dock icon

Here's Nigel's last script, reworked to use initWithSuiteName: rather than persistentDomainForName:. The advantage is that you don't have to read/write a dictionary for the whole domain, but rather that of a single key. There's probably no discernible difference in this case, but in other cases it could be significant. (I've also changed the predicate as above.)

Applescript:

on removeDockItem(dockItemName)
   set dockDefaults to current application's class "NSUserDefaults"'s alloc()'s initWithSuiteName:"com.apple.dock"
   set apps to dockDefaults's objectForKey:"persistent-apps"
   if (apps's |count|() > 0) then
       set filter to current application's class "NSPredicate"'s predicateWithFormat:("%K != %@") argumentArray:({"tile-data.file-label", dockItemName})
       set appsCopy to apps's filteredArrayUsingPredicate:(filter)
       
       if (appsCopy's |count|() < apps's |count|()) then
           tell dockDefaults to setObject:(appsCopy) forKey:("persistent-apps")
           tell application "Dock" to quit -- Possibly a bit extreme.
       end if
   end if
end removeDockItem

Last edited by Shane Stanley (2019-08-09 09:17:35 pm)


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#13 2019-08-10 01:23:06 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5118

Re: Help: Using AppleScript to remove dock icon

Shane Stanley wrote:

(Off to rebuild my Dock...)


Ouch! Thanks Shane. Sorry about your Dock.  sad  It's a long story involving trying several different things to get the predicate to work, with the eventual solution being to have the key path as an external argument and to leave off "self.". While I was posting the script, I noticed I still had the predicate string as "!(%K == %@)", which I'd changed from "%K != %@" during my experiments. I decided to change it back, but by then it was 03:11 in the morning ….

Now corrected.

Your version of the handler simplifies things a bit!  smile


NG

Offline

 

#14 2019-08-10 02:16:56 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6064

Re: Help: Using AppleScript to remove dock icon

Oh, I'm just glad of the confirmation that these things don't happen just to me smile


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#15 2019-08-10 03:00:27 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11626
Website

Re: Help: Using AppleScript to remove dock icon

Nigel Garvey wrote:

It's a long story involving trying several different things to get the predicate to work



By the way you can use the old underscore syntax to simulate the ObjC form:

Applescript:

set filter to current application's class "NSPredicate"'s predicateWithFormat_("%K != %@", "tile-data.file-label", dockItemName)


regards

Stefan

Offline

 

#16 2019-08-10 03:45:39 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5118

Re: Help: Using AppleScript to remove dock icon

Thanks, Stefan. That looks as if it could be slightly more efficient than the form with argumentArray:. It would certainly look better when there's only one argument!  smile


NG

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)