I am working on Mac OS X. How do I find out names of running applications in foreground as well as in background?
You can get all running applications with NSWorkSpace
NSArray *runningApplications = [[NSWorkspace sharedWorkspace] runningApplications];
The array contains instances of NSRunningApplication
Assuming you mean hidden with background and visible with foreground - the equivalent to the ⌘H shortcut in an application menu – you can filter the array with a predicate
NSPredicate *visiblePredicate = [NSPredicate predicateWithFormat:#"hidden == NO"];
NSPredicate *hiddenPredicate = [NSPredicate predicateWithFormat:#"hidden == YES"];
NSArray *visibleApplications = [runningApplications filteredArrayUsingPredicate:visiblePredicate];
NSArray *hiddenApplications = [runningApplications filteredArrayUsingPredicate:hiddenPredicate];
NSLog(#"%#", visibleApplications);
NSLog(#"%#", hiddenApplications);
To determine which application is currently active, filter with the active property.
NSPredicate *activePredicate = [NSPredicate predicateWithFormat:#"active == YES"];
NSArray *activeApplications = [runningApplications filteredArrayUsingPredicate:activePredicate]; // actually it's always an array containing one application
NSLog(#"%#", activeApplications[0]);
Related
My program automates a radio station. There is lots of communication back and forth between it and iTunes. I programmed it with scripting bridge. Scripting bridge suffers from memory leaks. Each call to scripting bridge leaks a small amount of memory. Add a lot of calls to a program that runs 24/7 and I've got software that will run for something less than 24 hours, and then quit.
My first attempt at a solution was to minimize my calls to scripting bridge. In researching that end, I came across ItunesLibrary. It isn't working for me.
NSError *error = nil;
ITLibrary *library = [ITLibrary libraryWithAPIVersion:#"1.0" error:&error];
if (library)
{
NSArray *playlists = [[NSArray alloc]init];
playlists = library.allPlaylists;
NSArray *tracks = [[NSArray alloc]init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"mediaKind == %d", ITLibMediaItemMediaKindSong];
tracks = [library.allMediaItems filteredArrayUsingPredicate:predicate];
NSLog(#"Playlists - %#",playlists);
NSLog(#"Tracks - %#",tracks);
}
This code is pretty much right out of Apple's docs. It should work - I think.
Before I added the predicate, I got some info on each of the podcasts in my iTunes library. In the nslog output, each of my playlists produces an entry similar to "". Each of my songs shows nothing more than (null).
All of the info is in iTunes. I can read it with scripting bridge. I can read it with AVAsset
AVAsset *asset = [AVURLAsset URLAssetWithURL:myUrl options:nil];
NSArray *metadata = [asset commonMetadata];
for ( AVMetadataItem* item in metadata )
{
NSString *key = [item commonKey];
NSString *value = [item stringValue];
NSLog(#"key = %#, value = %#", key, value);
}
With AVAsset I only get the song name, album name, and artist name. I need to access the rest of iTune's ID3 tags.
What have I don to break ItunesLibrary?
The secret to getting ItunesLibrary to work seems to be in the entitlements file. You need to add the key "com.apple.security.assets.music.read-only", and set it to YES. I got this by digging through a project on github.com.
This is the way the docs say to get all media items from library, however I want to get only the songs.
#import <iTunesLibrary/ITLibrary.h>
ITLibrary *library = [ITLibrary libraryWithAPIVersion:#"1.0" error:&error];
if (library)
{
tracks = library.allMediaItems; // <- NSArray of ITLibMediaItem
}
I found this answer: How to get all tracks from an album using iTunes.h/Scripting Bridge
I'm not sure how to adapt it to do what I need it to, or maybe it is less complicated now?
tracks = library.allMediaItems; is a NSArray of ITLibMediaItem objects.
According to the doc, it as a property mediaKind that gives it the item is a song (ITLibMediaItemMediaKindSong) or another kind of media.
So, you just have to use the predicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"mediaKind == %d", ITLibMediaItemMediaKindSong]]
So to filter (with previous predicate)
tracks = [library.allMediaItems filteredArrayUsingPredicate:predicate];
I am trying to launch the built-in calculator.app on my Mac(which means it is external to my application) within my application and force the calculator to stay frontmost permanently on screen.
Here is my process. Firstly, I launch the calculator and place it frontmost temporarily.
if ([[NSWorkspace sharedWorkspace] respondsToSelector:#selector(launchApplicationAtURL:options:configuration:error:)])
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:#"/Applications/Calculator.app/Contents/MacOS/Calculator" isDirectory:NO]
options:NSWorkspaceLaunchDefault
configuration:nil
error:NULL];
After that, I recognize the Calculator by it's owner name and try to pin Calculator.app frontmost. I was stuck here. What I would like to do is either these two ways:
1.Set an attribute to place it always frontmost. (Can't find suitable
attribute, only found attributes to resize or position)
2.Get the NSWindow of Calculator and set the level to frontmost. (Seems to be non-viable: How to convert a Carbon AXUIElementRef to Cocoa NSWindow)
But seems that both of them are not available.
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
NSArray *arr = CFBridgingRelease(windowList);
for (NSMutableDictionary *entry in arr){
NSString *ownerName = [entry objectForKey:(id)kCGWindowOwnerName];
if([ownerName isEqualToString:#"Calculator"]){
pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
AXUIElementRef appRef = AXUIElementCreateApplication(pid);
CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex( windowList, 0);
CFTypeRef role;
AXUIElementCopyAttributeValue(windowRef, kAXRoleAttribute, (CFTypeRef *)&role);
/*Would like to get the window of the application or assign some attribute to set Calculator frontmost*/
}
Are there any ways to achieve the two aspects I've mentioned above? Or are there any suggestions for setting an external application always being frontmost?
I want to get the applications from the cmd+tab menu in OS X. The best way I got now is to associate this with a AppleScript call with the following:
NSDictionary *errorDict;
NSAppleEventDescriptor *returnValue;
NSString *appleScriptText = #"tell application \"System Events\" to get name of (processes where background only is false)";
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:appleScriptText];
Then loop through the stuff coming back from it and to match it to the [[NSWorkspace sharedWorkspace] runningApplications] but this seems a little bit too weird to get this task done.
So my question here: is there a way that is not so quirky like this one?
I am really tense for the answers.
Given that you're already familiar with -[NSWorkspace runningApplications], why don't you just iterate over those and check which ones meet your criteria? The background only property corresponds to NSRunningApplication's activationPolicy property being something other than NSApplicationActivationPolicyRegular.
So, something like (not tested):
NSArray* apps = [[NSWorkspace sharedWorkspace] runningApplications];
NSIndexSet* indexes = [apps indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
return [obj activationPolicy] == NSApplicationActivationPolicyRegular;
}];
NSArray* names = [[apps objectsAtIndexes:indexes] valueForKey:#"localizedName"];
In my project, I implemented core data to save the bulk data under several entities. One of entity is "coupon" and it have nearly 10 attributes. One is username. When the app opens I need to fetch all the entries based on a particular user who logged in. Username is already saved into the core data when the user enters each entry. How can I set the predicate for this? I am new to core data concept. This is how i am fetching the all results under the entity coupon.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"Category BEGINSWITH[c] #"All" and Used == NO"];
[request setPredicate: pred];
NSArray *objects = [context executeFetchRequest:request error:&error];
NSLog(#"%#arry",objects);
if ([objects count]>0) {
[self.couponList addObjectsFromArray:objects];
}
[request release];
Any help or suggestion will be appreciated.Thanks in advance!
Your predicate has wrong syntax. You need to substitute the parameters into the format string.
Also, your predicate seems to have nothing to do with the username. Why?
[NSPredicate predicateWithFormat:#"username = %#", userName];
// or, including your existing predicate:
[NSPredicate predicateWithFormat:#"username = %# &&
category BEGINSWITH[c] %# &&
used == %#",
userName, #"All", [NSNumber numberWithBool:NO]];
Note that I have used category and used with lower initial letters. I assume these are properties of your entity in being fetched, so by convention the first letter should be small.
Also, you could actually also use your version used == NO if you prefer.