Skip to content

Instantly share code, notes, and snippets.

@algal
Created June 16, 2015 22:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save algal/da7af06404e687c44358 to your computer and use it in GitHub Desktop.
Save algal/da7af06404e687c44358 to your computer and use it in GitHub Desktop.
stringRelativePath
//
// NSString+RelativePaths.m
#import "NSString+RelativePaths.h"
/**
Returns a path to resourcePath, relative to anchorPath.
@param resourcePath trailing path components, possibly forming a valid absolute path
@param anchorPath trailing path components, of the anchorPath.
This is for constructing a path to a resource relative to some other anchorPath,
for functions like +[UIImage imageNamed:] which only accept paths relative to a certain
anchor like the bundle root.
For example:
NSString * absPath = @"/absolute/path/to/my/image.png";
UIImage * imageAbs = [UIImage imageNamed:absPath]; // does NOT work
NSString * relPath = PathRelativeToAnchorPath(absPath,[[NSBundle mainBundle] bundlePath]);
UIImage * imageRel = [UIImage imageNamed:relPath]; // works
Code adapted from:
http://stackoverflow.com/questions/6539273/objective-c-code-to-generate-a-relative-path-given-a-file-and-a-directory
*/
static NSString* PathRelativeToAnchorPath(NSString * resourcePath, NSString * anchorPath)
{
NSArray *pathComponents = [resourcePath pathComponents];
NSArray *anchorComponents = [anchorPath pathComponents];
NSInteger componentsInCommon = MIN([pathComponents count], [anchorComponents count]);
for (NSInteger i = 0, n = componentsInCommon; i < n; i++) {
if (![[pathComponents objectAtIndex:i] isEqualToString:[anchorComponents objectAtIndex:i]]) {
componentsInCommon = i;
break;
}
}
NSUInteger numberOfParentComponents = [anchorComponents count] - componentsInCommon;
NSUInteger numberOfPathComponents = [pathComponents count] - componentsInCommon;
NSMutableArray *relativeComponents = [NSMutableArray arrayWithCapacity:
numberOfParentComponents + numberOfPathComponents];
for (NSInteger i = 0; i < numberOfParentComponents; i++) {
[relativeComponents addObject:@".."];
}
[relativeComponents addObjectsFromArray:
[pathComponents subarrayWithRange:NSMakeRange(componentsInCommon, numberOfPathComponents)]];
return [NSString pathWithComponents:relativeComponents];
}
@implementation NSString (RelativePaths)
- (NSString*)stringWithPathRelativeTo:(NSString*)anchorPath {
return PathRelativeToAnchorPath(self, anchorPath);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment