CocoaSmugMug 1.2An Objective-C wrapper for the SmugMug 1.2 photo service APIs
Release: v1.2 (initial release)
Author: Chris Beauvois
License: MIT
Getting StartedDevelopment Requirements
OS X 10.4.x/10.5.x Cocoa.framework /usr/lib/libcrypto.0.9.x.dylib (ships with OS X 10.4/5, include in
... [More]
your Xcode project under "Frameworks")
SmugMug provides four choices of response formats: REST, JSON, PHP, and XML-RPC (default is REST). CocoaSmugMug delegates parsing responses through a simple protocol that you implement using the toolkit of your choosing for your choice of response format (see ResponseFormatter, declared in CocoaSmugMug.h).
For example: To parse JSON-formatted responses using Blake Seely's BSJSONAdditions (available at http://blakeseely.com/downloads.html ):
First, implement the ResponseFormatter protocol, or create a new class that implements the protocol:
@interface BSJSONResponseFormatter : NSObject
@endResponseFormatter has two methods:
@protocol ResponseFormatter
- (NSString *)formatType;
- (NSDictionary *)formatDictionaryFromResponseData:(NSData *)data;
@endThe formatType method returns the JSON format type, declared in CocoaSmugMug.h:
- (NSString *)formatType
{
return SMUGMUG_JSON_FORMAT;
}The formatDictionaryFromResponseData: method converts the JSON-formatted response data into an NSDictionary. BSJSONAdditions adds a category to NSDictionary for converting a JSON-formatted string into an NSDictionary:
#import "NSDictionary+BSJSONAdditions.h"
- (NSDictionary *)formatDictionaryFromResponseData:(NSData *)data
{
// create an autoreleased NSString from data
NSMutableString *jsonString = [[[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
// fix JSON URLs
[jsonString replaceOccurrencesOfString:@"\\/" withString:@"/" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [string length])];
// now, format the response using the NSDictionary+BSJSONAdditions category
NSDictionary *responseDictionary = [NSDictionary dictionaryWithJSONString:jsonString];
return responseDictionary;
}UsageWhen instanciating CocoaSmugMug, the designated initializer's single argument is an instance of your formatter:
BSJSONResponseFormatter *formatter = [[[BSJSONResponseFormatter alloc] init] autorelease];
CocoaSmugMug *smugmug = [[CocoaSmugMug alloc] initWithResponseFormatter:formatter];You are now ready to begin using CocoaSmugMug:
// login
SmugMugResponse *response = [smugmug secureLoginWithAPIKey:apiKey email:userEmail password:userPassword];
// login with password hash
NSString *hash = [[[response responseDictionary] objectForKey:@"Login"] objectForKey:@"PasswordHash"];
NSString *userID = [[[[response responseDictionary] objectForKey:@"Login"] objectForKey:@"User"] objectForKey:@"id"];
response = [smugmug loginWithAPIKey:apiKey userID:userID passwordHash:hash];
// to use SSL for all requests (be sure to add libcrypto.0.9.7.dylib to your Xcode project's frameworks)
[smugmug setShouldUseSSL:YES];
// to get your account tree, albums or categories
response = [smugmug getTree];
NSLog(@"\n\ngetTree:\n%@\n\n-------------------------------------", [response responseDictionary]);
response = [smugmug getAllAlbums];
NSLog(@"\n\ngetAllAlbums:\n%@\n\n-------------------------------------", [response responseDictionary]);
response = [smugmug getAllSubCategories];
NSLog(@"\n\ngetAllSubCategories:\n%@\n\n-------------------------------------", [response responseDictionary]);
// to create a category
response = [smugmug createCategory:@"Test Category"];
NSNumber *testCategoryID = [[[response responseDictionary] objectForKey:@"Category"] objectForKey:@"id"];
// to create a subcategory
response = [smugmug createSubCategoryWithName:@"Test Subcategory" forCategory:testCategoryID];
NSNumber *testSubcategoryID = [[[response responseDictionary] objectForKey:@"SubCategory"] objectForKey:@"id"];
// to create and customize an album in one shot
response = [smugmug createAlbumWithTitle:@"Test Album"
categoryID:testCategoryID
albumTemplateID:[NSNumber numberWithInt:0]
subCategoryID:testSubcategoryID
communityID:[NSNumber numberWithInt:0]
description:@"This is a test"
keywords:nil
password:nil
passwordHint:nil
position:[NSNumber numberWithInt:3]
sortMethod:nil
sortDirection:YES
public:NO
filenames:NO
comments:NO
external:NO
EXIF:YES
share:NO
printable:YES
originals:YES
familyEdit:NO
friendEdit:NO
header:NO
templateID:[NSNumber numberWithInt:0]
larges:YES
clean:YES
protected:YES
watermarking:NO
proofDays:[NSNumber numberWithInt:5]
backprinting:nil
smugSearchable:nil
worldSearchable:nil];
NSNumber *testAlbumID = [[[response responseDictionary] objectForKey:@"Album"] objectForKey:@"id"];
// synchronous upload
NSURL *url = [NSURL URLWithString:@"http://mechanicalmoon.com/Chris.jpg"];
response = [smugmug imageUpload:url
toAlbum:testAlbumID
withName:nil
caption:@"synchronous"
keywords:[NSArray arrayWithObject:@"testing; one; two"]
latitude:[NSNumber numberWithDouble:40.714]
longitude:[NSNumber numberWithDouble:-74.006]
altitude:[NSNumber numberWithInt:33]];
// asynchronous upload
NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
[center addObserver:self
selector:@selector(didCompleteUploadNotification:)
name:CocoaSmugMugDidCompleteUploadNotification
object:nil];
[center addObserver:self
selector:@selector(errorDuringUploadNotification:)
name:CocoaSmugMugUploadErrorNotification
object:nil];
NSString *transactionID = [smugmug threadedImageUpload:url
toAlbum:testAlbumID
withName:@"Chris.jpg"
caption:@"Katia likes Chris"
keywords:[NSArray arrayWithObject:@"asynch"]
latitude:[NSNumber numberWithDouble:40.714]
longitude:[NSNumber numberWithDouble:-74.006]
altitude:[NSNumber numberWithInt:33]];
- (void)didCompleteUploadNotification:(NSNotification *)notification
{
// get the uploaded image's id
SmugMugResponse *response = [smugmug responseFromDidCompleteUploadNotification:notification];
NSNumber *imageID = [[[_response responseDictionary] objectForKey:@"Image"] objectForKey:@"id"];
// get an URL to the image
response = [smugmug getInfoForImage:imageID];
NSString *largeURL = [[[response responseDictionary] objectForKey:@"Image"] objectForKey:@"LargeURL"];
// display in default browser
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:largeURL]];
}
- (void)errorDuringUploadNotification:(NSNotification *)notification
{
// retrieve error dictionary from the distributed notification
NSDictionary *errorDictionary = [smugmug errorDictionaryFromUploadErrorNotification:notification];
NSLog(@"errorDictionary: %@", errorDictionary);
}
@endContactFor any questions, comments, bug reports, etc. drop me a line at cocoasmugmug at gmail dot com. Thanks! [Less]