简体   繁体   中英

NSFileManager: Unable to create directory on some devices

I'd like to download a zip file and move the downloaded file using this code snippet:

NSFileManager *fileManager = [NSFileManager defaultManager];  
BOOL isDir;  
NSString *path = ...;  
NSString *targetPath = ...;  

NSString *targetDirectory = [targetPath stringByDeletingLastPathComponent];  
if (![fileManager fileExistsAtPath:targetDirectory isDirectory:&isDir] && !isDir)  
{  
     NSError *dirError;  
     if (! [fileManager createDirectoryAtPath:targetDirectory withIntermediateDirectories:YES attributes:nil error:&dirError])  
     {  
          NSLog(@"%@", dirError.localizedDescription);  
     }  
}  


//...  



if ([fileManager moveItemAtPath:path toPath:targetPath error:&error])  
{  
     success = YES;  
} 

It has worked fine on our test devices and it has also worked fine on iOS 8.x. Now, some beta tester have reported that moving the zip file fails on devices with iOS 9.x because the target directory does not exist. Not in general, only on a few devices running iOS 9.x. I have updated our test devices to iOS 9.1 and it still works. The zip file is the same for all test users.

The paths are not hard-coded, but are generated right before the code snippet. The zip file gets always copied from the temporary root directory to the subpath /map/maps/deu/deu_1.0.zip , eg

path = @"/private/var/mobile/Containers/Data/Application/0EAF2FEE-4E9F-4826-94AE-7D31D2B4D8E7/tmp/deu_1.0.zip";  
targetPath = @"/var/mobile/Containers/Data/Application/0EAF2FEE-4E9F-4826-94AE-7D31D2B4D8E7/Documents/map/maps/deu/deu_1.0.zip";  
targetDirectory = @"/var/mobile/Containers/Data/Application/0EAF2FEE-4E9F-4826-94AE-7D31D2B4D8E7/Documents/map/maps/deu"; 

The paths are always generated by reading the root path of the temporary directory resp. the documents directory and by appending the filename (deu_1.0.zip) resp. the subpath (/map/maps/deu/deu_1.0.zip):

From helper class MCPath:

+ (NSString *)directoryDocuments  
{  
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    NSString *directory = [paths objectAtIndex:0];  
    return directory;  
}  
+ (NSString *)directoryTemporaryFiles  
{  
    return NSTemporaryDirectory();  
} 

And here is the snippet how the paths are generated (filename read from URL but always the same URL, subpath stored in mapInfo object):

NSString *path = [[MCPath directoryTemporaryFiles] stringByAppendingPathComponent:[url lastPathComponent]];  
NSString *targetPath = [[MCPath directoryMap] stringByAppendingPathComponent:[mapInfo subPath:YES]]; 

But anyway, the code snippet on top checks if the target directory exists. If not, the target directory gets created. Finally, the zip file should be moved from the temporary directory to the target directory. That is the intention and it also works fine on our test devices. But not on all devices, especially on devices running iOS 9.x. Does anybody have any idea why? Does anybody know if there are known bugs in iOS 9.x while creating directories or moving files?

Thanks a lot for your response.

I don't believe this is correct:

if (![fileManager fileExistsAtPath:targetDirectory isDirectory:&isDir] && !isDir)

The docs state this about isDirectory : If path doesn't exist, this value is undefined upon return.

Therefore && !isDir is definitely wrong.

You want:

if (![fileManager fileExistsAtPath:targetDirectory isDirectory:&isDir]) {
    // Create directory
} else if (!isDir) {
    // Report error: plain file using that name and cannot continue
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM