The workspace is an ideal tool for helping you understand other people's code, be that a class you need to enhance, APIs you need to use or Frameworks that you need to work within. Where as a class browser lets you understand code, by traversing the inheritance hierarchy or jumping to named classes (if you have the source), the ActiveDeveloper Workspace lets you understand the code by allowing you to execute it within a safe, robust and fast environment.
You no longer need to set up a whole test application in order to build an environment to call your code segment. With the ActiveDeveloper Workspace you create instances of the classes you want to investigate, send messages to these instances and inspect or display the resulting object. You can create instances of any Foundation or AppKit class such as NSWindow, NSPanel etc.
In this section we will incrementally develop a segment of code to illustrate learning the OpenPanel API.
Start ActiveDeveloper and open a new workspace (menu:"Source Editors:New Workspace")
(Please read Manual1 first if you are not yet familiar with using an ActiveDeveloper Workspace).
We are going to experiment with the NSOpenPanel. Our goal is to understand how to use NSOpenPanel so that we can include opening files in our application.
So let's start! We want to open a open file panel, we know that they are instances of NSOpenPanel, browse the documentation for NSOpenPanel, looking for a method that would suggest that it may create an instance for us and a method that would place the panel on the screen for us.
[[NSOpenPanel openPanel] runModalForTypes: nil];
We can refer to NSOpenPanel since the Workspace imports Foundation and AppKit headers for us.
Take a moment to appreciate how quick these actions will be when you no longer need a User Guide. Start ActiveDeveloper, Start ActiveAppKitExplorer, Open a Workspace and have an open file panel created in one line of code. No matter how experienced a Xcode/Cocoa developer you are, it takes much longer to have to create a temporary project and build it first - each time.
Back to the guide. We have located methods that allow us to open the panel. To try to retrieve the selection made. Back to the documentation. We need to introduce a variable to refer to the panel in order to manipulate it after the user has made their selections (copy from the web browser and paste into the Workspace).
id openPanel= nil;
openPanel = [NSOpenPanel openPanel];
[openPanel runModalForTypes: nil];
[openPanel filenames];
Inspect this code, as a compound statement, select a file and press open, the runtime object inspector appears with the resulting object of the last statement, [openPanel filenames]; (an array of filenames).
At this stage we have pretty much covered the essence of interacting with NSOpenPanel, we know how to open it and query it for the user's selection. But while browsing the documentation we have seen other methods of interest, such as:
- (void)setCanChooseDirectories:(BOOL)flag,
- (void)setCanChooseFiles:(BOOL)flag,
- (void)setAllowsMultipleSelection:(BOOL)flag, just to mention a few.
There is no better way to understand a method than to confirm your suspicions immediately by sending these messages to the instance in the workspace. Lets try - (void)setCanChooseFiles:(BOOL)flag (copy from the web browser and paste into the Workspace).
id openPanel= nil;
openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles: NO];
[openPanel runModalForTypes: nil];
[openPanel filenames];
Try for yourself to experiment with some of the other methods defined on NSOpenPanel. Just, remember to send the methods preparing the panel before sending runModalForTypes: which displays the panel on screen.
In the documentation you see that -runModalForTypes: can be passed an Array, lets explore this further. If we pass an array of strings to the panel, it will only allow us to choose files with extensions that match those strings (copy from the web browser and paste into the Workspace).
id openPanel= nil;
id types = [NSArray arrayWithObjects: @"txt", @"rtf", nil];
openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles: YES];
[openPanel runModalForTypes: types];
[openPanel filenames];
We can see that we can only select txt and rtf files.
You should be feeling pretty confident now, that you can write a method using NSOpenPanel and return an array of selected filenames. So, lets start putting things together in a shape that will fit the standard Cocoa API for opening files, the -application:openFile: method on your NSApps delegate.
From your current Array of filenames you need to enumerate over the files and open them one after the other. The next step is to refactor the code to make it robust for application usage. This is a programmer issue rather than an ActiveDeveloper one, one kind of refactoring is shown below.
// the lack of indentation is to allow copy/paste from HTML to a Workspace
id openPanel= nil;
id result = [NSMutableArray array];
id enumerator, nextFile;
//id types = [NSArray array];
id types = nil;
if (!openPanel) {
openPanel = [[NSOpenPanel openPanel] retain];
[openPanel setAllowsMultipleSelection: YES]; // try comment in/out
// [openPanel setAllowsMultipleSelection: NO]; // try comment in/out
}
if ([openPanel runModalForTypes: types]) {
enumerator = [[openPanel filenames] objectEnumerator];
while (nextFile = [enumerator nextObject])
//[self application:NSApp openFile:nextFile];
[result addObject: nextFile];
}
return result;
You can also find this code in the workspace.wsp file of SampleBrowser Manual Demo.
We started with an empty ActiveDeveloper Workspace. And through a combination of Browsing existing documentation and interactive programming we have created a respectable code segment capable of manipulating the open file panel. We learned how to dictate such things as the number of selections that can be made and the kind of files that can be selected. No need for having to setup extra testing Xcode projects - for each API experiment.
We learned what is involved in opening these files after the panel has been closed, and as soon as it worked for us in the Workspace - we could with a newly gained ActiveDeveloper confidence - directly wrap our code into an Objective-C method. No rewrite is needed - because ActiveDeveloper allows you to script with Native Objective-C ...
We hope this showcased for you how efficient it is to program Objective-C interactively with ActiveDeveloper and how much fun it can be to get immediate responses.