Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Provide 3 different identifier types for IMBObject

We need three different types of identifiers for IMBObject:

1. identifier that is different for each IMBObject throughout a session and that can be used across processes

2. identifier that identifies a resource that an IMBObject is associated with persistently (e.g. for badging resources)

3 identifier that is compatible with iMedia2 (and was probably used by many host apps to implement badging then). As a host app developer you can use this one to migrate iMedia2 identifiers to the ones mentioned  under 2.
  • Loading branch information...
commit 56a04afd51762236e7a9f24cf2102b8ab4536a8d 1 parent 6dcc9f3
Joerg Jacobsen authored
View
4 IMBApertureAudioParser.m
@@ -82,13 +82,13 @@ @implementation IMBApertureAudioParser
// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
-// -[IMBParser identifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
// However, during the evolution of iMedia class names can change and identifier string would thus also change.
// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
// class must override this method to return a prefix that matches the historic class name...
-- (NSString*) identifierPrefix
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
{
return @"IMBApertureAudioParser";
}
View
4 IMBApertureParser.m
@@ -200,13 +200,13 @@ - (void) dealloc
//
// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
-// -[IMBParser identifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
// However, during the evolution of iMedia class names can change and identifier string would thus also change.
// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
// class must override this method to return a prefix that matches the historic class name...
-- (NSString*) identifierPrefix
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
{
return @"IMBApertureParser";
}
View
4 IMBApertureVideoParser.m
@@ -82,13 +82,13 @@ @implementation IMBApertureVideoParser
// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
-// -[IMBParser identifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
// However, during the evolution of iMedia class names can change and identifier string would thus also change.
// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
// class must override this method to return a prefix that matches the historic class name...
-- (NSString*) identifierPrefix
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
{
return @"IMBApertureVideoParser";
}
View
13 IMBFolderParser.m
@@ -315,6 +315,19 @@ - (NSData*) bookmarkForObject:(IMBObject*)inObject error:(NSError**)outError
#pragma mark Helpers
+// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// However, during the evolution of iMedia class names can change and identifier string would thus also change.
+// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
+// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
+// class must override this method to return a prefix that matches the historic class name...
+
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
+{
+ return @"IMBFolderParser";
+}
+
+
- (IMBObject*) objectForURL:(NSURL*)inURL name:(NSString*)inName index:(NSUInteger)inIndex;
{
IMBObject* object = [[[IMBObject alloc] init] autorelease];
View
13 IMBLightroom3or4Parser.m
@@ -575,6 +575,19 @@ - (FMDatabase*) previewsDatabase
}
+// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// However, during the evolution of iMedia class names can change and identifier string would thus also change.
+// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
+// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
+// class must override this method to return a prefix that matches the historic class name...
+
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
+{
+ return @"IMBLightroom3Parser";
+}
+
+
//----------------------------------------------------------------------------------------------------------------------
View
17 IMBLightroomParser.m
@@ -1447,6 +1447,7 @@ - (NSString*) absolutePathFromAttributes:(NSDictionary*)inAttributes
#pragma mark
#pragma mark Object Identifiers
+// Identifier must account for "virtual copies" of original resources in Lightroom
- (NSString*) identifierForObject:(IMBObject*)inObject
{
@@ -1462,6 +1463,22 @@ - (NSString*) identifierForObject:(IMBObject*)inObject
}
+// Identifier must account for "virtual copies" of original resources in Lightroom
+
+- (NSString *)persistentResourceIdentifierForObject:(IMBObject *)inObject
+{
+ NSString* identifier = [super persistentResourceIdentifierForObject:inObject];
+
+ if ([inObject isKindOfClass:[IMBLightroomObject class]])
+ {
+ NSNumber* idLocal = [(IMBLightroomObject*)inObject idLocal];
+ identifier = [NSString stringWithFormat:@"%@/%@",identifier,idLocal];
+ }
+
+ return identifier;
+}
+
+
//----------------------------------------------------------------------------------------------------------------------
/*
View
2  IMBObject.h
@@ -84,6 +84,7 @@ extern NSString* kIMBObjectPasteboardType;
NSData* _bookmark;
NSString* _name;
NSString* _identifier;
+ NSString* _persistentResourceIdentifier;
NSDictionary* _preliminaryMetadata;
NSDictionary* _metadata;
@@ -109,6 +110,7 @@ extern NSString* kIMBObjectPasteboardType;
@property (retain) NSString* name; // Display name for user interface
@property (readonly) NSImage* icon; // Small icon to be displayed in list view
@property (retain) NSString* identifier; // Unique identifier for this object
+@property (retain) NSString* persistentResourceIdentifier; // Unique persistent resource identifier for this object
@property (retain) NSDictionary* preliminaryMetadata; // Immediate (cheap) metadata
@property (retain) NSDictionary* metadata; // On demand (expensive) metadata (also contains preliminaryMetadata), initially nil
View
14 IMBObject.m
@@ -130,6 +130,7 @@ @implementation IMBObject
@synthesize atomic_bookmark = _bookmark;
@synthesize name = _name;
@synthesize identifier = _identifier;
+@synthesize persistentResourceIdentifier = _persistentResourceIdentifier;
@synthesize preliminaryMetadata = _preliminaryMetadata;
@synthesize metadata = _metadata;
@@ -179,6 +180,7 @@ - (void) dealloc
IMBRelease(_bookmark);
IMBRelease(_name);
IMBRelease(_identifier);
+ IMBRelease(_persistentResourceIdentifier);
IMBRelease(_preliminaryMetadata);
IMBRelease(_metadata);
@@ -209,6 +211,7 @@ - (id) initWithCoder:(NSCoder*)inCoder
self.atomic_bookmark = [coder decodeObjectForKey:@"bookmark"];
self.name = [coder decodeObjectForKey:@"name"];
self.identifier = [coder decodeObjectForKey:@"identifier"];
+ self.persistentResourceIdentifier = [coder decodeObjectForKey:@"persistentResourceIdentifier"];
self.error = [inCoder decodeObjectForKey:@"error"];
self.preliminaryMetadata = [coder decodeObjectForKey:@"preliminaryMetadata"];
@@ -247,6 +250,7 @@ - (void) encodeWithCoder:(NSCoder*)inCoder
[coder encodeObject:self.bookmark forKey:@"bookmark"];
[coder encodeObject:self.name forKey:@"name"];
[coder encodeObject:self.identifier forKey:@"identifier"];
+ [coder encodeObject:self.persistentResourceIdentifier forKey:@"persistentResourceIdentifier"];
[coder encodeObject:self.error forKey:@"error"];
[coder encodeObject:self.preliminaryMetadata forKey:@"preliminaryMetadata"];
@@ -288,6 +292,7 @@ - (id) copyWithZone:(NSZone*)inZone
copy.atomic_bookmark = self.bookmark;
copy.name = self.name;
copy.identifier = self.identifier;
+ copy.persistentResourceIdentifier = self.persistentResourceIdentifier;
copy.error = self.error;
copy.preliminaryMetadata = self.preliminaryMetadata;
@@ -317,6 +322,15 @@ - (id) copyWithZone:(NSZone*)inZone
#pragma mark
#pragma mark Helpers
+//- (void) setIdentifier:(NSString *)identifier
+//{
+// if (identifier == nil) {
+// NSLog(@"Nil identifier");
+// } else {
+// _identifier = identifier;
+// }
+//}
+
// Convert location to url...
View
17 IMBParser.h
@@ -124,10 +124,25 @@
- (NSString*) identifierForObject:(IMBObject*)inObject;
+// Returns an identifier for the resource that self denotes and that is meant to be persistent across launches
+// (e.g. when host app developers need to persist usage info of media files when implementing the badging delegate API).
+// This standard implementation is based on file reference URLs - so it will only work for file based URLs.
+// Subclass to adjust to the needs of your parser.
+
+- (NSString*) persistentResourceIdentifierForObject:(IMBObject*)inObject;
+
+// Returns the form of the persistent resource identifier for inObject that was used in iMedia2.
+// You can use this string to compare against your app's stored identifiers and convert them to
+// their new identifiers (persistentResourceIdentifierForObject:).
+// NOTE: This method should only be invoked for such purpose. It might be removed from the framework
+// in future versions.
+
+- (NSString*) iMedia2PersistentResourceIdentifierForObject:(IMBObject*)inObject;
+
// Subclasses may want to override this method to provide a backward compatible string.
// See further comments in implementation file...
-- (NSString*) identifierPrefix;
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix;
// Returns a minimal image for a given file system item that can be used as an icon for IMBNode...
View
69 IMBParser.m
@@ -264,14 +264,14 @@ - (NSData*) bookmarkForObject:(IMBObject*)inObject error:(NSError**)outError
#pragma mark
-#pragma mark Helpers
+#pragma mark Identifiers
// This helper method can be used by subclasses to construct identifiers of form "classname://path/to/node"...
- (NSString*) identifierForPath:(NSString*)inPath
{
- NSString* prefix = [self identifierPrefix];
+ NSString* prefix = [self iMedia2PersistentResourceIdentifierPrefix];
return [NSString stringWithFormat:@"%@:/%@",prefix,inPath];
}
@@ -279,30 +279,63 @@ - (NSString*) identifierForPath:(NSString*)inPath
//----------------------------------------------------------------------------------------------------------------------
-// This identifier string for IMBObject (just like IMBNode.identifier) can be used to uniquely identify an IMBObject.
-// This can be of use to host app developers who needs to cache usage info of media files in some dictionary when
-// implementing the badging delegate API. Simply using the path of a local file may not be reliable in those cases
-// where a file originated from a remote source and first had to be downloaded. For this reason using the identifier
-// as a key is more reliable...
-
+// This identifier string for IMBObject (just like IMBNode.identifier) can be used to uniquely identify an IMBObject
+// throughout a session. If you need a persistent identifier that identifies the resource associated with an IMBObject
+// use persistentResourceIdentifierForObject: instead.
- (NSString*) identifierForObject:(IMBObject*)inObject
{
- NSString* prefix = [self identifierPrefix];
+ NSString* parserClassName = NSStringFromClass([self class]);
+ NSUInteger libraryHash = [[[self mediaSource] path] hash];
+ NSString* path = [inObject.location path];
+ NSString* identifier = [NSString stringWithFormat:@"%@:%d/%@",parserClassName,libraryHash,path];
+ return identifier;
+}
+
+
+// Returns an identifier for the resource that self denotes and that is meant to be persistent across launches of the app
+// (e.g. when host app developers need to persist usage info of media files when implementing the badging delegate API).
+// This standard implementation is based on file reference URLs - so it will only work for file based URLs that denote
+// existing files.
+// Subclass to adjust to the needs of your parser.
+
+- (NSString*) persistentResourceIdentifierForObject:(IMBObject*)inObject
+{
+ NSURL *fileReferenceURL = [[inObject URL] fileReferenceURL];
+ if (fileReferenceURL)
+ {
+ return [fileReferenceURL absoluteString];
+ } else {
+ NSLog(@"Could not create persistent resource identifier for %@: resource %@ is not a file or does not exist",
+ inObject, [inObject URL]);
+ return nil;
+ }
+}
+
+
+// Returns the form of the persistent resource identifier for inObject that was used in iMedia2 (which has some
+// shortcomings). You can use this string to compare against your app's stored identifiers and convert them to
+// their new identifiers (persistentResourceIdentifierForObject:).
+// NOTE: This method should only be invoked for such purpose. It might be removed from the framework
+// in future versions.
+
+- (NSString*) iMedia2PersistentResourceIdentifierForObject:(IMBObject*)inObject
+{
+ NSString* prefix = [self iMedia2PersistentResourceIdentifierPrefix];
NSString* path = [inObject.location path];
- NSString* identifier = [NSString stringWithFormat:@"%@:/%@",prefix,path];
+ NSString* identifier = [NSString stringWithFormat:@"%@/%@",prefix,path];
return identifier;
}
// This method should be overridden by subclasses to return an appropriate prefix for IMBObject identifiers. Refer
-// to the method identifierForObject: to see how it is used. Historically we used class names as the prefix.
-// However, during the evolution of iMedia class names can change and identifier string would thus also change.
-// This is undesirable, as thing that depend of the immutability of identifier strings would break. One such
-// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
-// class can override this method to return a prefix that matches the historic class name...
+// to the method iMedia2PersistentResourceIdentifierForObject: to see how it is used. Historically we used class names
+// as the prefix. However, during the evolution of iMedia class names can change and identifier string would thus
+// also change. Being non-persistent this is undesirable, as thing that depend of the immutability of identifier strings
+// would break. One such example is object badges, which use such identifiers. To gain backward compatibilty, a parser
+// class can override this method to return a prefix that matches the historic class name used in iMedia2
-- (NSString*) identifierPrefix
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
{
return NSStringFromClass([self class]);
}
@@ -311,6 +344,10 @@ - (NSString*) identifierPrefix
//----------------------------------------------------------------------------------------------------------------------
+#pragma mark
+#pragma mark Helpers
+
+
// This method makes sure that we have an image with a bitmap representation that can be archived...
- (NSImage*) iconForItemAtURL:(NSURL*)url error:(NSError **)error;
View
1  IMBParserMessenger.m
@@ -381,6 +381,7 @@ - (void) _setObjectIdentifierWithParser:(IMBParser*)inParser onNodeTree:(IMBNode
for (IMBObject* object in inNode.objects)
{
object.identifier = [inParser identifierForObject:object];
+ object.persistentResourceIdentifier = [inParser persistentResourceIdentifierForObject:object];
}
for (IMBNode* subnode in inNode.subnodes)
View
8 IMBTestAppDelegate.m
@@ -619,9 +619,11 @@ - (void) concludeDragOperationForObjects:(NSArray*)inObjects
{
for (IMBObject* object in inObjects)
{
- [self.usedObjects setObject:object forKey:object.identifier];
+ if (object.persistentResourceIdentifier)
+ {
+ [self.usedObjects setObject:object forKey:object.persistentResourceIdentifier];
+ }
}
-
IMBNodeViewController* controller = [[IMBPanelController sharedPanelController] currentNodeViewController];
[controller setObjectContainerViewNeedsDisplay:YES];
}
@@ -636,7 +638,7 @@ - (CGImageRef) badgeForObject:(IMBObject*)inObject
{
static CGImageRef badgeImage = NULL;
- if ([self.usedObjects valueForKey:inObject.identifier])
+ if (inObject.persistentResourceIdentifier && [self.usedObjects valueForKey:inObject.persistentResourceIdentifier])
{
if (badgeImage == NULL)
{
View
4 IMBiPhotoImageParser.m
@@ -67,13 +67,13 @@ @implementation IMBiPhotoImageParser
// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
-// -[IMBParser identifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
// However, during the evolution of iMedia class names can change and identifier string would thus also change.
// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
// class must override this method to return a prefix that matches the historic class name...
-- (NSString*) identifierPrefix
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
{
return @"IMBiPhotoParser";
}
View
4 IMBiPhotoMovieParser.m
@@ -76,13 +76,13 @@ - (NSString*) iPhotoMediaType
// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
-// -[IMBParser identifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
// However, during the evolution of iMedia class names can change and identifier string would thus also change.
// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
// class must override this method to return a prefix that matches the historic class name...
-- (NSString*) identifierPrefix
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
{
return @"IMBiPhotoVideoParser";
}
View
16 IMBiTunesAudioParser.m
@@ -279,6 +279,22 @@ - (NSDictionary*) plist
//----------------------------------------------------------------------------------------------------------------------
+// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// However, during the evolution of iMedia class names can change and identifier string would thus also change.
+// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
+// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
+// class must override this method to return a prefix that matches the historic class name...
+
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
+{
+ return @"IMBiTunesParser";
+}
+
+
+//----------------------------------------------------------------------------------------------------------------------
+
+
// Create an identifier from the AlbumID that is stored in the XML file. An example is "IMBiPhotoParser://AlbumId/17"...
- (NSString*) identifierWithPersistentID:(NSString*)inPersistentID
View
13 IMBiTunesMovieParser.m
@@ -68,6 +68,19 @@ @implementation IMBiTunesMovieParser
//----------------------------------------------------------------------------------------------------------------------
+// This method must return an appropriate prefix for IMBObject identifiers. Refer to the method
+// -[IMBParser iMedia2PersistentResourceIdentifierForObject:] to see how it is used. Historically we used class names as the prefix.
+// However, during the evolution of iMedia class names can change and identifier string would thus also change.
+// This is undesirable, as things that depend of the immutability of identifier strings would break. One such
+// example are the object badges, which use object identifiers. To guarrantee backward compatibilty, a parser
+// class must override this method to return a prefix that matches the historic class name...
+
+- (NSString*) iMedia2PersistentResourceIdentifierPrefix
+{
+ return @"IMBiTunesVideoParser";
+}
+
+
// Exclude some playlist types...
- (BOOL) shoudlUsePlaylist:(NSDictionary*)inPlaylistDict
Please sign in to comment.
Something went wrong with that request. Please try again.