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.