I need that my application detect how many files has been dropped to it dock icon. For this i use application:openFiles: method
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
NSLog(#"%d",[filenames count]);
}
But unfortunately files sometimes separates by group. So, for example i dragged 3 files to dock icon and get this output:
2
1
How could it be?
Unfortunately that's life. If you really need to count the number of files received in a drop to the Dock icon, you need to set up a timer to combine the results received by the call application:openFiles: within a second (or some appropriate length of time.)
Related
I'm trying to use the "top" command in MacOS X to determine which app is using the resources.
When I do:
top -stats "pid,command"
the command column is truncated, if the process name is too long.
if you look at the activity monitor, the process name is shown properly (with full name) + icon. My questions are:
how to get the full process name?
sometimes the app icon show next to the process name, is there anyway to do the similar thing using objective-c? should I simply navigate to the app contents folder and grab the icns image?
First, if you're trying to get the data programmatically, driving top is almost definitely not what you want to do.
But, to answer your direct questions:
how to get the full process name?
There is no way to control the truncation of commands. You can use the -ncols parameter to set the width of the output for non-interactive output, but that doesn't stop top from truncating if it wants to.
sometimes the app icon show next to the process name, is there anyway to do the similar thing using objective-c? should I simply navigate to the app contents folder and grab the icns image?
No. How would you deal with apps that have multiple .icns files, e.g., for document icons? (Try it with iTunes, for example. If you pick the first .icns, you get the AIFF document icon; if you pick the last, you get the internal-use recent TV shows icon.)
The right way to do it is to get the NSBundle for the application, then do something like this:
NSString *iconFile = [bundle objectForInfoDictionaryKey:#"CFBundleIconFile"];
if (iconFile) {
NSString *iconPath = [bundle pathForResource:iconFile ofType:#"icns"];
// load and display the icon
}
So, how do you actually want to do this, if not by driving top?
Well, what you're asking for is actually not a well-defined thing. OS X has four different notions of task/process/program/application that don't correspond 1-to-1, and that makes life difficult if you want to write a mashup of two programs that use different notions—e.g., top deals in BSD processes, while Activity Monitor deals in OS X applications.
If what you actually want is the same list top uses, it's open source, so you can read it and do the same thing it does.
But the simplest way to get the list of BSD processes is probably the interfaces in libproc.h, in particular proc_listallpids and proc_pidinfo. For example:
int dump_proc_names() {
int buf[16384];
int count = proc_listallpids(&buf, 16384*sizeof(int));
for (int i = 0; i != count; ++i) {
int pid = buf[i];
char path[MAXPATHLEN+1] = {0};
int ret = proc_pidinfo(pid, PROC_PIDPATHINFO, 0,
&path, sizeof(path));
if (ret < 0) {
printf("%d: error %s (%d)\n", pid, strerror(errno), errno);
} else {
printf("%d: %s\n", pid, path);
}
}
}
Obviously in real code you're going to want to allocate the buffer dynamically, return the values instead of just dumping them, get more than just the paths, etc. But this is enough to give you the basic idea. (When you go to get additional information, be aware that you if you ask for any struct, you will get an EPERM error unless you have rights to see every member of that struct. So, don't go asking for PROC_PIDTASKALLINFO if you only want PROC_PIDT_SHORTBSDINFO.
Anyway, since this API deals with BSD processes (and Mach tasks), not applications, it won't directly help you get at the NSBundle you want to provide Activity Monitor-style features.
There is no way to do this that's entirely correct, but you can probably get away with something like this:
NSString *path = processPath;
while (path && ![path isEqualTo:#"/"]) {
NSBundle *bundle = [NSBundle bundleWithPath:path];
if (bundle) {
if ([bundle executablePath != processPath]) return nil;
return bundle;
}
path = [path stringByDeletingLastPathComponent];
}
There are probably alternative ways to do this, each with different tradeoffs. For example, using -[NSWorkspace runningApplications], storing the results in a dictionary mapping the bundle executable path to the bundle, and using that to look up each process is simple, but it only seems to be useful for applications owned by the current user (and probably in the current session). On the other hand, enumerating all bundles on the system, or asking Spotlight, or similar would probably be too slow to do on the fly, but would go out of date if you cached them on first run.
Another option, in place of libproc, is to use libtop.
Unfortunately, Apple doesn't provide it. They do have a libtop implementation, which they use for their top tool, but it's actually embedded in the source to top and not available from outside. You can find the source (at the link above) and embed it into your program the same way top itself does.
Alternatively, both GNU and BSD process utilities have Mac ports (although knowing which name to use with Homebrew/MacPorts/Google search isn't always easy…), so you could build one of those and use it.
However, unless you're trying to write cross-platform software (or already know how to write this code for linux or FreeBSD or whatever), I think that just adds extra complexity.
I am writing a iPhone app that calls a web service. Let say the web service returns 1000 elements in the json object. I don't want to load all 1000 of them since parsing can take some time. What I would like to do is load the first 15 elements of the NSDictionary that I created from the json object and then when the user scrolls to the bottom of the tableview have a 16th row that says "load more....". Since I already have all of the data stored in the NSDictionary object is there a way to break this up so that it returns the 15, then the user clicks "load more...." and it loads the next 15 and continues until there are no more elements in the NSDictionary? I can present examples of my code but I am wondering if anyone has an example of how to accomplish this. Thanks in advance for any assistance.
i think a UITableView does this for you. Only the visible cells are ever constructed. Their memory is then swapped with the next rows as you scroll down. I don't see a point in re-inventing the wheel.
Also as a note, only the visible cells are "parsed" as you put it. It will not construct a cell for every item in your datasource on load.
Assuming I hear you correctly I would say you just need a little tricky logic to get this working
I would simply maintain an index offset which I would multiply by the amount of rows you want to show at any time(15 in your case)
Your logic is to always return the amount of rows that you want to allow + 1 for the final. ex: return _indexOffset * 15 + 1; //for your numberOfRowsForSection
In your didSelectIndexPathOf you check if you're the last row:
if(indexPath.row == _indexOffset * 15)
{
_indexOffset ++;
[tableView reloadData];
}
This isn't an exact answer but I think it can get you started
I'm trying to build something that will only fire a command once per keyboard input (as opposed to every frame like QC does natively). In order to do so, I'm trying to listen in on the keyboard inputs (via Freeboard) and compare the current input versus a previous version.
What seems to be happening is the previous version is getting wiped every time the patch executes, so my conditional to compare strings is failing every time. Here's some code to make it a bit clearer:
- (BOOL)execute:(id <QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary *)arguments
{
self.outputPrevious=previousCharacter;
if ([self.inputCharacter caseInsensitiveCompare:previousCharacter]){
self.outputText=#"SAME";
}
else {
self.outputText=#"CHANGE";
}
previousCharacter = [NSString stringWithString:self.inputCharacter];
[previousCharacter retain];
return YES;
}
where self.outputText is the text that tells me the result of the if, self.outputPrevious is telling me what the previous character input was, and self.inputCharacter is the current keyboard input.
previousCharacter is defined in the header and instantiated in -init, so it shouldn't be being reset every time.
I've tried pretty much everything with this, so if you have any ideas or insights, that would be awesome. Thanks!
Figured it out eventually. Full solution can be found here
I have a UIActionSheet that I created Dynamically and it can have a number of buttons from 1 to 5 including cancel button. I can get the cancel button to work fine but lets say that only 2 buttons are need to be added onto the UIActionSheet, lets say they buttons 2 and 4 how do I determine which action to carry out. Cause normally I would use something like.
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch(buttonIndex) {
case 0:
// Do something here.
break;
case 1:
// Do something else here.
break;
case 2:
// Do something else again.
break;
case 3:
// Do something else here again.
break;
default:
break;
}
But if I only add two buttons dynamically there only going to use cases 0, 1. But if I add button 4 as one of the two buttons I still want it to use case 3. Is this possible or is there another way of doing it?
Use the buttonTitleAtIndex: method to check against the buttons' titles. You have to take care that your code won't break if you change a button's title in one place, though. It's probably best to save each button's title in an extra variable when you create the buttons and use this variable to compare with the button titles later.
When you create the UIActionSheet, keep a separate array mapping your button indexes to the actual tasks you want to perform (an actions enumeration, for example).
Then switch on tasks[buttonIndex] instead of buttonIndex.
I was wondering if there is an effective way to debug problems in xcode while coding in Objective-C. I create webpages constantly and code in jquery and javascript where you can set various alert boxes in different places in your code to determine if your script is properly executing sections. Can you do something like that in xcode to make sure that your script is executing methods properly and creating variables properly?
Thanks
Use the debugger - that's what it is there for! Set breakpoints by clicking in the grey are next to the line of code you want to break on. When this line of code is going to be excuted, the debugger will kick in and highlight the current place in execution. You can hover the cursor over variables in the IDE to examine their values, view the current call-stack (to see here this code has been called from) and get a list of local variables to help track program state. You can modify variable properties here too which often makes debugging simpler.
Execute code line by line by 'Stepping Over' (cmd+shift+o), which executes the current line, 'Stepping Into' (cmd_shift+i) which steps into the current line of code (if it is a function), or 'Stepping Out' to return back up the call stack.
If you want to stick to 'old-school' printf style debugging, go with NSLoging output to console.
NSLog(#"this text appears");
prints the following to the console:
this text appears
To print some basic variable values:
CGFloat pi = 3.14;
NSString *aFloatString = [NSString stringWithFormat:#"%.2f", pi];
NSLog(#"pi is equal to: %#", aFloatString);
Prints:
pi is equa to: 3.14
Standard c formatters can be used in NSLog i.e %d for int, %.2f for a float to 2 decimal places etc. Use %# for NSString*s.
Remember that NSLog will remain in production code unless you #IFDEF it out of release builds (or something similar), so if you don't want a performance hit, or embarrassing console logs to accompany the app you will want to remove them.
I've been known to litter functions that dump the following to console - and it isn't good:
OUTPUT:
Number of vertices is: 1200
<Requested reduction>
Can I kick it?
....
....
YES. I. CAN!
Number of vertices is: 800
Could have done with removing things like that :|
yes, the debugger can do all the things you want to do (just set some breakpoints - right click where you want them - then build&debug)
You can try writing to the console.
NSLog(#"Some status message here");
NSLog(#"The value of myObject is:%#", myObject);
To view the output of your application, while running with Xcode, click Run->Console and you will see all of the output from your application.