Apple Developer Connection
Advanced Search
Member Login Log In | Not a Member? Support

Using the DotMac SDK

Download .Mac SDK from ADC Member Site today. As a developer, you probably know that Apple's iApps are tightly integrated
with the .Mac services. But what about your own application? If you could integrate your application with .Mac, you could provide your users with innovative new networked features, delivered as seamlessly as they've come to expect from using the iApps.

Apple has been thinking that way, as well; and now you can easily hook your application up to the features and benefits of the .Mac “mother ship” just like those iApp applications. The DotMac Software Development Kit (SDK), whose components include the DotMac Kit, was released at Apple's Worldwide Developer Conference in June, 2004. The SDK gives you everything you need to build applications that take advantage of the .Mac services. And if that weren't enough, by embedding the DotMac Kit into your application you also stand to collect a significant bounty on each new .Mac member you bring in.

This article introduces you to the .Mac SDK from a developer's perspective. We'll cover the components of the .Mac SDK, how it works, why you want to use it, and how you use it to build applications integrated with .Mac services. Finally, we'll look at real-world examples of .Mac integrations, to spark your imagination about the possibilities for creating innovative new features for your own application.

Why Integrate with .Mac?

Integrating with .Mac brings your application powerful networked features, easily and with a great user experience. The universal namespace inherent in .Mac bridges the local world with the online world, and allows data to flow seamlessly between the two. Here are just a few things .Mac has to offer to your application at no cost:

  • Services based on stable, secure, and broadly-accepted open standards. .Mac supports network access via WebDAV, HTTP, XML-RPC, and other open standards. But integrating with .Mac requires no network programming on your part, so you can focus on developing product features rather than implementation details.
  • Always-on "store and forward." Integrating .Mac gives your desktop application the simplest direct-to-Web publishing/storage available. Every .Mac account includes 250 MB of combined storage space, of which the user is free to allocate as much as they like to your application. You can easily publish data, subscribe to data, and share documents in a distributed workflow.
  • Painless account management. Creating credentials, resetting passwords, and other account management details are all handled for you. No assembly required.
  • Access to over one-half million members. Your application can instantly tap into a growing number of .Mac members. In addition, customers are more likely to use, and stay with, your product because of its integration with .Mac.
  • Highly scalable services. Just how scalable? The iDisk service alone has 7+ TB (yes, that's trillions of bytes) downloaded and 1/2+ TB uploaded per week. It offers over 1.5Gbps of available bandwidth that can be increased on demand. That's one less scalability problem that you have to worry about.
  • .Mac Affiliate Program. Simply embed the DotMac Kit into your application and join the .Mac Affiliate Program, and you've built yourself an additional income stream. For each new .Mac member that signs up through your application, you'll get paid. Any developer—ISV, shareware, open source—can join the Affiliate Program.
  • Systems support and monitoring 24/7. Simply put, it's a dedicated group of folks at .Mac whose lives can be interrupted by a cell phone. Better them than you.
  • The opportunity to stand out in your market. You simply can't do this on any other platform. No other operating system gives you access to a universal credentialed namespace and Internet-based services built on open standards.

In summary, integrating with .Mac can significantly reduce your development time and cost by providing network services, without your having to worry about protocols, security, servers, or other backend services and maintenance.

What Is the .Mac SDK?

Taking advantage of .Mac within your application starts with the .Mac SDK. Unveiled at WWDC, the.Mac SDK includes the DotMac Kit—an embeddable framework that allows you to tightly integrate the Internet-based .Mac services with your application—all without any network programming. ADC members can download it at no cost, and it's available today. (Membership is free; to learn more, check out the ADC Membership page.)

Because the DotMac Kit is an embeddable framework, not part of the core operating system, you can use it in applications running on Mac OS X versions 10.2.6 and higher. And although the DotMac Kit has only been available since WWDC 2004, it has been tested the best possible way—through real-world use. The code is already in use by many of the .Mac services like HomePage, and a wide range of third-party applications, including Intuit QuickBooks.

How Data Flows

The DotMac Kit fully supports both asynchronous and synchronous data flow between your application and the .Mac services. All operations are asynchronous by default, but you can set synchronous behavior at any time. Asynchronous is preferred because it means that your application can go about its business while data is moving on the network.

Figure 1 shows the sequence of events for an asynchronous upload. The putData:toPath: method returns immediately, but your delegate object is called asynchronously to signal that the upload has completed or failed with an error.

Uploading data asynchronously.

Figure 1: Uploading data asynchronously.

Figure 2 shows the same operation performed synchronously. In this case, the putData:toPath: method blocks until the upload has completed or failed with an error.

Uploading data synchronously.

Figure 2: Uploading data synchronously.

You can safely flip between asynchronous and synchronous operations without affecting transactions already in progress. And it's all thread-safe. You don't have to worry about threading issues, run loops, or any of that other madness.

The DotMac Kit Framework Classes

The DotMac Kit framework uses a simple "session" style Cocoa API for moving data between desktop applications and .Mac services. It also offers a neat wrapper around the .Mac services to shield you from all the gory protocol, security, and server details. Let's look at the three classes in the framework that you'll use, shown in Figure 3.

DotMac Kit Framework Classes.

Figure 3: DotMac Kit Framework Classes.

The DMMemberAccount class encapsulates a .Mac member account. When you create a DMMemberAccount object, you can instantiate it with credentials from system preferences—or, optionally, with a user-specified user name and password. After creating a DMMemberAccount object, you use it to validate the member's credentials, check when the account will expire, determine which .Mac services are available for the account, upgrade an account, or even sign up a new .Mac member.

Once you have a DMMemberAccount object, you can then use it to create a .Mac service session object. The first version of the DotMac Kit provides a session for working with the iDisk Service. A DMiDiskSession object is a remote proxy that initiates transactions to handle all synchronous and asynchronous I/O with the .Mac iDisk service. With a DMiDiskSession object in hand, you can perform a rich set of operations such as uploading and downloading data, moving and copying resources, locking and unlocking resources, and listing server-side contents. Each DMiDiskSession object encapsulates a specific iDisk. Any iDisk or Public Folder may be accessed provided that the credentials in the DMMemberAccount object grant the appropriate access.

All of the response details, including tracking transaction states, monitoring progress, handling errors, and returned results of a specific operation are encapsulated in a DMTransaction object. Indeed, a DMTransaction object does all the real work. DMTransaction objects are created by both DMMemberAccount and DMiDiskSession objects, offering an elegant way to handle both synchronous and asynchronous communication through the same API.

Getting Started

Now it's time to put the DotMac Kit to good use. We'll walk through how to integrate it into your application step-by-step.

  • Become A (Trial) Member. To start using the DotMac Kit, you need a .Mac account. If you aren't ready to purchase a full membership, you can get a 60-day free trial .Mac membership. Doing so now will give you a unique identity to test your application's integration with .Mac. Go to www.mac.com for more information on a .Mac account and its benefits.
  • Get your Creator Code. Apple provides a location online for submitting your request as part of the ADC Data Type Registration set of forms—use the Creator Code Registration form.
  • Embed DotMac Kit in Your Application. Unlike system frameworks that are shared by other applications, the DotMac Kit framework is designed to reside in your application bundle's private Frameworks directory. Embedding the DotMac Kit framework in your application guarantees that your application is always linked to the correct version of the framework. And the whole kit is just over 500 KB, so it doesn't bloat your application.

After downloading the DotMac Kit, follow these steps to embed the DotMac Kit into your application:

  1. Add the DotMacKit.framework bundle to your Xcode project. In Xcode, choose Project > Add to Project and navigate to the directory where you downloaded the DotMacKit.framework. Then drag the DotMacKit.framework to the "Frameworks > Linked Frameworks" folder in Xcode's "Groups & Files" browser.
  2. Create a Copy Files build phase to ensure that the DotMac Kit framework will be copied your application's private Frameworks directory. To do that, select your application target and choose Project > New Build Phase > New Copy Files Build Phase. Then, in the Inspector window for the new build phase, choose "Frameworks" in the Destination pop-up menu.
  3. Finally, drag the DotMacKit.framework listing in the "Linked Frameworks" folder to the Copy Files build phase you just created for your application target.
When you've taken care of these steps, you're ready to write some code and start incorporating the DotMac Kit into your application.

Using the DotMac Kit API

It doesn't take much code to start slushing data around. The following examples show you the basics:

  • Checking a member account
  • Signing up a new member
  • Uploading data
  • Downloading data

Using these examples as a guide, you can quickly enable your application with push-button collaboration.

Checking a Member Account

The first order of business is to create a DMMemberAccount object, using the line of code below (note that the four dashes in @"----" should be replaced with your unique Creator Code).

DMMemberAccount *myMemberAccount = [DMMemberAccount accountFromPreferencesWithApplicationID:@"----"];

The accountFromPreferencesWithApplicationID: class method uses the credentials stored in the .Mac preferences on your system. This is handy because it means you don't have to prompt the user for her credentials.

The application ID is your "meal ticket," that is, it's the unique identifier that lets you get paid for new .Mac customers who sign up through your application. So don't forget to obtain a Creator Code for each application that uses the DotMac Kit.

It's also a good idea to set the application name on the DMMemberAccount. This will become increasingly useful over time as the DotMac Kit is revised.

[myMemberAccount setApplicationName:@"My Killer .Mac App"]; 

Next, validate the credentials.

if ([myMemberAccount validateCredentials] != kDMSuccess) { 
    // invalid credentials - sign them up?
} 

If the credentials validate, then you're set. If not, then you might want to offer to sign the user up. We'll talk about that shortly.

Once you have validated the credentials, the next step is to verify that the .Mac service your application will use is available to the member account. In this example, we'll assume that you want to check the service availability using a synchronous (blocking) call. Remember that the DotMac Kit defaults to asynchronous. You must specify when you want synchronous behavior.

The following code verifies that the iDisk service is available using a synchronous transaction:

[myMemberAccount setIsSynchronous:YES];

DMTransaction *serviceTransaction = [myMemberAccount servicesAvailableForAccount]; 
  
if ([serviceTransaction isSuccessful]) { 
    NSArray *services = [serviceTransaction result]; 
    if ([services containsObject:kDMiDiskService] == NO) {
      // iDisk service is not available
    } 
} else { 
    // handle error 
} 

Finally, check to see if the account will expire soon. This is a proactive way to nudge your users to upgrade their .Mac account before it expires and they can't use the .Mac features of your application.

DMTransaction *daysLeftTransaction = [myMemberAccount daysLeftUntilExpiration];
if ([daysLeftTransaction isSuccessful]) { 
    NSNumber *daysLeft = [daysLeftTransaction result]; 
    if ([daysLeft intValue] < 30) {
        // display a reminder message with a prompt, and then...
        [myMemberAccount upgradeAccount];
    }
} else { 
    // handle error
} 

Signing Up a New Member

If a user of your application is not yet a .Mac member and cannot fully enjoy your application's features without a .Mac account, sign them up... and don't forget you qualify for a commission for doing so.

[DMMemberAccount signUpNewMemberWithApplicationID:@"(your creator code here)"];

This method opens the .Mac sign-up page in the user's default browser. Specifying your unique application ID ensures (assuming you're a member of the .Mac Affiliate Program) that you'll earn a commission if the user becomes a paying .Mac member.

You can also obtain the URL for the .Mac sign-up page directly, for cases where you would like to display the page within your own user interface.

NSURL *url = [DMMemberAccount signUpURLWithApplicationID:@"(your creator code here)"];

A note of caution: The URL may change in the future, so use the URL returned by this method rather than hard-coding it into your application.

Uploading Data

Given a valid DMMemberAccount object, you're ready to start moving bits. Up to this point, we've been using synchronous operations because the I/O for checking the member account was relatively lightweight. However, you want to use asynchronous transactions as much as possible to offer the best user experience—and it's the default for the DotMac Kit.

To upload data to an iDisk, create a DMiDiskSession with the DMMemberAccount object.

DMiDiskSession *mySession = [DMiDiskSession iDiskSessionWithAccount:myMemberAccount];

Then initiate an asynchronous transaction that publishes arbitrary data to a path on the iDisk. The following example publishes a simple message to a file in the member's Documents folder:

NSString *message = @"Hello, .Mac!";
NSData *messageData = [message dataUsingEncoding:NSASCIIStringEncoding];
	
DMTransaction *uploadTransaction = [mySession putData:messageData toPath:@"/Documents/upload.txt"];
        
if (uploadTransaction != nil) {
    // asynchronous transaction is in flight
}

Notice in this example that the message is first wrapped in an NSData object before being uploaded. We'll look at convenience methods for placing the contents of local files into server-side files a bit later.

Since the upload transaction is asynchronous, how do you know whether it was successful? One way is to use the following methods to check the transaction's state and monitor its progress through polling:

int transactionState = [uploadTransaction transactionState];
SInt64 bytesToMove = [uploadTransaction contentLength];
SInt64 bytesMovedSoFar = [uploadTransaction bytesTransferred];   

Displaying the results of these methods gives the user some indication of the work in progress. For the most responsive user experience, it's also a good idea to register a callback delegate with the DMiDiskSession object. We'll do just that in the next example.

Downloading Data

Next, we want to turn around and get the data that we just uploaded. The DMiDiskSession object used in the previous example is still set for asynchronous behavior. However, in this case we set a delegate on the DMiDiskSession object, and then call the getDataAtPath: method of the DMiDiskSession object.

[mySession setDelegate:self];
	
DMTransaction *downloadTransaction = [mySession getDataAtPath:@"/Documents/upload.txt"];	
    
if (downloadTransaction != nil) {
    // asynchronous transaction in flight
}

Using a delegate lets you track coarse-grained transaction state changes. You can combine this with the asynchronous polling technique from the last example to create a very responsive user experience. Also, please note that a DMiDiskSession's delegate is only messaged by asynchronous transactions. For example, you could use an NSTimer to poll the transaction progress and display it in a progress bar. Then when the delegate is messaged, the flow of the code changes to handle the transaction's result.

The delegate object must conform to the informal DMTransactionDelegate protocol which defines three callback methods for asynchronous transaction operations. Here are the methods with skeleton implementations:

- (void)transactionSuccessful: (DMTransaction *)theTransaction {
    NSData *result = [theTransaction result];
    NSString *resultString = [[NSString alloc]initWithData:result encoding:NSASCIIStringEncoding];
}

- (void)transactionHadError: (DMTransaction *)theTransaction {
    // asynchronous transaction failed
    int errorType = [theTransaction errorType];
}

- (void)transactionAborted: (DMTransaction *)theTransaction {
    // asynchronous transaction was cancelled
}

When the transaction has successfully completed, the delegate's transactionSuccessful: method is called. Use the result method of the provided DMTransaction object to obtain the results of those operations that provided a result object. The NSData object refers to memory-mapped data that, in this case, is used to create an encoded string.

Note that every transaction can have a different delegate. Simply set a delegate on the DMiDiskSession object and the next asynchronous transaction you initiate will message that delegate.

Convenience Methods

To further enable its quick and painless adoption, the DotMac Kit API also provides NSFileManager-style, synchronous-only methods to move local files to and from .Mac, and manage resources already on .Mac. The DMiDiskSession class defines the following methods, for example:

  • - createFileAtPath:contents:attributes:
  • - createDirectoryAtPath:attributes:
  • - movePath: toPath:handler:
  • - copyPath: toPath:handler:
  • - removeFileAtPath:handler:
  • - contentsAtPath:
  • - fileExistsAtPath:

These examples have given you a broad view of the DotMac Kit API. For more depth, check out the API documentation and the two sample projects included with the SDK. In our final section below, we look at a few more of the interesting problems you can solve with the DotMac Kit.

What Could You Do?

Armed with this information, you're ready to build applications with networked features to leverage .Mac's services and member community, and earn revenue while doing it. What could you do with the DotMac Kit at your fingertips? Here are just a few examples to help engage your imagination:

  • Store and sync software registration information. Imagine your machine has a total meltdown and you don't have a current backup. Usually, you'd have to manually re-enter all the registration information for your favorite licensed application. But if that application uses the DotMac Kit and stores all of your registration details in your .Mac account, then you wouldn't need to do anything. The next time you launch the application, it uses your credentials to automatically grant you access to the application. And because the registration is tied to your .Mac credentials—rather than to a specific machine—you could use the application across multiple machines. Further, you could encrypt the information before uploading it to the user's iDisk, and place it in the Documents folder so that it is not web published.
  • Synchronize application preferences across multiple Macs. Many of your favorite applications have lots of configurable options, such as the relative size and placement of various windows and palettes. Trouble is, you use those applications on your iMac at home and your G5 in the office. Wouldn't it be convenient if the application preferences were stored on your iDisk so that all the palettes were sized and placed uniformly across multiple machines?
  • Lightweight collaboration. You don't necessarily have to read and write to only your iDisk. You can also read from and write to any .Mac member's Public folder provided you have permissions to do so. Say, for example, you're on a team developing creative web content. One of the team members has a document in his Public folder that's shared by the team. You can generate content in your local memory, push it up to the server-side document, and then publish the content. Not everybody has to be online at the same time, and when they are, using the locking features of the DotMac Kit, the shared document is protected from concurrent edits. Even better, because iDisk and HomePage work together, you can publish web reports on project status or other key metadata at the same time.

Until now, you may have thought of .Mac as just a great big hard drive in the sky. The DotMac Kit turns it into a digital hub for your applications. And so the question really is: What couldn't you do with it?

Conclusion

Using the DotMac Kit, your application can leverage the .Mac services in the same way that Apple's iApp applications use those services today. The result is a win-win for everyone. Your application will stand out from the crowd. Your application's users will enjoy unparalleled features. And as a .Mac affiliate, you'll earn a commission every time your application signs up a new .Mac member. So what are you waiting for?

For More Information

This article has introduced you to the power of the DotMac Kit. The following references will help you dig in deeper:

Also, the O'Reilly book Inside .Mac by Chuck Toporek is an excellent introduction and reference guide to the .Mac services

Updated: 2005-09-20