Camsoft
Camsoft

Reputation: 12005

Creating a safe filename from an NSString?

Is there way to take a NSString and turn it into a safe version that can be used as a filename to save to the user Documents directory on the iPhone.

I'm currently doing something like this:

NSString *inputString = @"This is sample text which may have funny chars and spaces in.";

NSInteger len = [inputString length];        
NSString *newFilename = [[inputString substringToIndex:MIN(20, len)] stringByAppendingPathExtension:@"txt"];

This currently leaves me with something like:

This is sample text .txt

Need to make sure characters that are not allowed in filenames and stripped out too.

Upvotes: 6

Views: 1381

Answers (3)

Chris Fox
Chris Fox

Reputation: 641

If all you really need is a safely random filename then just use SecRandomCopyBytes to the length you want and base64-encode it.

Upvotes: -1

Hollance
Hollance

Reputation: 2976

You can also do it the old fashioned way instead of using a regex:

NSString* SanitizeFilename(NSString* filename)
{
    NSMutableString* stripped = [NSMutableString stringWithCapacity:filename.length];
    for (int t = 0; t < filename.length; ++t)
    {
        unichar c = [filename characterAtIndex:t];

        // Only allow a-z, A-Z, 0-9, space, -
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') 
        ||  (c >= '0' && c <= '9') || c == ' ' || c == '-')
            [stripped appendFormat:@"%c", c];
        else
            [stripped appendString:@"_"];
    }

    // No empty spaces at the beginning or end of the path name (also no dots
    // at the end); that messes up the Windows file system.
    return [stripped stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

Upvotes: 3

cutsoy
cutsoy

Reputation: 10251

You'll probably end up with some regex or something. Simply because it's too dangerous to use a except-filter (you may miss some illegal chars).

Therefor I'ld recommend you to use RegexKitLite (http://regexkit.sourceforge.net/RegexKitLite/), combined with the following line of code:

inputString = [inputString stringByReplacingOccurencesOfRegex:@"([^A-Za-z0-9]*)" withString:@""];

This will replace all characters except A-Z, a-z and 0-9 =)!

Upvotes: 5

Related Questions