How to change permission of a directory recursively using NSFileManager setAttributes - objective-c

I'm currently using NSFileManager setAttributes to change the permission of a directory. My problem is that it doesn't appear to do so recursively. Is there any way to force it to do so?

I don't think there's a built-in method to do this, but it shouldn't be hard to do something like:
NSString *path = #"/The/root/directory";
NSDictionary *attributes; // Assume that this is already setup
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *subPaths = [fileManager subpathsAtPath:path];
for (NSString *aPath in subPaths) {
BOOL isDirectory;
[fileManager fileExistsAtPath:aPath isDirectory:&isDirectory];
if (isDirectory) {
// Change the permissions on the directory here
NSError *error = nil;
[fileManager setAttributes:attributes ofItemAtPath:aPath error:&error];
if (error) {
// Handle the error
}
}
}
This is untested, but should give you a starting point.

NSString *path = #"/User/user/aPath";
NSFileManager *manager = [[[NSFileManager alloc] init] autorelease];
if ([manager fileExistsAtPath: path]) {
NSDictionary *attrib = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:0], NSFileGroupOwnerAccountID,
[NSNumber numberWithInt:0], NSFileOwnerAccountID,
#"root", NSFileGroupOwnerAccountName,
#"root", NSFileOwnerAccountName, nil ];
NSError *error = nil;
[manager setAttributes:attrib ofItemAtPath:path error:&error];
NSDirectoryEnumerator *dirEnum = [manager enumeratorAtPath: path];
NSString *file;
while (file = [dirEnum nextObject]) {
[manager setAttributes:attrib ofItemAtPath:[path stringByAppendingPathComponent:file] error:&error];
}
}

Related

How to get list of contents from folder using contentsOfDirectoryAtPath in cocoa?

I want to fetch all contents of the folder and add to a submenu of NSMenuItems.
For achieving this, I'm using code given below:
NSArray *dirContents = [[NSArray alloc]init];
dirContents=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:updated error:nil];
This code is working but only in one folder. Strange but it is true. I have tried the same code for other folders but it gives nil value in dirContents.
So how can I access the list of all the contents of a selected folder?
Try this to track the access error.
NSError *error;
NSArray *dirContents = [[NSArray alloc]init];
dirContents=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:updated error:&error];
if(error){
NSLog(#"%#",error);
}
Make sure you use relative path to the directory, if the app is sandboxed, not absolute path.
NSURL *containerUrl =[[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:#"Your.app.container.id"];
path = [[containerUrl URLByAppendingPathComponent:#"your/folder/path"] path];
+(NSArray*)allURLs:(NSURL*)url{
NSFileManager *fileManager = [NSFileManager defaultManager];
//NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
NSURL *bundleURL = url;
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:bundleURL
includingPropertiesForKeys:#[NSURLNameKey, NSURLIsDirectoryKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:^BOOL(NSURL *url, NSError *error)
{
NSLog(#"[Error] %# (%#)", error, url);
return url;
}];
NSMutableArray *mutableFileURLs = [NSMutableArray array];
for (NSURL *fileURL in enumerator) {
NSString *filename;
[fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil];
NSNumber *isDirectory;
[fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
// Skip directories with '_' prefix, for example
if ([filename hasPrefix:#"_"] && [isDirectory boolValue]) {
[enumerator skipDescendants];
continue;
}
if (![isDirectory boolValue]) {
[mutableFileURLs addObject:fileURL];
}
}
return mutableFileURLs;
}

Objective c -enumaeratorAtPath: Not Working at root level folders

I am trying to enumerate files and folders at root level
(/Users/Myname/Desktop or /Users/Myname/Documents),[enumarator nextobject] always gives nil value.
How can i solve this issue.
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:#"/Users/Myname/Desktop"];
NSString *content= [enumerator nextObject];//content always nil.
Try this:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDirectoryEnumerator * emuerator = [fileManager enumeratorAtPath:#"/usr/Myname/Desktop"];
NSString *filename; while ((filename = [emuerator
nextObject]))
{
NSLog (#"file! %#", filename);
}
OR
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSFileManager *manager = [[NSFileManager alloc] init];
NSDirectoryEnumerator *emuerator= [manager enumeratorAtPath: #"/usr/Myname/Desktop"];
for (NSString *filename in emuerator) {
// Do something with file
}
[manager release];

Can't Access Entity In Core Data From Another View Controller

I am a novice Objective-C programmer and core data user. This is my first time using core data. What I am trying to do is put entities in a core data database and then retrieve and edit them in another View Controller.
Here is the code in my ViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
NSString *documentName = #"myDocument";
NSURL *url = [documentsDirectory URLByAppendingPathComponent:documentName];
UIManagedDocument *document = [[UIManagedDocument alloc]initWithFileURL:url];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[url path] ];
if(fileExists)
{
[document openWithCompletionHandler:^(BOOL success){
if(!success) NSLog(#"Error (this isn't printed)");
}];
}
else
{
[document saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
if(!success) NSLog(#"Error (this isn't printed)");
}];
NSManagedObjectContext *context = document.managedObjectContext;
QuestionResponse *question1 = [NSEntityDescription insertNewObjectForEntityForName: #"QuestionResponse" inManagedObjectContext: context];
QuestionResponse *question2 = [NSEntityDescription insertNewObjectForEntityForName: #"QuestionResponse" inManagedObjectContext: context];
QuestionResponse *question3 = [NSEntityDescription insertNewObjectForEntityForName: #"QuestionResponse" inManagedObjectContext: context];
QuestionResponse *question4 = [NSEntityDescription insertNewObjectForEntityForName: #"QuestionResponse" inManagedObjectContext: context];
question1.question = #"What is your favorite food?";
question2.question = #"Who is your favorite fictional character?";
question3.question = #"Name someone who loves you:";
question4.question = #"What is your favorite place (real or fictional)?";
question1.order = [NSNumber numberWithInt:1];
question2.order = [NSNumber numberWithInt:2];
question3.order = [NSNumber numberWithInt:3];
question4.order = [NSNumber numberWithInt:4];
question1.group = [NSNumber numberWithInt:1];
question2.group = [NSNumber numberWithInt:1];
question3.group = [NSNumber numberWithInt:2];
question3.group = [NSNumber numberWithInt:2];
question1.display = [NSNumber numberWithBool:NO];
question2.display = [NSNumber numberWithBool:NO];
question3.display = [NSNumber numberWithBool:NO];
question4.display = [NSNumber numberWithBool:NO];
NSFetchRequest* request2 = [NSFetchRequest fetchRequestWithEntityName:# "QuestionResponse"];
NSError* error2 = nil;
NSArray* results = [context executeFetchRequest:request2 error:&error2];
if (!results || !results.count){
NSLog(#"No elements (this isn't printed)");
}
if(results.count == 4)
{
NSLog(#"We have four entities (this is what is printed)");
}
}
}
In my AnswerViewController.m this is the code:
- (IBAction)answerQuestion1:(id)sender {
//File creation begins here (same as in View Controller)
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
NSString *documentName = #"myDocument";
NSURL *url = [documentsDirectory URLByAppendingPathComponent:documentName];
UIManagedDocument *document = [[UIManagedDocument alloc]initWithFileURL:url];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[url path] ];
if(fileExists)
{
[document openWithCompletionHandler:^(BOOL success){
if(!success) NSLog(#"Error");
}];
NSLog(#"File Exists (this is printed)");
}
else
{
[document saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
if(!success)NSLog(#"There has been a problem (this isn't printed)");
}];
}
NSManagedObjectContext *context = document.managedObjectContext;
//File Creation ends here
NSError *error = nil;
NSFetchRequest* request2 = [NSFetchRequest fetchRequestWithEntityName:# "QuestionResponse"];
NSError* error2 = nil;
NSArray* results = [context executeFetchRequest:request2 error:&error2];
if (!results || !results.count){
NSLog(#"No entities (this is what is printed");
}
else
{
NSLog(#"Some entities (this isn't printed)");
}
}
In my ViewController.m the core data has four elements but when I try to access them in AnswereViewController.m there is nothing in core data. Why is this happening and how can I access my elements from AnswereViewController.m?
In order to use CoreData successfully, you have to first understand the flow of it. In essence, CoreData can be broken down into two main parts:
the database (so the .sqlite file itself)
the persistent store coordinator (henceforth known as psc)
What you have done so far in ViewController.m is that you have told the compiler to insert your 4 objects into your managedObjectContext. This gets done on a psc level. The psc acts like a scratchpad for all of your database changes. Until you actually tell it to save it, it will only live in the psc and not in your .sqlite file. What you need to do then is to call:
[context save:&error2]
This will tell the compiler to push your current status of the psc into the database so it persists.
I hope this helps you.

Saving images to a directory

Hi I want to save an image to a directory, I pass the NSData and do what I think will save the file in a directory I create but the problem is that it doesn't save. This is what I have so far. Why doesn't the initWithContentsOfURL:encoding:error: work, it returns null but the other method I used works? The main problem is WRITETOURL which returns a 0 which i think means that the information wasn't stored properly, any tips?
NSFileManager *fm = [[NSFileManager alloc] init];
NSArray * directoryPaths = [fm URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask];
NSLog(#"%#", directoryPaths);
NSURL* dirPath = nil;
dirPath = [[directoryPaths objectAtIndex:0] URLByAppendingPathComponent:[NSString stringWithFormat:#"photos.jpeg"]];
NSError* theError = nil;
[fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theError];
UIImage* photoToStore = [UIImage imageWithData:photoToSave];
NSString *pathContainingPhoto = [[NSString alloc] initWithFormat:#"%#.jpeg", UIImageJPEGRepresentation(photoToStore, 1.0)];
NSError *error = nil;
BOOL OK = [pathContainingPhoto writeToURL:dirPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(#"OK = %d", OK); //Returns 0
NSLog(#"%#", dirPath);
//WHY DOESNT THIS VERSION WORK?
// NSString *pathToFile = [[NSString alloc] initWithContentsOfURL:dirPath encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", pathToFile);
NSString* pathToFile = [NSString stringWithContentsOfURL:dirPath encoding:nil error:nil];
NSArray *dirContents = [fm contentsOfDirectoryAtPath:pathToFile error:nil];
NSLog(#"%#", dirContents);
Do like this and int count in .h file and set its intial value count = 0; in viewDidLoad:
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:#"Image_%d.png",count];
error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath]) // removing item it already exuts
{
[[NSFileManager defaultManager] removeItemAtPath:stringPath error:&error];
}
if(photoToSave) // nsdata of image that u have
{
[photoToSave writeToFile:stringPath atomically:YES];
}
count++; // maintaining count of images

Delete empty folders in iOS?

I have plenty of empty temporary folders in app's Document folder.
How to delete them all?
I tried:
NSArray *folders = [[NSFileManager defaultManager]contentsOfDirectoryAtURL:[self applicationDocumentsDirectory] includingPropertiesForKeys:[NSArray arrayWithObject:#"NSURLIsDirectoryKey"] options:0 error:nil];
if (folders) {
for (NSURL *url in folders) {
[[NSFileManager defaultManager]removeItemAtURL:url error:nil];
}
}
but it deletes all, not only folders
This snippet of code deletes only directiories that are empty.
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *files = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil];
for (NSString *file in files) {
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:file];
NSError *error;
if ([[fileManager contentsOfDirectoryAtPath:fullPath error:&error] count]==0) {
// check if number of files == 0 ==> empty directory
if (!error) {
// check if error set (fullPath is not a directory and we should leave it alone)
[fileManager removeItemAtPath:fullPath error:nil];
}
}
}
If you simply want to delete all directories (both empty and not empty) the snippet can be simplified into this:
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *files = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil];
for (NSString *file in files) {
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:file];
if ([fileManager contentsOfDirectoryAtPath:fullPath error:nil])
[fileManager removeItemAtPath:fullPath error:nil];
}