Yeah, so did I at the beginning of this thread!
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
Well done, Chris! I like it!
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.