Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

twoodcc

macrumors P6
Original poster
Feb 3, 2005
15,307
26
Right side of wrong
ok, i want to make a mac program that keeps track of your computer's uptime, keep a record uptime, and maybe average uptime and more statistics if possible.

i have taken a few programming courses, but only matlab, visual basic, and C#, so they don't really help me with this one.

i have gone through a few mac tutorials, but they weren't like the program i want.

i know there is a widget called "show-off" that basically does this, but i have computers on panther, and i just want to make my own program

if anyone could help me get started, i'd really appreciate it. i don't really know how to start this

thanks in advance
 
ok, i want to make a mac program that keeps track of your computer's uptime, keep a record uptime, and maybe average uptime and more statistics if possible.

The easiest way to do it is with an AppleScriptStudio application.

inside of the idle handler say

set timewords to every word of (do shell script "uptime")
set timewords to every word of (do shell script "uptime")
set uptime to (item 4 of timewords) * days + (item 6 of timewords) * hours + (item 7 of timewords) * minutes
 
The easiest way to do it is with an AppleScriptStudio application.

inside of the idle handler say

set timewords to every word of (do shell script "uptime")
set timewords to every word of (do shell script "uptime")
set uptime to (item 4 of timewords) * days + (item 6 of timewords) * hours + (item 7 of timewords) * minutes

A simple obj-C application will use less CPU resource than applescript, but assuming you have a modern Mac (fast G4/G5/Intel) you'll be OK, from experience an applescript application (on an iMac G5) uses about 0.3% CPU while sleeping.
 

thanks for the link. have you used this book before yourself?

The easiest way to do it is with an AppleScriptStudio application.

inside of the idle handler say

set timewords to every word of (do shell script "uptime")
set timewords to every word of (do shell script "uptime")
set uptime to (item 4 of timewords) * days + (item 6 of timewords) * hours + (item 7 of timewords) * minutes

thanks. so if i copy and paste this into an AppleScriptStudio application, it will work? or do i need to change it some?

A simple obj-C application will use less CPU resource than applescript, but assuming you have a modern Mac (fast G4/G5/Intel) you'll be OK, from experience an applescript application (on an iMac G5) uses about 0.3% CPU while sleeping.

well i would be running this on a G4 mac mini.....so any help in speed would be nice
 
As an Amazon Associate, MacRumors earns a commission from qualifying purchases made through links in this post.
thanks. so if i copy and paste this into an AppleScriptStudio application, it will work? or do i need to change it some?

The code I gave will generate the uptime as seconds but won't do anything useful with it. You will need code to store it some place and calculate useful information with it.

A straight cocoa solution would be much more efficient but not easier.
 
The code I gave will generate the uptime as seconds but won't do anything useful with it. You will need code to store it some place and calculate useful information with it.

A straight cocoa solution would be much more efficient but not easier.

ok thanks. i'll see what i can come up with
 
The code I gave will generate the uptime as seconds but won't do anything useful with it. You will need code to store it some place and calculate useful information with it.

A straight cocoa solution would be much more efficient but not easier.

well i got it working. but it doesn't do anything yet. what do you think would be the best way to display the uptime on the screen?
 
well i'm gonna be honest here, i've tried to do this, but i'm not really sure how to go about it. could you help me out with it?


thanks in advance

I was away at WWDC and not watching the forums.

Did you end up with the Cocoa solution or the AS solution.

For AS
set contents of text field "Foo" to timewords

The text field has to be named "Foo" in Applescript in Interface Builder for this to work.



For Cocoa
[myTextField setStringValue:timeWords];

The text field has to be connected to an IBOutlet on the class you are working on.
 
I was away at WWDC and not watching the forums.

Did you end up with the Cocoa solution or the AS solution.

For AS
set contents of text field "Foo" to timewords

The text field has to be named "Foo" in Applescript in Interface Builder for this to work.



For Cocoa
[myTextField setStringValue:timeWords];

The text field has to be connected to an IBOutlet on the class you are working on.

thanks. i'm trying the AS version.

i did what you said, but nothing is showing up in the text box. i set it to uneditable. is that a problem? i don't want to be able to type in the box
 
thanks. i'm trying the AS version.

i did what you said, but nothing is showing up in the text box. i set it to uneditable. is that a problem? i don't want to be able to type in the box

Uneditable is fine, you have to make sure the box is being pointed too correctly from the code.
 
well i need some help here. first, i tried to use the code that was given to me in this thread in applescript studio, but i couldn't figure out how to put it in a textbox.

the last 2 nights i've been working with a few other members on a cocoa application that does the same thing, and none of us can figure out how to get the uptime. we tried this, but it doesn't work right:

Code:
double newVar = currentTimeAsDuration;
	
	NSString *Astring = [NSString stringWithFormat:@"%f", newVar]; 	
	
	double value = [Astring intValue]; 

	double inSeconds = value * .0001; //mili-sec
	double inMinutes = inSeconds / 60; //sec-min
	double inHours = inMinutes / 60; //min-hour
	
	NSString *string = [NSString stringWithFormat:@"%f", inHours];
	
	NSString *hoursExtract = [string substringToIndex:1];
	NSString *minutesExtract = [string substringWithRange:NSMakeRange(2,2)];
	NSString *secondsExtract = [string substringWithRange:NSMakeRange(4,2)];
	
	NSString *finalString = [NSString stringWithFormat:@"%@h %@m %@s", hoursExtract, minutesExtract, secondsExtract];
	
	
	[textField setStringValue:finalString]

so if anyone can help, that would be great.

thanks
 
well me and rev316 got it to display your uptime correctly.

now the next step is to keep a record of your best (longest) uptime.

can anyone help us out with that? storing data is a little over my head right now

thanks
 
Could you post your whole Xcode project here? I can't really see from the snippet above what is going on...

Also, do you only want to store the longest uptime, or do you want more detailed stats?
 
Could you post your whole Xcode project here? I can't really see from the snippet above what is going on...

Also, do you only want to store the longest uptime, or do you want more detailed stats?

here is the updated code:

Code:
#import "uptimeApp.h"

@implementation uptimeApp


- (IBAction)createTime:(id)sender
{
	AbsoluteTime currTime; 
	currTime = UpTime();
	
    float currentUptime = (float)AbsoluteToDuration(currTime);
	if (0.0f > currentUptime) // negative means microseconds
	currentUptime /= -1000000.0f;
    else // positive means milliseconds
	currentUptime /= 1000.0f;

    int days = 0;
	
    float currentUptimeinMinutes = currentUptime / 60;
    
   	int hours = (int)currentUptimeinMinutes / 60; //get hours	
  	int diffHinMin = hours * 60; //find the minutes of the hours	
  	int minutes = currentUptimeinMinutes - diffHinMin; //difference to get minutes
  	 	
    if (minutes > 59)
  	{
        hours += 1;
        minutes = 0;
    }
  	
  	if (hours > 23)
  	{
        days = hours / 24;
        hours = hours % 24;
    }
  	
    NSString *string = [NSString stringWithFormat:@"%dd %dh %dm", days, hours, minutes];
	[textField setStringValue:string];  // display it in our outlet
}    
@end

thanks. well, eventually we would like to hold more stats if possible, like your last 10 uptimes or something.
 
Here's my solution. I've changed the name of your class to AppController, because it makes more sense (and starts with a capital letter!).

AppController.h:

Code:
#import <Cocoa/Cocoa.h>


@interface AppController : NSObject
{
	IBOutlet NSTextField *textField;
}

- (IBAction)createTime:(id)sender;

- (NSNumber *)longestRecordedUpTime;
- (NSArray *)lastTenRecordedUpTimes;
@end

AppController.m:
Code:
#import "AppController.h"

NSString *MBLongestRecordedUpTime = @"MBLongestRecordedUpTime";
NSString *MBLastTenRecordedUpTimes = @"MBLastTenRecordedUpTimes";


@interface NSNumber (MBUpTimeAdditions)

+ (id)currentUpTime;
- (NSString *)formattedUpTimeString;
@end


@implementation AppController

- (IBAction)createTime:(id)sender;
{
	NSNumber *currentUpTime = [NSNumber currentUpTime];
	[textField setStringValue:[currentUpTime formattedUpTimeString]];
	
	if ([[NSUserDefaults standardUserDefaults] objectForKey:MBLongestRecordedUpTime] == nil || [currentUpTime compare:[[NSUserDefaults standardUserDefaults] objectForKey:MBLongestRecordedUpTime]] == NSOrderedDescending)
		[[NSUserDefaults standardUserDefaults] setObject:currentUpTime forKey:MBLongestRecordedUpTime];
		
	NSMutableArray *lastTenUpTimes = [[[NSUserDefaults standardUserDefaults] objectForKey:MBLastTenRecordedUpTimes] mutableCopy];
	if (lastTenUpTimes == nil)
		lastTenUpTimes = [[NSMutableArray alloc] initWithCapacity:10];
	[lastTenUpTimes insertObject:currentUpTime atIndex:0];
	if ([lastTenUpTimes count] > 10)
		[lastTenUpTimes removeLastObject];
	[[NSUserDefaults standardUserDefaults] setObject:lastTenUpTimes forKey:MBLastTenRecordedUpTimes];
	[lastTenUpTimes release];
}

- (NSNumber *)longestRecordedUpTime;
{
	return [[NSUserDefaults standardUserDefaults] objectForKey:MBLongestRecordedUpTime];
}

- (NSArray *)lastTenRecordedUpTimes;
{
	return [[NSUserDefaults standardUserDefaults] objectForKey:MBLastTenRecordedUpTimes];
}

@end


@implementation NSNumber (MBUpTimeAdditions)

+ (id)currentUpTime;
{
	return [self numberWithUnsignedLongLong:UnsignedWideToUInt64(AbsoluteToNanoseconds(UpTime())) / 1000000000];	// UpTime in seconds
}

- (NSString *)formattedUpTimeString;
{
	unsigned days = [self unsignedLongLongValue] / (60 * 60 * 24);
	unsigned hours = ([self unsignedLongLongValue] / (60 * 60)) % 24;
	unsigned minutes = ([self unsignedLongLongValue] / 60) % 60;
	
	return [NSString stringWithFormat:@"%ud %uh %um", days, hours, minutes];
}

@end
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.