Skip to content

Instantly share code, notes, and snippets.

@millenomi
Created April 18, 2010 22:25
Show Gist options
  • Save millenomi/370588 to your computer and use it in GitHub Desktop.
Save millenomi/370588 to your computer and use it in GitHub Desktop.
//
// ILType.h
// ILType
//
// Created by ∞ on 18/04/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <MobileCoreServices/MobileCoreServices.h>
#import <CoreGraphics/CoreGraphics.h>
#else
#import <Carbon/Carbon.h>
#import <Quartz/Quartz.h>
#endif
@interface ILType : NSObject {
NSString* UTI;
}
// These methods accept an argument that is either a NSString or a ILType.
// If it's of the right kind (for instance, passing a NSString to UTIWithType) the argument will be returned unchanged; otherwise, it will be transformed to the right type.
// Note that the CFStringRef returned by UTIWithType: uses ObjC rules (no need to release it).
// Additionally, both accept a nil parameter gracefully returning nil.
+ (CFStringRef) UTIWithType:(id) type;
+ (ILType*) typeWithType:(id) type;
// Designated initializer.
- initWithUTI:(id) uti;
+ typeWithUTI:(id) uti;
@property(readonly, nonatomic, copy) NSString* UTI;
// (id)-typed arguments can be either a ILType or a UTI NSString.
- (BOOL) conformsTo:(id) type; // self conforms to type?
- (BOOL) isConformingType:(id) type; // type conforms to self?
@property(readonly) NSDictionary* declaration;
@property(readonly) NSURL* definingBundleURL;
@property(readonly) NSString* localizedDescription;
// Returns a type object for the given tag of the given kind.
// 'kind' is one of the kUTTagClass… constants.
// The last argument can be a ILType or a NSString UTI object.
+ typeForTag:(NSString*) tag ofClass:(CFStringRef) kind conformingToType:(id) type;
// Same, but returns all applicable types.
+ (NSArray*) allTypesForTag:(NSString*) tag ofClass:(CFStringRef) kind conformingToType:(id) type;
// Returns the tag of the given class.
// 'kind' is one of the kUTTagClass… constants.
- (NSString*) preferredTagOfClass:(CFStringRef) kind;
@end
@interface ILType (ILTypeConvenienceMethods)
// The bundle that declares this type.
@property(readonly) NSBundle* definingBundle;
// An array of all types the receiver conforms to.
@property(readonly) NSArray* conformingToTypes;
// Use the kUTTagClass… objects as keys.
@property(readonly) NSDictionary* tagsByClass;
// Returns a path to an image representing files of this type. If there is an image with the given size or greater, it'll be returned; otherwise, a smaller image will be returned if specified, or nil if none.
- (NSString*) pathToRepresentingImageOfSize:(CGSize) s;
@end
//
// ILType.m
// ILType
//
// Created by ∞ on 18/04/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "ILType.h"
@interface ILType ()
@property(copy, nonatomic, setter=private_setUTI:) NSString* UTI;
@end
@implementation ILType
+ (CFStringRef) UTIWithType:(id) type;
{
if ([type isKindOfClass:[NSString class]])
return (CFStringRef) type;
else
return (CFStringRef) [type UTI];
}
+ (ILType*) typeWithType:(id) type;
{
if ([type isKindOfClass:[NSString class]])
return [self typeWithUTI:type];
else
return type;
}
- initWithUTI:(id) uti;
{
if ((self = [super init]))
self.UTI = uti;
return self;
}
+ typeWithUTI:(id) uti;
{
return [[[self alloc] initWithUTI:uti] autorelease];
}
@synthesize UTI;
- (void) dealloc
{
[UTI release];
[super dealloc];
}
- (NSUInteger) hash;
{
return [UTI hash] ^ [[self class] hash];
}
- (BOOL) isEqual:(id) o;
{
return [o isKindOfClass:[ILType class]] && [[o UTI] isEqual:self.UTI];
}
- (BOOL) conformsTo:(id) type; // self conforms to type?
{
return UTTypeConformsTo((CFStringRef) self.UTI, [[self class] UTIWithType:type]);
}
- (BOOL) isConformingType:(id) type; // type conforms to self?
{
return UTTypeConformsTo([[self class] UTIWithType:type], (CFStringRef) self.UTI);
}
- (NSDictionary*) declaration;
{
return [(id) UTTypeCopyDeclaration((CFStringRef) self.UTI) autorelease];
}
- (NSURL*) definingBundleURL;
{
return [(id) UTTypeCopyDeclaringBundleURL((CFStringRef) self.UTI) autorelease];
}
- (NSString*) localizedDescription;
{
return [(id) UTTypeCopyDescription((CFStringRef) self.UTI) autorelease];
}
+ typeForTag:(NSString*) tag ofClass:(CFStringRef) kind conformingToType:(id) type;
{
return [self typeWithType:[(id)UTTypeCreatePreferredIdentifierForTag(kind, (CFStringRef) tag, [self UTIWithType:type]) autorelease]];
}
+ (NSArray*) allTypesForTag:(NSString*) tag ofClass:(CFStringRef) kind conformingToType:(id) type;
{
NSArray* a = [(id)UTTypeCreateAllIdentifiersForTag(kind, (CFStringRef) tag, [self UTIWithType:type]) autorelease];
NSMutableArray* types = [NSMutableArray arrayWithCapacity:[a count]];
for (NSString* uti in a)
[types addObject:[self typeWithUTI:uti]];
return types;
}
- (NSString*) preferredTagOfClass:(CFStringRef) kind;
{
return [(id)UTTypeCopyPreferredTagWithClass((CFStringRef) self.UTI, kind) autorelease];
}
@end
@implementation ILType (ILTypeConvenienceMethods)
- (NSBundle*) definingBundle;
{
return [NSBundle bundleWithPath:[self.definingBundleURL path]];
}
- (NSArray*) conformingToTypes;
{
NSMutableArray* a = [NSMutableArray array];
for (NSString* uti in [self.declaration objectForKey:@"UTTypeConformsTo"])
[a addObject:[[self class] typeWithUTI:uti]];
return a;
}
- (NSDictionary*) tagsByClass;
{
return [self.declaration objectForKey:@"UTTypeTagSpecification"];
}
- (NSString*) pathToRepresentingImageOfSize:(CGSize) s;
{
NSString* path = nil;
NSDictionary* d = self.declaration;
#if TARGET_OS_IPHONE
if (s.width <= 64 || s.height <= 64)
path = [d objectForKey:@"UTTypeSize64IconFile"];
if (!path)
path = [d objectForKey:@"UTTypeSize320IconFile"];
#else
path = [d objectForKey:@"UTTypeIconFile"];
#endif
if (path)
path = [[self.definingBundle resourcePath] stringByAppendingPathComponent:path];
return path;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment