• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Running an NSApplication from a test case
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Running an NSApplication from a test case


  • Subject: Re: Running an NSApplication from a test case
  • From: "email@hidden" <email@hidden>
  • Date: Wed, 05 Mar 2014 09:50:57 +0000

On 4 Mar 2014, at 21:27, Daniel Luis dos Santos <email@hidden> wrote:

> Hello all,
>
> I have a test case where I would like to launch a UI. I have a NIB with a window that I load through code in the test case. Here goes the code :
>
> - (void)testExample
> {
>   NSArray* topLevelWidgets = nil;
>
>   NSBundle* theBundle = [NSBundle bundleForClass:[self class]];
>   [NSApplication sharedApplication];
>
>   Boolean nibLoaded = [theBundle loadNibNamed: @"TestSetOne" owner: [NSApplication sharedApplication] topLevelObjects: &topLevelWidgets];
>
>   if (!nibLoaded)
>       XCTFail(@"NIB file was not loaded");
>
>   [[NSApplication sharedApplication] runModalForWindow:[topLevelWidgets objectAtIndex:2]];

I would use an outlet here rattan indexing the top level objects.
> }
>
> Problem is that the last line does not cause the window in the NIB to appear. If I run the code through the debugger I can see the NSWindow instance that I am passing to the “runModalForWindow”.
>
> What am I doing wrong ?

Is the test case running as a part of a foundation tool?

If this is the case then application runloop isn’t established.

The overview section in the NSPPlication docs has something to say on this:
https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/nsapplication_class/reference/reference.html

The main() function Xcode creates begins by calling a function named NSApplicationMain(), which is functionally similar to the following:

void NSApplicationMain(int argc, char *argv[]) {
   [NSApplication sharedApplication];
   [NSBundle loadNibNamed:@"myMain" owner:NSApp];
   [NSApp run];
}

So try using NSApp as the nib owner and remember to call -run.
I would not try and run the window modally. If you do then calling -stop will only exit the modal run loop, not the application one.

NSApp run will block until -stop is sent. I found the following method did the trick.

/*

- stopApp:

*/
- (void)stopApp:(id)sender
{
#pragma unused(sender)

	// will stop run loop after next actual event object dispatched.
	// a timer doesn't count here
	[NSApp stop:self];

	// send a dummy event to trigger stopping
	NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
										location:NSMakePoint(0,0)
								   modifierFlags:0
									   timestamp:0
									windowNumber:0
										 context:nil
										 subtype:1
										   data1:1
										   data2:1];
	[NSApp postEvent:event atStart:YES];
}

.

It may also be necessary to transform the process type to a foreground application in some cases - I don’t quite remember all the detail of this however so you may need to experiment.

/*

transform to foreground application
*/
+ (BOOL)transformToForegroundApplication
{
	//
	// check if already transformed
	//
	if ([self isForegroundApplication]) {
		return YES;
	}

	OSStatus osStatus;
	ProcessSerialNumber ourPSN;


	// get our current process
	if ((osStatus = GetCurrentProcess(&ourPSN)) != noErr) {
		OSStatusLog(osStatus);
		return NO;
	}

	// transform it into a foreground app
	if ((osStatus = TransformProcessType(&ourPSN, kProcessTransformToForegroundApplication)) != noErr) {
		OSStatusLog(osStatus);
		return NO;
	}

	// bring it to the front
	if ((osStatus = SetFrontProcess(&ourPSN)) != noErr) {
		OSStatusLog(osStatus);
		return NO;
	}

	// set system UI mode to limit interaction for this process
	SetSystemUIMode(kUIModeNormal, 0);

	// sharedApplication will make a connection to the window server
	[NSApplication sharedApplication];


	isForegroundApplication = YES;

	return YES;

}


Jonathan















_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden


References: 
 >Running an NSApplication from a test case (From: Daniel Luis dos Santos <email@hidden>)

  • Prev by Date: Re: Key event data not available in eventRef
  • Next by Date: secure uitextfield is not secure
  • Previous by thread: Running an NSApplication from a test case
  • Next by thread: secure uitextfield is not secure
  • Index(es):
    • Date
    • Thread