Get name of (external) display - objective-c

I'm trying to get the name of the connected external display with Cocoa or CoreFoundation. With "name" I mean that string that appears in the title bar of the System Preferences window when editing Display preferences.
I couldn't find any API for that in NSScreen or in the Quartz Display Services.
But there has to be a way, because if I access the color space of the display like this:
CGColorSpaceRef colorSpace = CGDisplayCopyColorSpace(displayID);
and I log the color space's description I get:
<CGColorSpace 0x100113c20>
(kCGColorSpaceICCBased; kCGColorSpaceModelRGB; DELL 2408WFP)

I found a solution in an other thread (I wonder why I didn't find that before...).
I updated it to be ARC compatible:
- (NSString *)screenNameForDisplay:(CGDirectDisplayID)displayID {
NSString *screenName = #"";
NSDictionary *deviceInfo = (__bridge NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
if ([localizedNames count] > 0) {
screenName = [localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]];
}
return screenName;
}

Related

PHPhotoLibrary getting album and photo info

I am trying to get info on all the albums/photos using the PHPhotoLibrary. I barely know objective C, and i've looked at some tutorial/sample but couldn't find everything that I needed.
Here is a link to the sample code I based my code on.
https://developer.apple.com/library/ios/samplecode/UsingPhotosFramework/Introduction/Intro.html#//apple_ref/doc/uid/TP40014575-Intro-DontLinkElementID_2
So far I was able to get the albums name and identifier. And I am getting a list of photos, I am able to get their identifier as well, but not the filename. But if I put a break point in my fonction and look at my PHAsset pointer values, I can see the filename there (inside _filename), but if I try to call the variable with the filename in it, the variable does not exist.
So if anyone can provide a sample code to get all info on albums/photos/thumbnail that would be awesome. Or just getting the filename would be a good help.
Here is the code I have tried so far:
-(void)awakeFromNib{
NSMutableArray *allPhotos = self.getAllPhotos;
for (int x = 0; x < allPhotos.count; x ++)
{
PHAsset *photo = [self getPhotoAtIndex:x];
PHAssetSourceType source = photo.sourceType;
NSString *id = photo.localIdentifier;
NSString *description = photo.description;
NSUInteger height = photo.pixelHeight;
NSUInteger width = photo.pixelWidth;
NSLog(#"Test photo info");
}
}
-(PHAsset*) getPhotoAtIndex:(NSInteger) index
{
return [self.getAllPhotos objectAtIndex:index];
}
-(NSMutableArray *) getAllPhotos
{
NSMutableArray *photos = [[NSMutableArray alloc] init];
PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
allPhotosOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *allPhotos = [PHAsset fetchAssetsWithOptions:allPhotosOptions];
PHFetchResult *fetchResult = #[allPhotos][0];
for (int x = 0; x < fetchResult.count; x ++) {
PHAsset *asset = fetchResult[x];
photos[x] = asset;
}
return photos;
}
As you can see, I can get the image height and width, its id, but cannot get the url to it.
I have found a way to get the url of my photo.
-(void)getImageURL:(PHAsset*) asset
{
PHContentEditingInputRequestOptions *options = [[PHContentEditingInputRequestOptions alloc] init];
[options setCanHandleAdjustmentData:^BOOL(PHAdjustmentData *adjustmentData) {
return [adjustmentData.formatIdentifier isEqualToString:AdjustmentFormatIdentifier] && [adjustmentData.formatVersion isEqualToString:#"1.0"];
}];
[asset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info)
{
NSURL* url = contentEditingInput.fullSizeImageURL;
}];
}
Filenames in the Photos library are an implementation detail and subject to change. There are various private API for discovering them (or ways to use valueForKey or other public introspection APIs to find where they're hidden), they aren't something to be relied upon. In particular, an asset that's been edited is likely to have a different filename than the original.
What do you need a filename/URL for? If you're just uniquely identifying the asset across launches of your app, use localIdentifier. If you're showing it to the user... why? Something like IMG_0234.jpg vs IMG_5672.jpg has little meaning to the average user.
To fetch the assets in a specific album, use fetchAssetsInAssetCollection:options:. To fetch the album(s) containing a specific asset, use fetchAssetCollectionsContainingAsset:withType:options:. To discover the list(s) of albums, use other APIs on PHAssetCollection and its superclass PHCollection.

string not populating with array data, even though arrays are not really empty

I am trying to create a non-Document-based application for Mac OS X that randomizes cards for the game of Dominion.
From many of the ones I have tried, the only thing I cannot seem to do is limit the number of sets picked from a selection made by the user, and things worked pretty well in my program, but I am having issues.
I am trying to get the results to print in a custom view, but every time I look at the print preview, nothing shows, except header text, as specified in an NSMutableString.
This piece of code is what is being used to print and is found in MasterViewController:
- (IBAction)print:(id)sender
{
NSMutableString *content = [[NSMutableString alloc] initWithString:#"Cards\r\n\r\n"];
for (int i = 0; i < [supply.game count]; i++)
{
[content appendFormat:#"Card: %# Set: %# Cost: %d\r\n", [supply.game[i] name], [supply.game[i] collection], [supply.game[i] cost]];
}
[content appendFormat:#"\r\n\r\nRequired\r\n\r\n"];
for (int i = 0; i < [[setup supply] count]; i++)
{
NSDictionary* current = [setup supply][i];
NSString* key = [current allKeys][0]; // get the key of the current dictionary must be 0, as there is only one key
int value = [[current valueForKey:key] integerValue]; // variable to hold key value
if (value > 0) {
[content appendFormat:#"%#: %#", key, #"Yes"];
}
else
{
[content appendFormat:#"%#: %#", key, #"No"];
}
}
printView.content = [NSMutableString stringWithString:content];
[printView print:sender];
}
the data initially gets filled into some tableviews, which displays the correct content, and the supply.game array is the exact array that contains cards used for games.
setup is a property that refers to a view controller that populates a table with kinds of cards that may be required for games (e.g. shelters, colonies, ruins, spoils, and potions) and the supply method is supposed to return the array that view controller creates, which is itself not empty, as that table populates properly.
printView is a property that is assigned to a custom view found in MainMenu.xib and is the real view being used to print from.
the printView class looks like this:
header:
#import <Cocoa/Cocoa.h>
#interface PrintView : NSView
{
NSMutableString* content;
}
#property NSMutableString* content;
- (void)drawStringInRect:(NSRect)rect; // method to draw string to page
- (void)print:(id)sender; // method to print
#end
implementation:
#import "PrintView.h"
#implementation PrintView
#synthesize content;
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)print:(id)sender
{
[[NSPrintOperation printOperationWithView:self] runOperation];
}
- (void)drawRect:(NSRect)dirtyRect {
NSGraphicsContext *context = [NSGraphicsContext currentContext];
if ([context isDrawingToScreen])
{
}
else
{
[[NSColor whiteColor] set];
NSRect bounds = [self bounds];
if (content == nil || [content length] == 0)
{
NSRectFill(bounds);
}
else
{
[self drawStringInRect:bounds];
}
}
}
- (void)drawStringInRect:(NSRect)rect
{
NSSize strSize; // variable to hold string size
NSPoint strOrigin; // variable used to position text
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSFont fontWithName:#"Helvetica" size:12] forKey:NSFontAttributeName];
[attributes setObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName];
strSize = [content sizeWithAttributes:attributes];
strOrigin.x = rect.origin.x + (rect.size.width - strSize.width)/2;
strOrigin.y = rect.origin.y + (rect.size.height - strSize.height)/2;
[content drawAtPoint:strOrigin withAttributes:attributes];
}
#end
When I check the array sizes for printing operation, the size of the arrays is reported as zero, thus resulting in my current problem
If you need more code, here is code from Github, but I do not have the experimental branch up there, which is where the above code came from, though it should not be too different.
The MasterViewController will show how the supply.game array is made and SetupViewController houses the code that is used to determine what is needed in the game, as well as show how the supply array from [setup supply] is being produced.
MasterViewController has also been added as an object to MainMenu.xib, so I do not know if that affects anything.
Any idea of what I need to do?
Edit: Added in info that might be relevant

Making a simple quiz game. Stuck with the arrays part

I'm trying to make a game with 2 views, the first view has buttons which segues to another view. Depending on the segue identifier, it loads an image which the player has to guess.
I also have a an array which lists hints for the 4 images.
With the array, i made a button which shows the hints on the view, but the problem I have right now is that I don't know how to set the correct array to the image/puzzle.
A code that works right now is this:
if ([self.thePuzzle.name isEqual: #"lion"])
{
NSArray *hints = [lines[0] componentsSeparatedByString:#" "];
self.hintLabel.text = hints[0];
}
But after adding another line for the second image/puzzle, the app crashes.
2nd UPDATE: code that crashes
After entering this code
if ([self.thePuzzle.name isEqual: #"penguin"])
{
NSArray *hints = [lines[1] componentsSeparatedByString:#" "];
self.hintLabel.text = hints[1];
}
The hint button works for the 1st code, which has the lion picture, while the second part of the code, for the penguin pic, crashes when the Hint button is pressed.
3rd Update: Additional information
I made xcode access a file from the internet which contained the words for my array.
This is how i coded it.
[super viewDidLoad];
// Do any additional setup after loading the view.
self.imageView.image = [UIImage imageNamed:self.thePuzzle.imgFileName];
NSString *urlString = #"http://m.uploadedit.com/b032/1395295852132.txt";
NSString *contents = [TextFileManager readStringFromURL:urlString];
//parse contents
lines = [contents componentsSeparatedByString:#"\n"];
for( int i = 0; i < lines.count; i++)
{
NSString *line = lines[i];
NSLog(#"%d: %#", i, line);
}

Read from iPhoto Library programmatically

I want to create an Application that connects to the iPhoto Library. So now I would like to read the Events and the pictures themselves from the library.
Is there an elegant / easy way to do this or do I have to manually read the Bundle Structure of the iPhoto User Data?
So far I have only found a picture taker: Is there a UIImagePicker for the Mac Desktop
Update: I found another relevant SO post: Selecting iPhoto images within a cocoa application
You can do it with NSAppleScript. This is some copy/paste from my app, hacked up a bit just to show the idea.
NSAppleEventDescriptor d = .. compile this script ..
#"tell application \"iPhoto\" to properties of albums"
for (int i = 0; i < [d numberOfItems]; i++)
{
NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];
// <NSAppleEventDescriptor: 'ipal'{
// 'ID ':4.265e+09,
// 'purl':'utxt'("http://www.flickr.com/photos/..."),
// 'pnam':'utxt'("Vacation"),
// 'alTy':'pubs',
// 'alCh':[ ],
// 'alPx':'msng' }>
NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
NSString *albumId = [[albumDesc descriptorForKeyword:'ID '] stringValue];
You can do the same thing to find the images
NSString *scp =
[NSString stringWithFormat:#"tell application \"iPhoto\" to properties of photos of album id %#",
[album objectForKey:#"id"]];
NSAppleEventDescriptor *d = ... compile scp ...
// 1 based!?
for (int i = 1; i <= [d numberOfItems]; i++)
{
NSAppleEventDescriptor *photoDesc = [d descriptorAtIndex:i];
// Yes.. this happens. Not sure why?!
if (!photoDesc)
continue;
// <NSAppleEventDescriptor: 'ipmr'{
// 'pnam':'utxt'("IMG_0058.JPG"),
// 'pwid':768,
// 'pdim':[ 768, 1024 ],
// 'alti':1.79769e+308,
// 'filn':'utxt'("3133889525_10975ba071_b.jpg"),
// 'ipth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"),
// 'idat':'ldt '($F57C69C500000000$),
// 'rate':0,
// 'titl':'utxt'("IMG_0058.JPG"),
// 'phit':1024,
// 'itpt':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Thumbnails/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg.jpg"),
// 'ID ':4.295e+09,
// 'lati':'msng',
// 'pcom':'utxt'(""),
// 'opth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"),
// 'lngt':'msng',
// 'tiln':'utxt'("3133889525_10975ba071_b.jpg.jpg") }>
NSString *path = [[photoDesc descriptorForKeyword:'ipth'] stringValue];
NSString *imgname = [[photoDesc descriptorForKeyword:'pnam'] stringValue];
If releasing apps on the App Store you are now required now required to use the Sandbox, this stops the previous AppleScript method from working (the iPhoto app launches but an empty set is returned).
iPhoto libraries consist of a directory structure containing photos, databases and XML files. The contents changes with each version of iPhoto so be careful if manually accessing these files.
If you just want the album details you can parse the file AlbumData.xml
If you would like photos you can browse the Masters folder. The files structure follows date rather than by the sets configured in iPhoto.
More information can be found on the internals of the iPhoto library here:
http://www.fatcatsoftware.com/iplm/Help/iphoto%20library%20internals.html
The majority of the databases are in SQLite format and so can be programmatically accessed through Objective C, though again you can expect schema changes between different versions of iPhoto. The main databases of interest are Library.apdb and Properties.apdb in Database/apdb.
If you still want to use the Apple Script method, here's a version of the previous answer with the Apple script execution part included:
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:#"tell application \"iPhoto\" to properties of albums"];
NSAppleEventDescriptor *d = [script executeAndReturnError:nil];
NSLog(#"photo library count: %ld", (long)[d numberOfItems]);
for (int i = 0; i < [d numberOfItems]; i++)
{
NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];
NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
NSLog(#"%#", albumName);
}

How do I get the details of an application using Objective-C?

I have the following code to detect the current window. How can I get 1) application internal name, 2) location, 3) publisher and 4) description of the window/application?
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//Get info about the currently active application.
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
NSDictionary* currentAppInfo = [workspace activeApplication];
//Get the PSN of the current application.
UInt32 lowLong = [[currentAppInfo objectForKey:#"NSApplicationProcessSerialNumberLow"] longValue];
UInt32 highLong = [[currentAppInfo objectForKey:#"NSApplicationProcessSerialNumberHigh"] longValue];
ProcessSerialNumber currentAppPSN = {highLong,lowLong};
//Grab window information from the window server.
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
ProcessSerialNumber myPSN = {kNoProcess, kNoProcess};
//Loop through the windows, the window list is ordered from front to back.
for (NSMutableDictionary* entry in (NSArray*) windowList)
{
int pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
GetProcessForPID(pid, &myPSN);
//If the process of the current window in the list matches our process, get the front window number.
if(myPSN.lowLongOfPSN == currentAppPSN.lowLongOfPSN && myPSN.highLongOfPSN == currentAppPSN.highLongOfPSN)
{
NSNumber *windowNumber = [entry objectForKey:(id)kCGWindowNumber];
windowNumber = [entry objectForKey:(id)kCGWindowNumber];
NSString* applicationName = [entry objectForKey:(id)kCGWindowOwnerName];
NSLog(#"Capture the window: %# with window ID: %#.",applicationName,windowNumber);
return applicationName;
//Break because we only want the front window.
break;
}
}
CFRelease(windowList);
[pool release];
You should use the ProcessInformationCopyDictionary function from the Process Manager API. Give it &myPSN and kProcessDictionaryIncludeAllInformationMask as arguments and you will get the information you are looking for.
I was looking for something related with this topic. I need a WindowRef of the window or window part at a certain location (mouse position) and it has to be over all the windows of all running applications...
I´ve tried it with Carbon (´Cos my App is entirely written in C++) but I´ve found that Some Carbon Functions Doesn´t work properly (MacFindWindow, FindWindow, HIWindowFindAtLocation, FindWindowOfClass, HIWindowGetCGWindowID...)
Maybe I´m doing it wrong, It´s difficult to believe that those Carbon functions won´t work any more in 64 bits architectures...
So, related with your question I found the same code and I tried this but it isn´t what I need, I hope it helps you in any way and I´ll keep searching and trying till I get it (If the O.S can do it everybody should).
//if the process of the current window in the list matches our process, get the front window number
if(myPSN.lowLongOfPSN == currentAppPSN.lowLongOfPSN && myPSN.highLongOfPSN == currentAppPSN.highLongOfPSN)
{
NSNumber* windowNumber = [entry objectForKey:(id)kCGWindowNumber];
NSString* applicationName = [entry objectForKey:(id)kCGWindowOwnerName];
NSLog(#"The current app is %# and the window number of its front window is %#.",applicationName,windowNumber);
CGRect bounds;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[entry objectForKey:(id)kCGWindowBounds], &bounds);
NSLog(#"WINDOW RECT BOUNDS; (x,y,width, height) = (%d,%d, %d, %d)", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
break;
}
Also, follow this link, I´t will help you. I´m sure:
http://code.google.com/p/blazingstars/source/browse/trunk/PokerHK/HKLowLevel.m?r=70