What characters are allowed in a iOS file name?

First of all, you're using the wrong method. Trimming the string will only remove characters in the beginning and the end of the string.

What you're looking for is something more like:

fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"_"];

However, that's a suboptimal solution, since you'll have to do that for every character you want to exclude, so maybe you want to keep looking or write you're own method for manipulating the string.

iOS is UNIX based and as such I suppose it supports almost any characters in filenames. UNIX allows white spaces, <, >, |, \, :, (, ), &, ;, as well as wildcards such as ? and *, to be quoted or escaped using \ symbol. However I wouldn't use any of those characters in my filenames. In fact, I would restrict the characters in my filenames to 'a'-'z', '0'-'9', '_' and '.'.


Use RegEx:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^a-zA-Z0-9_]+" options:0 error:nil];
filename = [regex stringByReplacingMatchesInString:filename options:0 range:NSMakeRange(0, filename.length) withTemplate:@"-"];

As I did not see a list with allowed characters in this question but the question wanted a list with such characters I am adding a bit more details on this topic.

First we need to know what is the file system that iOS devices use. Using multiple online sources this seems to be HFSX which is the HFS+ case sensitive version. And including one link here for reference: https://apple.stackexchange.com/questions/83671/what-filesystem-does-ios-use

Now that we know what the file system is we can look for what characters are not allowed. And these seem to be: colon (:) and slash (/). Here is a link for reference: http://www.comentum.com/File-Systems-HFS-FAT-UFS.html

Having this information and what others have written in this thread my personal preference for removing not allowed characters from file names is the following Swift code:

filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()))
filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.illegalCharacterSet()))
filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.controlCharacterSet()))
filename = "-".join(filename.componentsSeparatedByString(":"))
filename = "-".join(filename.componentsSeparatedByString("/"))

The reason I am not preferring the RegEx approach is that it seems too restrictive to me. I do not want to restrict my users only to Latin characters. They may as well wish to use some Chinese, Cyrillic or whatever else they like.

Happy coding!


I find this to be cleaner and probably much more performant. This is based on Angel Naydenov's solution, but first constructing Character set with all invalid characters and then calling components(separatedBy:) just once.

Swift 3 & 4

var invalidCharacters = CharacterSet(charactersIn: ":/")
invalidCharacters.formUnion(.newlines)
invalidCharacters.formUnion(.illegalCharacters)
invalidCharacters.formUnion(.controlCharacters)

let newFilename = originalFilename
    .components(separatedBy: invalidCharacters)
    .joined(separator: "")

Swift 2

let invalidCharacters = NSMutableCharacterSet(charactersInString: ":/")
invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.newlineCharacterSet())
invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.illegalCharacterSet())
invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.controlCharacterSet())

let filename = originalFilename
    .componentsSeparatedByCharactersInSet(invalidCharacters)
    .joinWithSeparator("")