Search code examples
ioscocoansdatawritetofile

Proper way to giving name to file when [NSData writeToFile:] used


I'm using that code to save downloaded videos from internet to application document folder:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *save_it = [documentsDirectory stringByAppendingPathComponent:video_filename];


NSError *error;
BOOL success = [fileData writeToFile:save_it options:0 error:&error];
if (!success) {
    NSLog(@"writeToFile failed with error %@", error);
}

it works, but if there is a slash "/" in the video_filename it breaks because of slash is directory seperator, I know.

For example when video_filename is : Best Video / Best Song Ever.3gpp , log says:

{NSFilePath=/Users/Apple/Library/Developer/CoreSimulator/Devices/5A7D36F5-6EDB-495D-9E8E-B9EB22E5357C/data/Containers/Data/Application/B1D0AC48-D84C-4A0D-9F09-08BF4C45DD32/Documents/Best Video / Best Song Ever.3gpp, NSUnderlyingError=0x7d339430 "The operation couldn’t be completed. No such file or directory"}

I don't know is there any other special character that will make crashing,

So what is the best way of cleaning these special characters from nsstring ?

We can make SEO friendly urls in PHP, I'm searching a function like that to do this.


Solution

  • The first problem I see here is that your file path includes some spaces. in the example you gave, the value of video_filename variable is "Best Video / Best Song Ever.3gpp" which includes spaces around the slash. You first have to delete the spaces, this might help you do that:

    NSArray *components = [video_filename componentsSeparatedByString:@"/"];
    
    for (NSInteger i = 0, i < components.count, ++i) {
        NSString *string = components[i];
        string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
        components[i] = string;
    }
    
    NSString *path = [components componentsJoinedByString:@"/"];
    

    If I understood correctly, your video_filename might be either in the form xxx.3gpp or yyy/xxx.3gpp. If it's the format of yyyy/xxxx.3gpp, you first have to create a directory named yyyy and then save the file to that directory. This might help you do that:

    - (void)createDirectory:(NSString *)directoryName
                 atFilePath:(NSString *)filePath
    {
        NSString *filePathAndDir = [filePath
                                    stringByAppendingPathComponent:directoryName];
        NSError *error;
    
        if (![[NSFileManager defaultManager] createDirectoryAtPath:filePathAndDir
                                       withIntermediateDirectories:NO
                                                        attributes:nil
                                                             error:&error]) {
            NSLog(@"Create directory error: %@", error);
        }
    }
    

    and the way you would use this is

    [self createDirectory:components[0] atFilePath:documentsDirectory];
    

    hope this helps!