0

I have a project, which contains images in its resources. For example: image1yellow.png, image2red.png, image3green.png... The number of these images could be different, but my app has to know the number and their names. So I want to collect these images from the resources by searching for them... The 'image' part of the title is constant and right after that there is a number. The final part of the title is always a color name (so..variable strings) >>> image+3+green=image3green. I think somehow I can search with these criterias...

madG
  • 13
  • 4
  • Start here for getting a listing of files, then perform the search through the array. http://stackoverflow.com/questions/7900879/how-to-list-all-folders-and-their-subdirectories-files-in-iphone-sdk – trumpetlicks Feb 04 '13 at 21:32
  • If any of the provided solutions have aided in solving this problem, please either mark a solution that has answered the problem and/or up-vote any answers that you have found to be useful. Thanks! – Alex Smith Feb 08 '13 at 06:15

2 Answers2

0

EDIT

Actually, NSBundle has an even more convienient method :

URLsForResourcesWithExtension:subdirectory:inBundleWithURL:

With this you can get an array of all your png ressources and then use it to determine which image you want.

To get the ressources starting with image you can then use :

    NSArray * array = [NSBundle URLsForResourcesWithExtension:@"png" subdirectory:nil inBundleWithURL:[[NSBundle mainBundle] bundleURL]];
    [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [obj isKindOfClass:NSURL.class] && [[((NSURL *) obj) resourceSpecifier] hasPrefix:@"image"];
    }];

Of course, this is NOT the best way to retrieve it, I'm almost sure you have some simple logic to get the end of the image name, you can probably have a better algorithm (maybe you could just sort the array and use an enumerator). Also you might want to keep the final result (e.g. all ressources starting with image) in a static field to retrieve them faster, instead of redoing all the work each time.

Basically, you have to do the rest of the implementation according to what you really want to have (or give example of your logic to get the final image).

Original response

I'm not sure I understand what you want but I think it's something like that :

    NSArray * ressources = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[[NSBundle mainBundle] resourcePath] error:&error];

You could also consider

contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:

Xval
  • 938
  • 5
  • 17
  • Ok, thanks! With your original response (NSArray *ressources...) I could list out the projects resources. This is an improvement, but I still don't know how to list out only the images which starting the 'image' tag. – madG Feb 05 '13 at 11:07
  • You could look for this in the results of the array – Xval Feb 05 '13 at 14:09
  • This will work but it won't guarantee the format of the string image followed by an integer followed by a colour. It only checks if the beginning word is an image and the file type is a png. – Alex Smith Feb 06 '13 at 00:16
  • Indeed, i forgot about this, but it would only need another test to be sure the following characters are integers. As i said, the following code to get the 'correct' image name depends in the real logic of the image name construction, which isn't clear. For example it would probably be faster to iterate all the png files found and construct an array of all 'correct' image names directly. – Xval Feb 06 '13 at 14:50
0

Since you know the structure of the file name, create a new NSString with a particular format given a set of variables:

NSUInteger arbitraryNumber = 7;
NSString *color = @"yellow";
NSString *extension = @"png";
NSString *imageName = [NSString stringWithFormat:@"image%d%@.%@", arbitraryNumber, color, extension];

Or assign these images to an array in a loop...

EDIT: After clear oversight with the question at hand...

The following is a recursive solution using regular expressions to get the desired "phrase" in a filename. I wrote this just for you and tested it. Of course, this stuff is kind of tricky so if you hand it a file name like "images23green.png" it may fail. If you're concerned about this, you should learn more about regular expressions!

To have this execute, just call [self loadImages].

- (void)loadImages
{
    NSDictionary *filenameElements = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"^(image)\\d+\\w+\\.\\w{3}$", @"^(image)", @"^\\d+", @"^\\w+", @"^\\w{3}", nil] forKeys:[NSArray arrayWithObjects:@"filename", @"image", @"number", @"color", @"fileExtension", nil]];
    NSString *string = @"image23green.png";      // Example file name
    NSError *error = NULL;
    error = [self searchForSubstring:@"image" inString:string withRegexFormatDictionary:filenameElements beginAtIndex:0];
}

- (NSError *)searchForSubstring:(NSString *)key inString:(NSString *)givenString withRegexFormatDictionary:(NSDictionary *)filenameElements beginAtIndex:(NSInteger)index
{
    NSError *error = NULL;
    NSString *substring = [givenString substringFromIndex:index];

    NSString *regexPattern = [filenameElements objectForKey:key];
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexPattern options:NSRegularExpressionCaseInsensitive error:&error];
    NSArray *matches = [regex matchesInString:substring options:0 range:NSMakeRange(0, [substring length])];
    if ([matches count] > 0)
    {
        NSRange matched = [[matches objectAtIndex:0] rangeAtIndex:0];
        NSLog(@"matched: %@", [substring substringWithRange:matched]);

        index = 0;
        NSString *nextKey;
        if      ([key isEqualToString:@"image"])         { nextKey = @"number"; index = matched.length; }
        else if ([key isEqualToString:@"number"])        { nextKey = @"color"; index = matched.length; }
        else if ([key isEqualToString:@"color"])         { nextKey = @"fileExtension"; index = matched.length + 1; }
        else if ([key isEqualToString:@"fileExtension"]) { nextKey = nil; }
        if (nextKey)
            error = [self searchForSubstring:nextKey inString:substring withRegexFormatDictionary:filenameElements beginAtIndex:index];
    }
    return error;
}

This solution accepts a filename with a numeric value of any length, any color name length that will only accept alphabetical characters (i.e., no hyphens allowed) and a 3 character long file extension. This may be changed by replacing {3} to {3-4} if you want a range of 3 to 4 character length, and so on...

Alex Smith
  • 468
  • 5
  • 22
  • Yes! I know the structure of the file name. Its always starting with an 'image' tag, but the number and the color names after this part are unknown... – madG Feb 05 '13 at 11:10
  • There's an obvious fix to the problem I mentioned in my edit. I will add it tomorrow. – Alex Smith Feb 05 '13 at 14:48
  • I've edited the code to be much more reliable. Hope this helps! – Alex Smith Feb 06 '13 at 00:06
  • I should just mention that this code does no looping through your resources, you must implement that yourself. This JUST does string matching. – Alex Smith Feb 06 '13 at 00:18