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

S0ULphIRE

macrumors newbie
Original poster
Jun 6, 2009
6
0
With a lot of help from google, I've managed to put together a simple program which shows the user their IP Address when they select the 'Refresh IP' box from the program's dropdown menu.

It gets and displays the correct IP, but there's one small problem. The name of the menu isn't showing correctly.

screenshot20100428at103.png


As you can see in the image, half the IP is cut off on the top of the bar. I have no idea what's causing this and would appreciate any help! I don't usually program in Cocoa, so go easy on me :)

Also (separate issue I think) after this line, NSLog won't work anymore:
NSData *data = [file readDataToEndOfFile];
I've included an example in the AppController.m file

The xcode project is attached. I used xcode 3.2.2 on OSX 10.6.3
Let me know if you need any more details

Thanks!
Mike
 

Attachments

  • Project.zip
    19 KB · Views: 76
It's because you have a newline (\n) character at the end of the string. You can use -[NSString stringByTrimmingCharactersInSet:] with +[NSCharacterSet whitespaceAndNewlineCharacterSet] to trim.

As for the NSLogs not showing after the task executes, I suspect your task setup code is not properly coded. It's too early for me to debug but I dropped in this function that's a variation of a method that I've been using for years now with no problems, and couldn't reproduce the issue.
Fake edit: I removed my setStandardInput: line and got the same issue. I'm not sure exactly what's going on, maybe someone else can explain.

Code:
int executeTask(NSString *taskPath, NSArray *args, NSData **outputData)
{
	NSTask *task = nil;
	NSPipe *inPipe = nil, *outPipe = nil;
	NSFileHandle *outHandle = nil;
	int status;
	
	if ((taskPath == nil) ||
		([[NSFileManager defaultManager] fileExistsAtPath:taskPath] == NO) ||
		([[NSFileManager defaultManager] isExecutableFileAtPath:taskPath] == NO))
	{
		// task doesn't exist or isn't executable!
		return 1;
	}
	
	task = [[NSTask alloc] init];
	[task setLaunchPath:taskPath];
	if ((args != nil) && ([args count] > 0))
	{
		[task setArguments:args];
	}
	
	// NSPipe can return nil
	outPipe = [[NSPipe alloc] init];
	if (outPipe != nil)
	{
		outHandle = [outPipe fileHandleForReading];
		[task setStandardOutput:outPipe];
		[task setStandardError:outPipe];
	}
	
	inPipe = [[NSPipe alloc] init];
	if (inPipe != nil)
	{
		[task setStandardInput:inPipe];
	}
	
	[task launch];
	
	if (outHandle != nil)
	{
		if (outputData)
			*outputData = [outHandle readDataToEndOfFile];
		[outHandle closeFile];
	}
	
	[task waitUntilExit];
	status = [task terminationStatus];
	
	[outPipe release];
	[inPipe release];
	[task release];
	
	return status;
}

Here's the modified GetIpAddress: method:

Code:
NSData *data = nil;
NSArray *args = [NSArray arrayWithObjects: @"-c", @"ifconfig en0 | grep \"inet \" | cut -f2 -d\" \"", nil];
if (executeTask(@"/bin/sh", args, &data) == EXIT_SUCCESS) {
	NSString *output = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
	ipaddress = [[output stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] retain];
}
else
	ipaddress = [NSLocalizedString(@"Error", nil) retain];
 
Thanks for that! Much appreciated :)
I added a setStandardInput line in my code as well and it resolved the NSLog issue too...strange...

Would you know a way to test if the 'ipaddress' variable is blank? E.g. doesn't contain an IP address string? I tried the below but it didn't work. Unplugging the mac from the network still doesn't make the if statement evaluate to true, so it just bypasses it.
Code:
	if (ipaddress == NULL) {
		ipaddress = @"NO IP SET";
	}
Cheers,
Mike
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.