Je suppose que c'est un problème de débutant, mais j'essayais de vérifier si un répertoire existe dans mon dossier Documents sur l'iPhone. J'ai lu la documentation et j'ai trouvé ce code qui s'est malheureusement écrasé avec EXC_BAD_ACCESS dans la ligne BOOL fileExists:
-(void)checkIfDirectoryAlreadyExists:(NSString *)name
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *path = [[self documentsDirectory] stringByAppendingPathComponent:name];
BOOL fileExists = [fileManager fileExistsAtPath:path isDirectory:YES];
if (fileExists)
{
NSLog(@"Folder already exists...");
}
}
Je ne comprends pas ce que j'ai fait de mal? Il me semble tout parfait et il est certainement conforme à la documentation, non? Toute révélation sur l'endroit où je me suis trompé serait très appréciée! Merci.
ACTUALISÉ:
Ne fonctionne toujours pas...
-(void)checkIfDirectoryAlreadyExists:(NSString *)name
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *path = [[self documentsDirectory] stringByAppendingPathComponent:name];
BOOL isDir;
BOOL fileExists = [fileManager fileExistsAtPath:path isDirectory:&isDir];
if (fileExists)
{
if (isDir) {
NSLog(@"Folder already exists...");
}
}
}
Jetez un oeil dans la documentation pour cette signature de méthode:
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory
Vous avez besoin d'un pointeur vers une variable BOOL comme argument, pas un BOOL lui-même. NSFileManager enregistrera si le fichier est un répertoire ou non dans cette variable. Par exemple:
BOOL isDir;
BOOL exists = [fm fileExistsAtPath:path isDirectory:&isDir];
if (exists) {
/* file exists */
if (isDir) {
/* file is a directory */
}
}
Juste au cas où quelqu'un aurait besoin d'un getter, cela crée un dossier dans Documents, s'il n'existe pas:
- (NSString *)folderPath
{
if (! _folderPath) {
NSString *folderName = @"YourFolderName";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [documentPaths objectAtIndex:0];
_folderPath = [documentsDirectoryPath stringByAppendingPathComponent:folderName];
// if folder doesn't exist, create it
NSError *error = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDir;
if (! [fileManager fileExistsAtPath:_folderPath isDirectory:&isDir]) {
BOOL success = [fileManager createDirectoryAtPath:_folderPath withIntermediateDirectories:NO attributes:nil error:&error];
if (!success || error) {
NSLog(@"Error: %@", [error localizedDescription]);
}
NSAssert(success, @"Failed to create folder at path:%@", _folderPath);
}
}
return _folderPath;
}
J'ai une classe Utility singleton que j'utilise pour des choses comme ça. Comme je ne peux pas mettre à jour ma base de données si elle reste dans Documents, je copie mes fichiers .sqlite de Documents vers/Bibliothèque/Documents privés à l'aide de ce code. La première méthode trouve la bibliothèque. Le second crée le dossier Documents privés s'il n'existe pas et renvoie l'emplacement sous forme de chaîne. La deuxième méthode utilise la même méthode de gestionnaire de fichiers que @wzboson.
+ (NSString *)applicationLibraryDirectory {
return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
}
+ (NSString *)applicationLibraryPrivateDocumentsDirectory {
NSError *error;
NSString *PrivateDocumentsDirectory = [[self applicationLibraryDirectory] stringByAppendingPathComponent:@"Private Documents"];
BOOL isDir;
if (! [[NSFileManager defaultManager] fileExistsAtPath:PrivateDocumentsDirectory isDirectory:&isDir]) {
if (![[NSFileManager defaultManager] createDirectoryAtPath:PrivateDocumentsDirectory
withIntermediateDirectories:NO
attributes:nil
error:&error]) {
NSLog(@"Create directory error: %@", error);
}
}
return PrivateDocumentsDirectory;
}
Je l'utilise comme ceci dans l'initialisation de mon coordinateur de magasin persistant. Cependant, le même principe s'applique à tous les fichiers.
NSString *libraryDirectory = [Utilities applicationLibraryPrivateDocumentsDirectory];
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:sqliteName];
NSString *destinationPath = [libraryDirectory stringByAppendingPathComponent:sqliteName];