As a developer, you probably know that Apple's iApps are tightly
integrated 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:
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 FlowsThe 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
Figure 1: Uploading data asynchronously.
Figure 2 shows the same operation performed synchronously. In this
case, the 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 ClassesThe 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. Figure 3: DotMac Kit Framework Classes.
The
Once you have a
All of the response details, including tracking transaction states,
monitoring progress, handling errors, and returned results of a
specific operation are encapsulated in a Getting StartedNow 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.
After downloading the DotMac Kit, follow these steps to embed the DotMac Kit into your application:
Using the DotMac Kit APIIt doesn't take much code to start slushing data around. The following examples show you the basics:
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 *myMemberAccount = [DMMemberAccount accountFromPreferencesWithApplicationID:@"----"];
The 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 [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 MemberIf 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 DataGiven 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 *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 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
Downloading Data
Next, we want to turn around and get the data that we just uploaded.
The [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
The delegate object must conform to the
informal - (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
Note that every transaction can have a different delegate. Simply set
a delegate on the 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
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:
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? ConclusionUsing 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 InformationThis 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 |