I'm observing NSWorkspaceDidDeactivateApplicationNotification notification to get the application that has just lost focus. I'm ending up with an instance of NSRunningApplication which you get from the userInfo dictionary key - NSWorkspaceApplicationKey - of the notification object.
I was thinking that I'd be able to get the main window from the app from the notification but I'm not sure where to go from here as NSRunningApplication seems to pretty limited. Any help would be appreciated.
BTW - I'm using MacRuby but the answer doesn't need to be in MacRuby.
Thanks
Apple has traditionally been pretty locked-down about this sort of thing. NSRunningApplication itself was just introduced in 10.6, and as you said, it's a bit limited. Depending on what you want to do, the answer might be in the Accessibility framework or it might be the CGWindow API. You can use the processIdentifier from the NSRunningApplication to match it up with those APIs.
It's very difficult to get the main window of other apps; they're not even guaranteed to be Cocoa! They can be either Carbon or Java, or Qt, or Mono... So there's no way you can get NSWindow of another app, unless you do a hack. You can try Accessibility API to get the window info etc. of other apps independently of the framework used, but it's not so easy to use.
Unless the application opts to participate in IAC via AppleScript support or some other means, you simply don't touch its windows or anything else outside of your own heap space.
Related
I'm trying to iterate through a user's photo library on OS X. On iOS, I would use the Photos framework, but apparently that's not available on OS X, and we're supposed to use the Media Library framework instead. However, while I was able to use the code linked above to get access to a MLMediaSource object, I'm having a hard time figuring out how to iterate through the photo assets.
The Media Library Framework documentation makes reference to a mediaObjectForIdentifier: method, which sounds promising, but doesn't indicate what sort of identifiers should be used. I'm fairly experienced with iOS, but a complete n00b on OS X, so I'm feeling a little lost.
If I just wanted to iterate through a user's library, NSLog'ing each photo, how might I go about that? Either using the Media Library Framework, or another framework so long as it works for the current Photos library?
This framework isn't hard to work with, but it is tedious because it async/lazy loads the properties, and KVO is the only want to be notified about the async completion.
If you want to iterate the photos, you don't need to know the identifiers in advance.
Create a media library:
self.library = [[MLMediaLibrary alloc] initWithOptions:options];
Add a KVO observer for mediaSources. Access mediaSources, if non-nil, go to the next step, otherwise go to the next step when your KVO observer fires.
In the next step, iterate the sources, add a KVO observer on rootMediaGroup, and access rootMediaGroup on each source. If it is non-nil, call your iterator now, otherwise call it from the KVO notification handler.
For each rootMediaGroup, follow the same strategy as above, but for mediaObjects. The media objects are the things you are ultimately after.
My question is based on the fact that, one might have multiple smaller projects and then wants to integrate them into one bigger one, for coding efficiency.
I saw multiple project's where the App Delegate wasn't used at all, I think the Adium project was one of them. I also was a couple of times able to recreate it in the past, now I cannot remember how.
I figure a basic NSObject inherited class would fit, plus its instantiation and connections.
The question is, is it possible to work without App Delegate (or have a workaround)?
You need an app delegate, if you want to implement some of the methods declared in the NSApplicationDelegate protocol to respond to certain app life-cycle events. If you don't need to implement any of those, you don't need an app delegate. Some delegate methods also have notification alternatives.
OK, from your comment...
I mean having no additional code in AppDelegate
Then yes.
It is not only possible, it is recommended. Exactly for the reason that you have said.
The app delegate is there as a communication layer between the app and the OS. i.e. "the app has started", "the app is about to close", "the app just received a notification", etc...
All of these is what the app delegate is for.
The logic of your app should not go anywhere near you app delegate. Like you said, you may have different apps or different targets in your app that use different app delegates.
If you have code in there then you would have to duplicate it to each copy.
There are many other reasons too.
Here is a quick link... http://www.hollance.com/2012/02/dont-abuse-the-app-delegate/
There are many others about not using the app delegate.
Is there a way to find a Zombie at runtime in objective-c?
I'm looking for a way to prevent an object to call a method on a zombie, is there any way to detect one without making the app crash?
I do know about weak reference under ARC iOS5 and common sense programming practice.
I was thinking that a way could be asking the object size (I know that maybe "inside" there are just reference) but if the object still exist it should give a value, if it doesn't probably just the single pointer size.
Using malloc_size(pointerToObject)
Could it work?
UPDATE:
I do know how to run Instruments for Zombies detection
I don't think Andrea is asking how to run instruments to detect zombies, I think she wants to guard against calling a dealloced instance at runtime. I'm not sure what malloc size will return in this case. I think anything you come up with short of what they've done with NSZombies (which is to never truly free instances) will be gimicky and only work part of the time. I think your best best is the boring old diligent programming and profiling with instruments to guard against making these calls rather than trying to catch the error at runtime.
Try running the application with Instruments, and select the "Zombies" template.
On the scheme menu (upper left, next to run/stop). Select "Edit Scheme...". A sheet will appear. Select the Run/Debug scheme there. Select the "Diagnostics" tab on the center pane. Check Zombies.
I am new to mac os X development ,I downloaded an open source mac application ,but i couldn't able to understand the flow of execution of cocoa program.so any one can explain the program flow of a general cocoa program briefly.
Thanks in advance
Start in main. It's not likely to contain anything interesting, but worth checking just in case. Most probably, it will contain only a call to NSApplicationMain, which will create the NSApplication object and send it a run message. That's what gets the application running, and this method will run for the rest of the rest of the process.
Then look in the MainMenu nib. Loading this is one of the first things the application will do. Any windows here that are set as “Visible on Launch” will come up immediately; more importantly, the application delegate will probably be here. Check the application's or File's Owner's (the application is both of them in this nib, so you need to check both) delegate outlet, and if one of them is connected, follow the connection. See what class that object is an instance of.
Once you've found the application delegate class, open it up in Xcode. Look through the list of application delegate methods and find which ones are implemented, and read the ones that are. The application:…FinishLaunching: twins will be particularly important at the start of the process.
From there, it's all just reading code, seeing what it does, and going where it takes you.
Peter's answers are good - I'd also say to check for implementations of 'awakeFromNib', especially for object loaded from MainMenu.nib. You often find interesting things stashed away in that method, rightly or wrongly.
I'm still working on my problem that an NSView in NSMenuItem is not receiving any notification when the user chooses it by pressing the return key.
For this i want to log all methods which are called on an Objective-C object.
Can i do this in some way without using a debugger?
Not easily, no, and probably not the most effective way to debug this anyway. If it isn't receiving a notification, it is likely that no method is being called.
You could build a proxy class that forwards all methods and then plug that in, logging as it forwards. See the documentation for NSProxy for more information.
But, again, not the best way to debug this.
Do you have a separate question regarding the views, menus, and notifications? (I didn't obviously find one).