text: In this article, you'll learn how to use the Web Kit to handle an application's
  on-line registration. Registration has always been a bit tricky, so applications use various methods. Some
  applications offer a button that spawns a web browser, but the registration site may use features not supported by the user's
  default browser, and browser users get distracted and sometimes quit before they finish registering.
  You could always create your own unique
  form-registration process and write the code that displays, validates, and
  submits registration information. But that's a labor-intensive undertaking;
  unless you have a large-scale product, you may prefer a simpler, quicker way to
  take registrations.
  With the Web Kit, a set of classes for
  displaying web content that is included in Xcode, you can easily integrate an
  HTML-based registration form into your
  application. Then, with simple web-based scripts, you can handle validation and
  processing of user registration. While this may not work perfectly for all
  situations, it provides a good combination of convenience and reliability.
  The basic techniques discussed in this article can be applied to any
  integration of the Web Kit into existing applications. In your own applications you
  may find circumstances where you can use HTML rendering outside of the Web
  browser.
  This article has two parts: in the first part, you build the interface using
  Xcode and Interface Builder. When you have your interface, you then can use the second part of this article to create the
  backend, using code samples that show you how, and can also serve as a starting point. It assumes you are running Mac OS X 10.3 Panther, and using Xcode version 1.1 (or later).
  Rather than build a Cocoa application from scratch, for this article we'll start
  with one of the example projects in /Developer/Examples that ship
  with Xcode. While it's unlikely that a user of the CircleView application would
  want to register for updates, this example gives your version of the
  application that functionality.
  /Developer/Examples
  Start by making a copy of the CircleView application, located in the in the
  AppKit subdirectory in /Developer/Examples/AppKit/CircleView. Rename
  the new folder to "CircleReg" to keep the original. Now, make sure
  everything is working, by opening the new project file in Xcode, and click on the
  "Build and run active executable" button in Xcode's toolbar.
  /Developer/Examples/AppKit/CircleView
  To build the interface, you need to create a couple of widgets. First, you'll need a window to hold
  your web form. In the "Groups & Files" tab of the main Xcode window, open
  the NIB Files group. Double-click on MainMenu.nib in the files pane—this
  will open the interface in Interface Builder.
  You will need a new class to attach your registration code to. On the
  Classes tab of the Interface Builder window for MainMenu.nib, select NSObject>NSResponder>NSWindow. From the Classes menu, select "Subclass
  NSWindow." Rename the new class from "MyWindow" to "RegWindow." This
  will be the class that holds the code for the application registration
  process. Select the RegWindow class, and select Show Info from the Tools
  menu. Select Attributes from the pop-up menu at the top of the Info window,
  and select the Outlets tab at the top of the pane in that window. Click
  the Add button. A new Outlet is created, named myOutlet, of type
  "id." Change the name to webView of type WebView, as shown in Figure 1: Adding a WebView Outlet.
  Figure 1: Adding a WebView Outlet.
  Select Create Files for RegWindow from the Classes menu. The default options
  should be correct; you want to create both RegWindow.h and
  RegWindow.m, and insert them into the target called CircleView;
  see Figure 2: Inserting Files into the Target. Click Choose.
  RegWindow.h
  RegWindow.m
  Figure 2: Inserting Files into the Target.
  Now, create a new window to use this class. Go to the Cocoa-Windows tab
  of the Interface Builder palette window. Drag the window icon out of the
  palette, and a new window will appear. Select Show Info from the Tools
  menu. Change the window's name to "Registration," and uncheck the checkboxes
  for Miniaturize and Resize. Users shouldn't be able to alter this
  window; it would just be confusing. See Figure 3: Defining the RegWindow.
  Figure 3: Defining the RegWindow.
  Select Custom Class from the pop-up
  menu at the top of the info window, and select RegWindow from the list.
  The window's default size (480x360) should be fine for this application,
  but if your registration page was larger, you would need to change it, by
  selecting Size from the pop-up menu.
  Next, create a WebView object in this window. In the palette window is a tab
  called Cocoa GraphicsViews, the seventh from the left—since Panther, this
  palette includes a WebView object; see Figure 4: Selecting the WebView Custom View. Drag the WebView icon from the palette into
  the Registration window. In the Info window, set its size and location using the
  Size tab, then set its Custom Class to WebView using the Custom Class tab.
  Figure 4: Selecting the WebView Custom View.
  Finally, attach the registration window's webView outlet to the new WebView
  object. To do this, go to the Instances tab in the MainMenu.nib window.
  Control-click on the Window object which represents the registration window,
  and drag over to the WebView object in the Registration window. This will
  cause the Info window to open (if it's closed), and change to the Connections
  selection from the pop-up menu. Select the webView outlet from the list, and
  click Connect, as shown in Figure 5: Attaching the Outlet to the Object.
  Figure 5: Attaching the Outlet to the Object.
  There's your registration window. Now you'll need a way for the user to open
  the window, namely, a menu. Move your cursor to the Apple menu from the menu
  window. (It may actually be a blank spot next to the Edit menu—click
  there and the menu should appear.) Drag an "Item" menu selection from the menu
  tab of the palette into this menu, just below About CircleView. Open the Info
  window and rename this menu item "Register..." as shown in Figure 6: Naming Register... Menu. By convention, since it will
  open a new window in which you perform a task, it gets an ellipsis in its name.
  Figure 6: Naming the Register... Menu.
  Control-drag from the new menu item to the registration window title bar, and select
  the makeKeyAndOrderFront target in the Info window, then click
  Connect, as shown in Figure 7: Selecting the Target. Close the
  registration window; you don't want it to be open when the application first
  opens.
  makeKeyAndOrderFront
  Figure 7: Selecting the Target.
  Finally, add the WebKit Framework to your project. Select Add Frameworks...
  from the Project menu. Navigate to the
  System/Library/FrameworksFolder on your system disk, and select
  WebKit.Framework.
  System/Library/Frameworks
  WebKit.Framework
  Save your work. Test the interface, and make sure that the registration
  window opens when you select the menu item. It's still empty now, but that's
  fine.
  This application uses a resource file called form.html, which contains
  the actual registration form. Put the following HTML in a file named form.html in the CircleReg directory.
  form.html
  Listing 1: form.html
  <html>
  <head><title>Registration</title>
  </head>
  <body>
  <form method="post" action="">
  <table>
  <tr><th>First name:</th><td><input type="text" name="first"></td></tr>
  <tr><th>Last name:</th><td><input type="text" name="last"></td></tr>
  <tr><th>Phone number:</th><td><input type="text" name="phone"></td></tr>
  <tr><th> Mailbox:</th><td><input type="text" name="mail"></td></tr>
  </table>
  <p>Let us know who you are.</p>
  <input type="submit" name="submit" value="Register">
  </form>
  </body>
  In Xcode, select "Add Files..." from the project menu, and then select form.html.
  Next, you need to alter the RegWindow.h that you created with Xcode.
  Below is the code that belongs in the new RegWindow.h file:
  Listing 2: RegWindow.h
  /* RegWindow */
  #import <Cocoa/Cocoa.h>
  #import <WebKit/WebKit.h>
  @interface RegWindow : NSWindow
  {
  IBOutlet WebView *webView;
  }
  - (void)reloadForm;
  @end
  This code adds a new instance method and a new instance variable. The instance
  method reloadForm does the actual work of finding the local HTML
  pages and loading them in the WebView object. The instance
  variable holds a registration code.
  reloadForm
  WebView
  The new code RegWindow.m, seen below, provides a number of instance
  methods. Copy this over the RegWindow.m code that had been created by Xcode.
  Listing 3: RegWindow.m
  #import "RegWindow.h"
  #import <Foundation/NSBundle.h>
  #import <WebKit/WebUIDelegate.h>
  #include <string.h>
  @implementation RegWindow
  - (void)displayErrorMessage:(NSString *)error {
  NSBeginAlertSheet(
  @"Error",
  @"OK",
  nil,
  nil,
  self,
  self,
  NULL,
  NULL,
  self,
  error,
  nil);
  }
  - (void) webView:(WebView *)sender decidePolicyForMIMEType:(NSString *) type request:(NSURLRequest *)
  request frame:(WebFrame *)frame decisionListener:(id)listener {
  [listener use];
  }
  - (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation
  request:(NSURLRequest *)request
  newFrameName:(NSString *)frameName
  decisionListener:(id)listener {
  [listener ignore];
  }
  - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation
  request:(NSURLRequest *)request
  frame:(WebFrame *)frame
  decisionListener:(id)listener {
  NSURL *url = [request URL];
  NSString *urlString = [url absoluteString];
  if ([urlString hasSuffix:@"close=true"]) {
  const char *s = [urlString cString];
  const char *reg = strstr(s, "reg=");
  if (reg) {
  const char *end;
  reg = reg + 4;
  end = strchr(reg, '+');
  printf("registration code %.*s\n", end ? (end - reg) : strlen(reg), reg);
  }
  [listener ignore];
  [self close];
  [self reloadForm];
  return;
  }
  printf("navigate: %s\n", [[url absoluteString] cString]);
  [listener use];
  }
  - (void)reloadForm {
  NSBundle *bundle = [NSBundle mainBundle];
  if (bundle == nil) {
  [self displayErrorMessage: @"No mainBundle"];
  return;
  }
  NSString *path = [bundle bundlePath];
  if (path == nil) {
  [self displayErrorMessage: @"Application bundle has no path?"];
  return;
  }
  NSString *fullPath = [NSBundle pathForResource:@"form" ofType:@"html" inDirectory:path];
  if (fullPath == nil) {
  [self displayErrorMessage: @"Can't find form.html."];
  return;
  }
  [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:fullPath]]];
  }
  - (void)awakeFromNib{
  [self reloadForm];
  [webView setPolicyDelegate:self];
  }
  @end
  This code is explained in detail in the next section.
  Since these files refer to the Web Kit, you need to add the Web Kit framework to your project. Select Add Frameworks...
  from the Project menu. Navigate to the System/Library/Frameworks folder
  on your system disk, and select WebKit.framework.
  WebKit.framework
  Now expand the CircleView group. The file form.html will be a top-level part of the
  CircleView project. Drag it into the Resources folder. Build and run the
  application. You should now see a registration form if you select the
  Register... menu item.
  Once you've got these plugged in, try the application. If you have an appropriate CGI
  script for it to submit to, it will let you register your application (a
  sample CGI script is provided below along with an explanation of its use).
  When the "Register..." menu item is selected, the RegWindow class's
  makeKeyAndOrderFront method is called. This is the routine which
  actually draws the window. It does several things:
  super makeKeyAndOrderFront
  com.apple.examples.CircleView.plist
  ~/Library/Preferences
  The reloadForm method finds the form and passes it on for the Web Kit
  to render. The elaborate series of NSBundle calls makes the
  application work no matter where it's installed; as long as the
  pages were installed as part of the application, they will be found.
  If a registration code has already been found, then the application
  generates an HTML string in a buffer and loads it, telling the
  user what the registration code is. If there's no registration
  code, the form to get one is loaded.
  NSBundle
  The form submission is pretty straightforward. What's interesting
  is the way the registration code is extracted. It would be annoying to
  try to read the actual web page returned, so the program doesn't do
  that. Instead, it sets a policy delegate up for the WebView object.
  A policy delegate is any object which implements the
  WebPolicyDecisionListener protocol. That's really just three functions to implement, called decidePolicyForNewWindowAction,
  decidePolicyForNavigationAction, and decidePolicyForMIMEType. For
  this trivial browser, which is designed to only process one form, two
  of these have limited use. NewWindowAction always sends an ignore
  message; this program never wants to open a new window. MIMEType always sends a use message; anything sent back by the server is presumed okay.
  decidePolicyForNewWindowAction
  decidePolicyForNavigationAction
  decidePolicyForMIMEType
  NewWindowAction
  MIMEType
  The bulk of the work happens in the NavigationAction policy
  listener. This method is called with, among other things, a URL that the policy
  delegate is supposed to make a decision on. The sample CGI script produces an HTTP meta
  refresh tag. That tag redirects the user agent to a URL that ends with
  "reg=code". The NavigationAction policy delegate then looks for
  the 'reg=code' string within the URL. If it's there, the delegate scans the URL
  for the returned registration code, and sends an ignore message to the listener
  (telling the Web Kit code not to follow that URL). It also saves the
  registration code using the NSUserDefaults class. The window can be
  closed manually by the user. Alternatively, a link on the form goes URL ending
  in 'close=true'. The policy delegate also looks for a URL like that, and if it
  sees one, tells the Web Kit not to follow the link, and closes
  the window.
  NavigationAction
  NSUserDefaults
  If you reopen the window, what happens? The makeKeyAndOrderFront
  method synchronizes with the preference database, finding the registration code.
  It then displays a page saying the user is already registered.
  The policy delegate is set in awakeFromNib, rather than in
  makeKeyAndOrderFront. This is important! If it were not set up
  this way, there might be a race condition where the window was browsing before
  the policy delegate was in place.
  awakeFromNib
  This article offers just a simple example to get you started; you can create
  custom code for your application that does much more. The
  WebPolicyDecisionListener protocol is extremely flexible, and lets
  you do a wide range of maintenance tasks. For instance, if you have a CGI
  script which, given a URL, performs some trivial alteration on that URL, you
  could build a web browser which runs every URL it sees through that script. You
  can log URLs. You can check for patterns you don't like. You can block sites,
  you can block types of files. You could resolve host names in URLs, and block
  names pointing to certain IP numbers.
  WebPolicyDecisionListener
  As you saw in this application, you can even make use of data
  returned by the server. As long as you control both ends, you can do
  pretty much anything. If you want to change your registration form, no problem;
  have the CGI script take the data provided, and funnel it into a new form,
  which explains to the user why you need more data than you previously asked
  for. All the program knows is that, if it sees a
  URL with 'reg=string' in it, that it's found your registration code.
  Updated: 2008-01-02
  Get information on Apple products.
  Visit the Apple Store online or at retail locations.
  1-800-MY-APPLE