« Previous entry | Next entry » Browse > Snippets
Skip to comments (2)
A Cocoa class to ease iPod management
Posted by l0ne on Oct 18 2005 @ 08:54 :: 3148 unique visits
Free for everyone to use. May need tweaking (and will surely need to update its family detection) once somebody gets his hands on a video iPod this week.L0iPod.h:
CODE: OTHER
// L0iPod.h
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
typedef enum {
// internal, unused
kL0iPodUnchecked = -1,
// cannot determine the iPod type.
kL0iPodGeneric = 0,
// iPod, first or second generation
kL0iPodMechanicalOrTouchWheel = 1,
// iPod, third generation
kL0iPodTouchWheelAndButtons = 2,
// iPod mini (either first or second gen.)
kL0iPodMini = 3,
// iPod, fourth generation
kL0iPodClickWheel = 4,
// iPod photo or iPod with color display
kL0iPodColorDisplay = 5,
// iPod, fifth generation
kL0iPodVideo = 6, // may change
// iPod nano
kL0iPodNano = 7,
// iPod shuffle
kL0iPodShuffle = 128
} L0iPodFamily;
@interface L0iPod : NSObject {
FSRef iPodRef;
L0iPodFamily family;
}
// If the given path is inside an iPod, returns the absolute
// path to that iPod's mount point. Otherwise, returns nil.
+ (NSString*) deviceRootForPath:(NSString*) path;
// Is the given path an iPod mount point?
+ (BOOL) hasControlFolder:(NSString*) path;
// Returns the mount points of all mounted iPods.
+ (NSArray*) allMountedDevices;
// Initializes a L0iPod object that refers to the iPod that
// contains the given path. Returns the new object or nil if
// the path is not inside an iPod.
- (id) initWithPath:(NSString*) path;
// The file:// URL to the iPod mount point.
// Always returns the right URL, even if it has changed since
// you created this object. Returns nil if iPod was unmounted.
- (NSURL*) fileURL;
// The absolute path to the iPod mount point.
// Always returns the right path, even if it has changed since
// you created this object. Returns nil if iPod was unmounted.
- (NSString*) path;
// Returns the iPod's icon at a size of 32x32, as currently
// displayed by the Finder.
- (NSImage*) icon;
// Returns a dictionary containing the keys and values of the
// iPod's SysInfo file.
- (NSDictionary*) deviceInformation;
// Returns the iPod's family (one of the L0iPodFamily constants
// above).
- (L0iPodFamily) family;
// Does this iPod have a display?
- (BOOL) hasDisplay;
// Does this iPod have a color display?
- (BOOL) hasColorDisplay;
// Does this iPod have the Extras > Notes submenu?
- (BOOL) hasNotes;
// Can this iPod be connected to a TV (for photo or video
// viewing)?
- (BOOL) hasTVOut;
// Can this iPod play back video?
- (BOOL) hasVideoPlayback;
// Does this iPod have photo display capabilities?
- (BOOL) hasPhotoAlbum;
// The iPod's display name, as shown by the Finder, or
// nil if the iPod was unmounted.
- (NSString*) displayName;
@end
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
typedef enum {
// internal, unused
kL0iPodUnchecked = -1,
// cannot determine the iPod type.
kL0iPodGeneric = 0,
// iPod, first or second generation
kL0iPodMechanicalOrTouchWheel = 1,
// iPod, third generation
kL0iPodTouchWheelAndButtons = 2,
// iPod mini (either first or second gen.)
kL0iPodMini = 3,
// iPod, fourth generation
kL0iPodClickWheel = 4,
// iPod photo or iPod with color display
kL0iPodColorDisplay = 5,
// iPod, fifth generation
kL0iPodVideo = 6, // may change
// iPod nano
kL0iPodNano = 7,
// iPod shuffle
kL0iPodShuffle = 128
} L0iPodFamily;
@interface L0iPod : NSObject {
FSRef iPodRef;
L0iPodFamily family;
}
// If the given path is inside an iPod, returns the absolute
// path to that iPod's mount point. Otherwise, returns nil.
+ (NSString*) deviceRootForPath:(NSString*) path;
// Is the given path an iPod mount point?
+ (BOOL) hasControlFolder:(NSString*) path;
// Returns the mount points of all mounted iPods.
+ (NSArray*) allMountedDevices;
// Initializes a L0iPod object that refers to the iPod that
// contains the given path. Returns the new object or nil if
// the path is not inside an iPod.
- (id) initWithPath:(NSString*) path;
// The file:// URL to the iPod mount point.
// Always returns the right URL, even if it has changed since
// you created this object. Returns nil if iPod was unmounted.
- (NSURL*) fileURL;
// The absolute path to the iPod mount point.
// Always returns the right path, even if it has changed since
// you created this object. Returns nil if iPod was unmounted.
- (NSString*) path;
// Returns the iPod's icon at a size of 32x32, as currently
// displayed by the Finder.
- (NSImage*) icon;
// Returns a dictionary containing the keys and values of the
// iPod's SysInfo file.
- (NSDictionary*) deviceInformation;
// Returns the iPod's family (one of the L0iPodFamily constants
// above).
- (L0iPodFamily) family;
// Does this iPod have a display?
- (BOOL) hasDisplay;
// Does this iPod have a color display?
- (BOOL) hasColorDisplay;
// Does this iPod have the Extras > Notes submenu?
- (BOOL) hasNotes;
// Can this iPod be connected to a TV (for photo or video
// viewing)?
- (BOOL) hasTVOut;
// Can this iPod play back video?
- (BOOL) hasVideoPlayback;
// Does this iPod have photo display capabilities?
- (BOOL) hasPhotoAlbum;
// The iPod's display name, as shown by the Finder, or
// nil if the iPod was unmounted.
- (NSString*) displayName;
@end
L0iPod.m:
CODE: OTHER
//
// L0iPod.m
#import "L0iPod.h"
@implementation L0iPod
+ (NSString*) deviceRootForPath:(NSString*) path {
NSArray* arr = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
NSEnumerator* enu = [arr objectEnumerator];
NSString* root;
while (root = [enu nextObject]) {
if ([path hasPrefix:root] && [self hasControlFolder:root])
return root;
}
return nil;
}
+ (BOOL) hasControlFolder:(NSString*) path {
BOOL isDir;
return [[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"iPod_Control"] isDirectory:&isDir] && isDir;
}
+ (NSArray*) allMountedDevices {
NSArray* arr = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
NSEnumerator* enu = [arr objectEnumerator];
NSMutableArray* ipods = [NSMutableArray arrayWithCapacity:[arr count]];
NSString* path;
while (path = [enu nextObject]) {
if ([self hasControlFolder:path])
[ipods addObject:[[self alloc] initWithPath:path]];
}
return [NSArray arrayWithArray:ipods];
}
- (id) initWithPath:(NSString*) path {
if (self = [super init]) {
NSString* ipodRoot = [[self class] deviceRootForPath:path];
if (!ipodRoot) {
[self release];
return nil;
}
CFURLGetFSRef((CFURLRef)[NSURL fileURLWithPath:ipodRoot], &iPodRef);
family = kL0iPodUnchecked;
}
return self;
}
- (NSURL*) fileURL {
NSURL* url = (NSURL*) CFURLCreateFromFSRef(NULL, &iPodRef);
return [url autorelease];
}
- (NSString*) path {
return [[self fileURL] path];
}
- (NSImage*) icon {
NSString* path = [self path];
return path == nil? nil : [[NSWorkspace sharedWorkspace] iconForFile:path];
}
- (NSDictionary*) deviceInformation {
NSString* ipod = [self path];
if (!ipod)
return nil;
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
NSString* sysInfo = [NSString stringWithContentsOfFile:[ipod stringByAppendingPathComponent:@"iPod_Control/Device/SysInfo"]];
NSScanner* scanner = [NSScanner scannerWithString:sysInfo];
[scanner setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
while (![scanner isAtEnd]) {
NSString* key = nil, * value = nil;
[scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@":n"] intoString:&key];
if ([scanner scanString:@":" intoString:nil]) {
[scanner scanUpToString:@"n" intoString:&value];
[dict setObject:value forKey:key];
}
[scanner scanString:@"n" intoString:nil];
}
return [NSDictionary dictionaryWithDictionary:dict];
}
- (L0iPodFamily) family {
#define L0PVT_familyInfoEquals(buildid, visid) ([buildID hasPrefix:(buildid)] && [visibleID hasPrefix:(visid)])
if (family != kL0iPodUnchecked)
return family;
NSDictionary* info = [self deviceInformation];
NSString* buildID = [info objectForKey:@"buildID"];
NSString* visibleID = [info objectForKey:@"visibleBuildID"];
if (L0PVT_familyInfoEquals(@"0x01508000", @"0x01508000")) {
// mechanical/touch wheel (first & second generation)
family = kL0iPodMechanicalOrTouchWheel;
} else if (L0PVT_familyInfoEquals(@"0x02308000", @"0x02308000")) {
// touch wheel & buttons (third generation)
family = kL0iPodTouchWheelAndButtons;
} else if (L0PVT_familyInfoEquals(@"0x02608000", @"0x01408000")) {
// iPod mini
family = kL0iPodMini;
} else if (L0PVT_familyInfoEquals(@"0x03108000",@"0x03108000")) {
// click wheel (fourth generation)
family = kL0iPodClickWheel;
} else if (L0PVT_familyInfoEquals(@"0x04208000",@"0x01208000")) {
// iPod with color display (includes iPod photo)
family = kL0iPodColorDisplay;
} else if (L0PVT_familyInfoEquals(@"0x05008000",@"0x01008000")) {
// iPod nano
family = kL0iPodNano;
} else if (L0PVT_familyInfoEquals(@"0x01128000",@"0x01128000")) {
// iPod shuffle
family = kL0iPodShuffle;
} else {
// Unrecognized iPod
family = kL0iPodGeneric;
}
return family;
#undef L0PVT_familyInfoEquals
}
- (BOOL) hasDisplay {
return [self family] != kL0iPodShuffle;
}
- (BOOL) hasColorDisplay {
L0iPodFamily fam = [self family];
return fam == kL0iPodColorDisplay || fam == kL0iPodNano || fam == kL0iPodVideo;
}
- (BOOL) hasNotes {
L0iPodFamily fam = [self family];
return fam != kL0iPodMechanicalOrTouchWheel && fam != kL0iPodShuffle;
}
- (BOOL) hasTVOut {
L0iPodFamily fam = [self family];
return fam == kL0iPodColorDisplay || fam == kL0iPodVideo;
}
- (BOOL) hasVideoPlayback {
return [self family] == kL0iPodVideo;
}
- (BOOL) hasPhotoAlbum {
return [self hasColorDisplay];
}
- (NSString*) displayName {
NSString* path = [self path];
return path? [[NSFileManager defaultManager] displayNameAtPath:path] : nil;
}
@end
// L0iPod.m
#import "L0iPod.h"
@implementation L0iPod
+ (NSString*) deviceRootForPath:(NSString*) path {
NSArray* arr = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
NSEnumerator* enu = [arr objectEnumerator];
NSString* root;
while (root = [enu nextObject]) {
if ([path hasPrefix:root] && [self hasControlFolder:root])
return root;
}
return nil;
}
+ (BOOL) hasControlFolder:(NSString*) path {
BOOL isDir;
return [[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"iPod_Control"] isDirectory:&isDir] && isDir;
}
+ (NSArray*) allMountedDevices {
NSArray* arr = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
NSEnumerator* enu = [arr objectEnumerator];
NSMutableArray* ipods = [NSMutableArray arrayWithCapacity:[arr count]];
NSString* path;
while (path = [enu nextObject]) {
if ([self hasControlFolder:path])
[ipods addObject:[[self alloc] initWithPath:path]];
}
return [NSArray arrayWithArray:ipods];
}
- (id) initWithPath:(NSString*) path {
if (self = [super init]) {
NSString* ipodRoot = [[self class] deviceRootForPath:path];
if (!ipodRoot) {
[self release];
return nil;
}
CFURLGetFSRef((CFURLRef)[NSURL fileURLWithPath:ipodRoot], &iPodRef);
family = kL0iPodUnchecked;
}
return self;
}
- (NSURL*) fileURL {
NSURL* url = (NSURL*) CFURLCreateFromFSRef(NULL, &iPodRef);
return [url autorelease];
}
- (NSString*) path {
return [[self fileURL] path];
}
- (NSImage*) icon {
NSString* path = [self path];
return path == nil? nil : [[NSWorkspace sharedWorkspace] iconForFile:path];
}
- (NSDictionary*) deviceInformation {
NSString* ipod = [self path];
if (!ipod)
return nil;
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
NSString* sysInfo = [NSString stringWithContentsOfFile:[ipod stringByAppendingPathComponent:@"iPod_Control/Device/SysInfo"]];
NSScanner* scanner = [NSScanner scannerWithString:sysInfo];
[scanner setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
while (![scanner isAtEnd]) {
NSString* key = nil, * value = nil;
[scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@":n"] intoString:&key];
if ([scanner scanString:@":" intoString:nil]) {
[scanner scanUpToString:@"n" intoString:&value];
[dict setObject:value forKey:key];
}
[scanner scanString:@"n" intoString:nil];
}
return [NSDictionary dictionaryWithDictionary:dict];
}
- (L0iPodFamily) family {
#define L0PVT_familyInfoEquals(buildid, visid) ([buildID hasPrefix:(buildid)] && [visibleID hasPrefix:(visid)])
if (family != kL0iPodUnchecked)
return family;
NSDictionary* info = [self deviceInformation];
NSString* buildID = [info objectForKey:@"buildID"];
NSString* visibleID = [info objectForKey:@"visibleBuildID"];
if (L0PVT_familyInfoEquals(@"0x01508000", @"0x01508000")) {
// mechanical/touch wheel (first & second generation)
family = kL0iPodMechanicalOrTouchWheel;
} else if (L0PVT_familyInfoEquals(@"0x02308000", @"0x02308000")) {
// touch wheel & buttons (third generation)
family = kL0iPodTouchWheelAndButtons;
} else if (L0PVT_familyInfoEquals(@"0x02608000", @"0x01408000")) {
// iPod mini
family = kL0iPodMini;
} else if (L0PVT_familyInfoEquals(@"0x03108000",@"0x03108000")) {
// click wheel (fourth generation)
family = kL0iPodClickWheel;
} else if (L0PVT_familyInfoEquals(@"0x04208000",@"0x01208000")) {
// iPod with color display (includes iPod photo)
family = kL0iPodColorDisplay;
} else if (L0PVT_familyInfoEquals(@"0x05008000",@"0x01008000")) {
// iPod nano
family = kL0iPodNano;
} else if (L0PVT_familyInfoEquals(@"0x01128000",@"0x01128000")) {
// iPod shuffle
family = kL0iPodShuffle;
} else {
// Unrecognized iPod
family = kL0iPodGeneric;
}
return family;
#undef L0PVT_familyInfoEquals
}
- (BOOL) hasDisplay {
return [self family] != kL0iPodShuffle;
}
- (BOOL) hasColorDisplay {
L0iPodFamily fam = [self family];
return fam == kL0iPodColorDisplay || fam == kL0iPodNano || fam == kL0iPodVideo;
}
- (BOOL) hasNotes {
L0iPodFamily fam = [self family];
return fam != kL0iPodMechanicalOrTouchWheel && fam != kL0iPodShuffle;
}
- (BOOL) hasTVOut {
L0iPodFamily fam = [self family];
return fam == kL0iPodColorDisplay || fam == kL0iPodVideo;
}
- (BOOL) hasVideoPlayback {
return [self family] == kL0iPodVideo;
}
- (BOOL) hasPhotoAlbum {
return [self hasColorDisplay];
}
- (NSString*) displayName {
NSString* path = [self path];
return path? [[NSFileManager defaultManager] displayNameAtPath:path] : nil;
}
@end
1. On Jun 06 2006 @ 16:31 mahdmahd wrote:
it is too nice