I’ve written this bit of code to process a URL in string form to try and fetch retina image of possible. The intent is that is turns
scheme://host/path/name.extension
into
scheme://host/path/name@2x.extension
The URL is predictable so assuming, for example, there is just one ‘.’ in the final filename is safe. But I have that iOS feeling, where I’m wondering if this is too much code to get this done; is there a better, maybe API-provided way to do this?
This is just the beginning of a method that kicks off the request.
- (NSData *)fetchResourceWithURLLocation:(NSString *)location
requestedBy:(id<DataRequestDelegate>)requester
withIdentifier:(id)requestID {
NSData *resultData = nil;
// some disassembly to get rid of the double '/' in scheme
NSURL *locationURL = [NSURL URLWithString:location];
NSString *host = [locationURL host];
NSString *scheme = [locationURL scheme];
NSString *dataPath = [locationURL relativePath];
// if this is a retina display, rewrite the dataPath to use @2x
if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0)) {
NSArray *pathComponents = [dataPath componentsSeparatedByString:@"/"];
NSString *nameComponent = [pathComponents lastObject];
NSArray *nameComponents = [nameComponent componentsSeparatedByString:@"."];
NSAssert(([nameComponents count] == 2), @"nameComponent contains more than one \".\"");
nameComponent = [NSString stringWithFormat:@"%@@2x.%@", [nameComponents objectAtIndex:0], [nameComponents lastObject]];
dataPath = @"";
for(NSString *pathComponent in pathComponents) {
if(pathComponent != [pathComponents lastObject])
dataPath = [dataPath stringByAppendingString:[NSString stringWithFormat:@"%@/", pathComponent]];
}
dataPath = [dataPath stringByAppendingString:nameComponent];
}
// reassembly to check existence
NSString *processedLocation = [NSString stringWithFormat:@"%@://%@%@", scheme, host, dataPath];
You are right to think that is a dramatic amount of code to insert a string into your address string. What you want to do is fairly straightforward, so here is an example method that just pops the
"@2x"into a string just before the last".". It returns nil if there is no".". Further explanation in code comments.When tested like:
It logs:
Small side note:
If the original string was a mutable string, you could use
[mutableAddressString insertString:@"@2x" atIndex:extDotRange.location]instead of calculating a replacement range. Not worth creating a mutable for though.