SD and OS X version script

Yeah, so did I at the beginning of this thread! :wink:

Hey Ed,

As JM pointed out Shane thoughtfully provided some ASObjC for that.

I donā€™t happen to like the output though, so I changed it a bit.

use framework "Foundation"
set sysVerStr to ((current application's NSProcessInfo's processInfo()'s Ā¬
   operatingSystemVersionString())'s stringByReplacingOccurrencesOfString:("Version") Ā¬
   withString:"macOS") as text

-Chris

1 Like

Well done, Chris! I like it!

1 Like

Letā€™s incorporate Shaneā€™s bug-fix and let ASObjC do a little more of the work for us.

Only the app-id is needed now.

------------------------------------------------------------------------------
use framework "Foundation"
use framework "AppKit"
------------------------------------------------------------------------------

set appID to "com.latenightsw.ScriptDebugger6"

------------------------------------------------------------------------------

set appNSURL to current application's NSWorkspace's sharedWorkspace()'s URLForApplicationWithBundleIdentifier:appID
set appBundle to current application's NSBundle's bundleWithURL:appNSURL
set appName to (appBundle's infoDictionary()'s objectForKey:"CFBundleName") as text
set appVer to (appBundle's infoDictionary()'s objectForKey:"CFBundleShortVersionString") as text
set appBundleVer to (appBundle's infoDictionary()'s objectForKey:"CFBundleVersion") as text
set sysVer to (current application's NSProcessInfo's processInfo()'s operatingSystemVersionString())
set sysVer to (sysVer's stringByReplacingOccurrencesOfString:("Version") withString:"macOS")
set sysVer to (sysVer's stringByReplacingOccurrencesOfString:("Build ") withString:"") as text
set infoString to appName & space & appVer & " (" & appBundleVer & ") on " & sysVer

return infoString

--> "Script Debugger 6.0.4 (6A198) on macOS 10.12.3 (16D32)"

------------------------------------------------------------------------------

-Chris

Chris,

What do you think of this version. This version seems more straight forward. I also removed the second use framework ā€œFoundationā€ line as well as the use framework ā€œAppKitā€ and use scripting additions since they werenā€™t needed. I put a line between the first and second set of 3 lines because the middle lines are calculating the actual values that will be used while the first 3 lines are determining the the appBundle so those values can be calculated. The last 3 lines calculate the system info and create the output string.

use framework "Foundation"

------------------------------------------------------------------------------

set appID to "com.latenightsw.ScriptDebugger6"

------------------------------------------------------------------------------
--  Determine the application bundle
set appNSURL to current application's NSWorkspace's sharedWorkspace()'s URLForApplicationWithBundleIdentifier:appID
set appBundle to current application's NSBundle's bundleWithURL:appNSURL

-- Calculate the App's name, version and bundle version
set appName to (appBundle's infoDictionary()'s objectForKey:"CFBundleName") as text
set appVer to (appBundle's infoDictionary()'s objectForKey:"CFBundleShortVersionString") as text
set appBundleVer to (appBundle's infoDictionary()'s objectForKey:"CFBundleVersion") as text

-- Calculate the OSX information & create the output string
set procInfo to current application's NSProcessInfo's processInfo()
set sysVer to strings 9 thru -1 of ((procInfo's operatingSystemVersionString()) as text)
set infoString to appName & space & appVer & " (" & appBundleVer & ") on macOS " & sysVer

return infoString

Bill

Hey Bill,

Nothing wrong with that.

Thanks for pointing out the redundant ā€œuseā€ line. (Removed.)

The AppKit line is necessary according to Shane.

I prefer explicit string replacement to gathering position-based strings ā€“ itā€™s more robust and easier to read.

You missed the ā€œBuild ā€ string removal, which I included to match Edā€™s last script above.

On my own system Iā€™d use RegEx find/replace via the Satimage.osax, but this was a good case for simple string-replacement (which is easier for most people to grok).

-Chris

Yep ā€“ NSWorkspace is part of AppKit.

OK, so taking a step back, I hate using commands that I donā€™t understand, and this very simple script is now full of them.

So, hereā€™s a few questions:

Using Billā€™s database, why canā€™t I find any of these commands?

appBundleā€™s infoDictionary()'s objectForKey:ā€œCFBundleNameā€

where can I look up all the things I could get from each of the following:
appBundle;
appBundleā€™s infoDictionary()

Where can I look up what objectForKey (or any other parameter) would work with those?

also, would it be a good idea to include in a comment which framework a specific command requires? At least in sample scripts?

I donā€™t have Billā€™s DB, but ā€œappBundleā€ is just a variable in your script, so I wouldnā€™t expect to find it in any DB or reference.

However, a quick search on ā€œCFBundleNameā€ quickly let me to this page:
Core Foundation Keys

where you will find all of the objectForKey keys that are used in the script.

Shane,

Iā€™m confused. How did the script I modified work without a use framework ā€œAppkitā€? When I finish a script I always take out all the included stuff that isnā€™t needed so only the needed stuff would be left. My system has been if it works without it then itā€™s not needed. I assume later it will cause a problem at some unexpected time.

Bill

Ed,

Billā€™s database does not have a lot Appkit stuff yet and my database is not complete. Iā€™ll add this stuff to the database and post it to this discussion.

objectForKey is in Billā€™s database but infoDictionary is not.

The link to ā€œCore Foundation Keysā€ Jim posted is the page I use. Although I downloaded the page as a web archive to my Mac in case Apple gets rid of the web page some day. They do that from time to time.

Bill

There is nothing wrong with doing that. The question is which way would you include it. List them separately at the top so they can all be seen at once or in the code, either in the code above the line where they are used or to the right of the line, whichever works best.

Bill

Theyā€™re already listed at the top with the ā€œuseā€ line, but it would be helpful if they were noted with the command, before or after.

ā€“Framework

or

ā€“AppKit

I can see how that page would be useful to you and Shane and Jim, but wasnā€™t much help to me.

Ed,

The latest version of the database is A15. Is that the version you used?

Iā€™m not sure what you are referring to. Can you include a picture in a post. Then I can fix that.

The Framework section of the database only searches Frameworks. But the class section searches all classes in the database, for all the Frameworks entered in the database. For now those frameworks are just Foundation and AppKit. The class items list all class items, for all the classes, for all the frameworks, in the database. So if you are looking for a particular class use the class section, but if you are looking for the thing that does the actual work it will be a class item. Classes are are a collection of useful things with abilities related to solving some kind of issue.

For me I mostly just search class items to find what to use. When I find something the database tellā€™s me what class and framework to use when typing in the command. There are times the same class item name will appear in different classes. For this case use the class item with the class that best suits your intended purpose.

The database can do this kind of stuff but you have to break it down. To start with SDBundle is a user created item listed earlier in the discussion. The creation line is listed below.

SDBundle to current application's NSBundle's bundleWithIdentifier:"com.latenightsw.ScriptDebugger6"

So to understand this command you have to understand NSBundleā€™s bundleWithIdentifier. If you look up NSBundle in the class part of the database you will get only class information. It will not talk about the things in the class. So to understand the line you look up bundleWithIdentifier. Now if Billā€™s database was more complete it would have had bundleWithIdentifier in it and you would have got your answer. But lucky for you I know the guy who created the database so I can get him to add that. If it was in there then you could see an explanation and samples.

Bill

Iā€™m on version 14. I must have missed the announcement for 15. Can you post a link?

[quote=ā€œBillKopp, post:52, topic:436ā€]
How did the script I modified work without a use framework ā€œAppkitā€?[/quote]

Itā€™s probably not strictly needed in this case because the host app has already loaded it, and youā€™re not using any of the stuff defined in itā€™s bridgesupport file.

Iā€™m not exactly sure what a use statement fully does AppleScript-wise ā€“ itā€™s not documented anywhere. I donā€™t know whether terminology gets cached at the component level or higher. And although Iā€™d be interested to know, this is one of the places Iā€™m quite happy to take the advice of the engineers responsible, which is always to include a use statement for every framework whose classes or methods you use. Itā€™s no great burden, itā€™s a simple rule to follow, and these days hardly takes any time.

Are you allowing for the fact that the results of loading it earlier might have been cached?

Thereā€™s an argument to be made that perhaps we should just start using use framework "Cocoa", because that encapsulates Foundation and AppKit. But I think the appearance of AppKit often serves as a sort of heads-up that perhaps something a bit different is being done.

I like that.
Is there any downside to having a use framework statement even if you donā€™t really need it? Does it slow things down?

When ASObjC was introduced in 10.9, there was a definite pause as stuff was loaded the first time (that is, say, the first time you ran any ASObjC script in an editor). But I really havenā€™t noticed it since.

Terminology-wise, AppKit is very big ā€“ much bigger than Foundation ā€“ so if itā€™s going to show up anywhere, thatā€™s where itā€™s likely to be.

Iā€™m not sure how you can time it, though. In 10.9 it was in the order of a second or two, so it was obvious.