8

How can the filename be extracted from an ALAsset?

Is there a way to get this via the url or some other way?

some_id
  • 29,466
  • 62
  • 182
  • 304

2 Answers2

33

From iOS 5.0 you can get the file from ALAssetRepresentation Class.

ALAssetRepresentation *rep = [anAssetItem defaultRepresentation];
NSString *fileName = [rep filename];
Seunghoon
  • 5,632
  • 5
  • 35
  • 41
5

Update: As yeonsh notes below, from iOS 5.0 there is a better way. This answer is relevant for iOS < 5.0.

You can extract an URL from the ALAsset, but all the filenames are the same, on the form

assets-library://asset/asset.JPG?id=1000000001&ext=JPG

If you for some reason need different file names, try making an internal-external paradigm:

#import <Foundation/Foundation.h>

@interface NSURL (NSURL_Asset)

- (NSURL*) toExternalForm;
- (NSURL*) fromExternalForm;
- (NSString*) toExternalFilename;    

@end

#import "NSURL+Asset.h"
#import "URLParser.h" // from http://iphone.demay-fr.net/2010/04/parsing-url-parameters-in-a-nsstring/

static NSString *const EXTERNAL_TOKEN = @"/assetExternalForm/";

@implementation NSURL (NSURL_Asset)

// assets-library://asset/asset.JPG/assetExternalForm/1000000001.JPG -> assets-library://asset/asset.JPG?id=1000000001&ext=JPG
- (NSURL*) fromExternalForm {
    if([self.scheme isEqualToString:@"assets-library"]) {
        NSRange slash = [self.absoluteString rangeOfString:EXTERNAL_TOKEN options:NSBackwardsSearch];
        if(slash.location != NSNotFound) {

            NSRange dot = [self.absoluteString rangeOfString:@"." options:NSBackwardsSearch];

            if(dot.location != NSNotFound) {
                NSString* extention = [self.absoluteString substringFromIndex:(dot.location + dot.length)];
                NSString* identifier = [self.absoluteString substringWithRange:NSMakeRange(slash.location + slash.length, dot.location - (slash.location + slash.length))];

                return [NSURL URLWithString:[NSString stringWithFormat:@"%@?id=%@&ext=%@", [self.absoluteString substringToIndex:slash.location], identifier, extention]];
            }
        }
    }
    return self;
}

// assets-library://asset/asset.JPG?id=1000000001&ext=JPG -> assets-library://asset/asset.JPG/assetExternalForm/1000000001.JPG
- (NSURL*) toExternalForm {
    if([self.scheme isEqualToString:@"assets-library"]) {
        NSRange range = [self.absoluteString rangeOfString:@"?"];
        if(range.location != NSNotFound) {
            URLParser *parser = [[[URLParser alloc] initWithURLString:self.absoluteString] autorelease];

            NSString* extention = [parser valueForVariable:@"ext"];
            NSString* identifier = [parser valueForVariable:@"id"];

            if(extention != NULL && identifier != NULL) {
                return [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@.%@", [self.absoluteString substringToIndex:range.location], EXTERNAL_TOKEN, identifier, extention]];
            }
        }
    }
    return self;
}

// assets-library://asset/asset.JPG?id=1000000001&ext=JPG -> 1000000001.JPG
- (NSString*) toExternalFilename {
    if([self.scheme isEqualToString:@"assets-library"]) {
        NSRange range = [self.absoluteString rangeOfString:@"?"];
        if(range.location != NSNotFound) {
            URLParser *parser = [[[URLParser alloc] initWithURLString:self.absoluteString] autorelease];

            NSString* extention = [parser valueForVariable:@"ext"];
            NSString* identifier = [parser valueForVariable:@"id"];

            if(extention != NULL && identifier != NULL) {
                return [NSString stringWithFormat:@"%@.%@", identifier, extention];
            }
        }
    }
    return NULL;
}

@end

Note that you do not need a filename to read the content of an ALAsset. Use the ALAsset.defaultRepresentation.getBytes method for that.

Seunghoon
  • 5,632
  • 5
  • 35
  • 41
ThomasRS
  • 8,215
  • 5
  • 33
  • 48
  • @Thomas: I need the filenames for adding multiple images to an email as attachments. How would these filenames be accessed via the ALAssets? thanks – some_id Feb 19 '11 at 16:32
  • Well the MFMailComposeViewController.addAttachmentData method needs the NSData of the ALAsset, and then 'any' filename and the mimeType. So I would modify the toExternalForm method above to just return the filename, e.g.'1000000001.JPG', and make a method which maps from filename extension to mimeType, '.JPG' to -> image/jpeg. – ThomasRS Feb 19 '11 at 17:30
  • @Thomas: How should this be used? Can I just use the toExternalForm method in my current class or what is the @implementation NSURL for? If I can use it in my current class(just the method), what is self.scheme? Thanks a lot. – some_id Feb 20 '11 at 00:29
  • No real magic tricks, copy the method to whatever class you want. The @implementation NSURL is just for extending the NSURL class for those pieces of code whom want to import that header / add those methods to NSURL, sort of a 'utility' extension for NSURL. Yeah so this is kind of a clean approach, with the right setup, i.e. import, you can make calls to NSURL with in the above methods :P – ThomasRS Feb 20 '11 at 08:10
  • @Thomas: Thanks for all the help, I have an issue that URLParser doesnt exist, when importing(both imports dont exist). Is there a framework I should add? Also "EXTERNAL_TOKEN" doesnt exist. – some_id Feb 20 '11 at 10:56
  • EXTERNAL_TOKEN does exist, see the above code? And see http://iphone.demay-fr.net/2010/04/parsing-url-parameters-in-a-nsstring/. – ThomasRS Feb 20 '11 at 17:43
  • My bad. Thanks. So what is this used on? If I want to get the filename? What calls this function. Sorry for all the questions, I am just not sure how to use this, and no one else seems to know. – some_id Feb 20 '11 at 21:50
  • Modify the NSURL URLWithString method to change what is returned. – ThomasRS Feb 20 '11 at 22:28
  • @Thomas: I really need your help with this. I read the link, but am still unsure how to even use this. What would call it or how do I get the filename. your my only hope. No one else can answer this. – some_id Feb 21 '11 at 13:14
  • That seems to work thanks. it extracts the filename, but doesnt display the image . i get the print out "the image in mail for loop index:0 is 1000000002.JPG" – some_id Feb 22 '11 at 09:18
  • search this site if you have problems with mail, if you find nothing then start a new question with a good and understandable description of your problem. – ThomasRS Feb 22 '11 at 15:15