Warning in iCloud integration - iphone

I am trying to integrating iCloud.
Everything works fine but when I try to read a file from iCloud I get a warning Like:
Foundation called mkdir("/var/mobile/Library/Mobile Documents/.ubd/peer-E8A60A8F-FB9D-8721-F47C-hdffgdfg-v23/ftr/(A Document Being Saved By XYZ)"), it didn't return 0, and errno was set to 1.
My Code to fetch Data:
for (NSMetadataItem *item in results)
{
NSString *filename = [item valueForAttribute:NSMetadataItemDisplayNameKey];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
MyDocument *doc = [[MyDocument alloc] initWithFileURL:url];
[doc openWithCompletionHandler:^(BOOL success) {
if (success) {
NSData *file = [NSData dataWithContentsOfURL:url];
NSString *docDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"Import/iCloud"];
if (![[NSFileManager defaultManager] fileExistsAtPath:docDir])
[[NSFileManager defaultManager] createDirectoryAtPath:docDir withIntermediateDirectories:YES attributes:nil error:nil];
NSString *pdfFile = [docDir stringByAppendingPathComponent:filename];
if(![[NSFileManager defaultManager] fileExistsAtPath:pdfFile])
[[NSFileManager defaultManager] createFileAtPath:pdfFile contents:file attributes:nil];
NSLog(#"Successfully loaded data from cloud file name %#", filename);
}
else
{
NSLog(#"Failed to load data");
}
}];
}
}

It looks like you have a partially written file in iCloud (based on the A Document Being Saved By XYZ in the error), and your meta data query has returned that to you since it also matches the filename. I ran into a similar situation a few weeks ago and solved it by using the exact path to the file, as in:
NSString *filepath = [containerURL.path stringByAppendingPathComponent:#"MyFileName"];
NSPredicate *pred = [NSPredicate predicateWithFormat: #"%K == %#", NSMetadataItemPathKey, filepath];
[query setPredicate:pred];

Related

How to copy a file from URL to document folder?

I need to copy a text file from an URL and place / overwrite it in my app's document folder and then read it back to a data variable.
I have the following code:
NSData *data;
//get docsDir
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir=[paths objectAtIndex:0];
//get path to text.txt
NSString *filePath=[docsDir stringByAppendingPathComponent:#"text.txt"];
//copy file
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
if([fileManager fileExistsAtPath:filePath]==YES){
[fileManager removeItemAtPath:filePath error:&error];
}
NSString *urlText = #"http://www.abc.com/text.txt";
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSFileManager *fileManager=[NSFileManager defaultManager];
[fileManager copyItemAtPath:urlText toPath:filePath error:NULL];
}
//Load from file
NSString *myString=[[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
//convert string to data
data=[myString dataUsingEncoding:NSUTF8StringEncoding];
It builds and complies in good way but I cannot create the text.txt file in my document folder and then pass anything to my data variable.
I'm a newbie to both IOS and Xcode, any clues will be highly appreciated. Thanks!!
NSFileManager can only handle local paths. It won't do anything useful if you give it a URL.
copyItemAtPath:toPath:error: takes an error parameter. Use it, like this:
NSError *error;
if (![fileManager copyItemAtPath:urlText toPath:filePath error:&error]) {
NSLog(#"Error %#", error);
}
You would then get this error:
Error Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be
completed. (Cocoa error 260.)" UserInfo=0x9a83c00 {NSFilePath=http://www.abc.com/text.txt,
NSUnderlyingError=0x9a83b80 "The operation couldn’t be completed.
No such file or directory"}
It can't read the file at http://www.abc.com/text.txt, because it is not a valid path.
as Sunny Shah stated without explanation you have to fetch the object at the URL first:
NSString *urlText = #"http://www.abc.com/text.txt";
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSURL *url = [NSURL URLWithString:urlText];
NSError *error;
NSData *data = [[NSData alloc] initWithContentsOfURL:url options:0 error:&error];
if (!data) { // check if download has failed
NSLog(#"Error fetching file %#", error);
}
else {
// successful download
if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error]) { // check if writing failed
NSLog(#"Error writing file %#", error);
}
else {
NSLog(#"File saved.");
}
}
}
Always check for errors!
You should get the data from the URL and use WriteToFile
NSData *urlData = [NSData dataWithContentsOfURL: [NSURL URLWithString:urlText]];
[urlData writeToFile:filePath atomically:YES];

Deleting in NSDocumentDirectory

I save in NSDocumentDirectory this way:
NSLog(#"%#", [info objectAtIndex:i]);
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"Images%d.png", i]];
ALAssetRepresentation *rep = [[info objectAtIndex: i] defaultRepresentation];
UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
//----resize the images
image = [self imageByScalingAndCroppingForSize:image toSize:CGSizeMake(256,256*image.size.height/image.size.width)];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:YES];
I know how to delete all the images in NSDocumentDirectory.
But I was wondering on how to delete all of the images with the name of oneSlotImages.
Thanks
Try this ,just copy this code,your images with name oneSlotImages,will be removed from DocumentDirectory ,its just simple :
NSArray *directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] error:NULL];
if([directoryContents count] > 0)
{
for (NSString *path in directoryContents)
{
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:path];
NSRange r =[fullPath rangeOfString:#"oneSlotImages"];
if (r.location != NSNotFound || r.length == [#"oneSlotImages" length])
{
[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];
}
}
}
Have you looked at NSFileManager's methods? Maybe something like this called in a loop for all of your images.
[[NSFileManager defaultManager] removeItemAtPath:imagePath error:NULL];
Use like,
NSArray *dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:strDirectoryPath error:nil];
NSArray *zipFiles = [dirFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self CONTAINS[cd] %#", #"oneSlotImages"]];
The array zipFiles contains the names of all the files we filtered. Thus by appending the filenames with complete path of document directory with in a loop, you can make the full filepath of all the filtered files in the array. Then you can use a loop and call the method of NSFileManager object like below
[fileManager removeItemAtPath: strGeneratedFilePath error: &err];
which removes the itm at path from the directory.
By this way you can filter out the filenames contains oneSlotImages. So you can prefer to delete this ones. Hope this helps you.
As this is an old question now and also above answers shows how to delete by image name.What if I want to delete everything from NSDocumentDirectory at one shot, use the below code.
// Path to the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0)
{
NSError *error = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
// Print out the path to verify we are in the right place
NSString *directory = [paths objectAtIndex:0];
NSLog(#"Directory: %#", directory);
// For each file in the directory, create full path and delete the file
for (NSString *file in [fileManager contentsOfDirectoryAtPath:directory error:&error])
{
NSString *filePath = [directory stringByAppendingPathComponent:file];
NSLog(#"File : %#", filePath);
BOOL fileDeleted = [fileManager removeItemAtPath:filePath error:&error];
if (fileDeleted != YES || error != nil)
{
// Deal with the error...
}
}
}

How can i upload a UIImage to a specific folder in Documents?

I have a image name (lets say #"image.jpg" ) and i would like to save it to a folder i have created in my Documents folder named "coffeeShops". How can i do so ?
NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString *dir = #"coffeeShops";
NSString *destPath = [docs stringByAppendingPathComponent:dir];
// check if the destination directory exists, if not create it
BOOL isDirectory;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:destPath isDirectory:&isDirectory];
if(!exists || !isDirectory) {
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:destPath withIntermediateDirectories:NO attributes:nil error:&error];
if(error != nil) {
// should do error checking here
NSLog(#"%#",[error localizedDescription]);
}
}
NSString *fileName = #"image.jpg";
NSString *path = [destPath stringByAppendingPathComponent:fileName];
[UIImageJPEGRepresentation(image) writeToFile:path atomically:YES];

NSFileManager createDirectoryAtPath EXC_BAD_ACCESS

I have been working at this one for quite some time now but can't seem to resolve it. I have a core data application that also supports document sharing, therefore I'm trying to create a directory in the library folder for the sqlite db.
- (NSURL *)applicationPrivateDocumentsDirectory {
NSString *libraryDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *privateDocs = [libraryDirectory stringByAppendingPathComponent:#"PrivateDocuments"];
NSFileManager *fileMgr = [[NSFileManager alloc] init];
if (![fileMgr fileExistsAtPath:privateDocs]) {
NSLog(#"Does not exist");
NSError *error;
[fileMgr createDirectoryAtPath:privateDocs withIntermediateDirectories:YES attributes:nil error:&error];
NSLog(#"%#", [error description]);
}
NSURL *retURL = [NSURL fileURLWithPath:privateDocs];
return retURL;
}
The debug console outputs "Does not exist" followed by "EXC_BAD_ACCESS"
Any help is greatly appreciated.
Try to add this:
NSError *error = nil;

How to rename directories?

I have created a folder within the Documents folder in my application directory .
I wanted to rename that folder through code,but not able to understand how to do it.
Please help me out.
Have you tried?
NString *newDirectoryName = #"<new folder name>";
NSString *oldPath = #"<path to the old folder>";
NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newDirectoryName];
NSError *error = nil;
[[NSFileManager defaultManager] moveItemAtPath:oldPath toPath:newPath error:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
// handle error
}
NSString *oldDirectoryPath = #"Type your old directory Path";
NSArray *tempArrayForContentsOfDirectory =[[NSFileManager defaultManager] contentsOfDirectoryAtPath:oldDirectoryPath error:nil];
NSString *newDirectoryPath = [[oldDirectoryPath stringByDeletingLastPathComponent]stringByAppendingPathComponent:newDirectoryname];
[[NSFileManager defaultManager] createDirectoryAtPath:newDirectoryPath attributes:nil];
for (int i = 0; i < [tempArrayForContentsOfDirectory count]; i++)
{
NSString *newFilePath = [newDirectoryPath stringByAppendingPathComponent:[tempArrayForContentsOfDirectory objectAtIndex:i]];
NSString *oldFilePath = [oldDirectoryPath stringByAppendingPathComponent:[tempArrayForContentsOfDirectory objectAtIndex:i]];
NSError *error = nil;
[[NSFileManager defaultManager] moveItemAtPath:oldFilePath toPath:newFilePath error:&error];
if (error) {
// handle error
}
}
Using moveItemAtPath should work. Sometimes the directory isn't actually "renamed" but really moved to another place. In which case the target path directory structure needs to be created as well.
Here a code snippet i'm using that works well :
-(BOOL)renameDir:(NSString *)dirPath asDir:(NSString *)newDirPath cleanExisting:(BOOL)clean
{
NSError *error = nil;
NSFileManager *fm = [NSFileManager defaultManager];
if (clean && [fm fileExistsAtPath:newDirPath])
{
[fm removeItemAtPath:newDirPath error:&error];
if (error != nil)
{
NSLog(#"Error while renameDir %# as %# :\n%#",dirPath,newDirPath,error);
return NO;
}
}
//Make sure container directories exist
NSString *newDirContainer = [newDirPath stringByDeletingLastPathComponent];
if (![fm fileExistsAtPath:newDirContainer])
{
[fm createDirectoryAtPath:newDirContainer withIntermediateDirectories:YES attributes:nil error:&error];
}
if (error==nil)
{
[fm moveItemAtPath:dirPath toPath:newDirPath error:&error];
}
if (error!=nil)
{
NSLog(#"error while moveItemAtPath : %#",error);
}
return (error==nil);
}
This always work
NSLog (#"Copying download file from %# to %#", aPath, bPath);
if ([[NSFileManager defaultManager] fileExistsAtPath: bPath]) {
[[NSFileManager defaultManager] removeItemAtPath: bPath
error: &error];
}
if (![[NSFileManager defaultManager] copyItemAtPath: aPath
toPath: bPath
error: &error]){}
if ([[NSFileManager defaultManager] removeItemAtPath: aPath
error: &error]) {}
This is good article for renaming, deleting and create files.
// For error information
NSError *error;
// Create file manager
NSFileManager *fileMgr = [NSFileManager defaultManager];
// Point to Document directory
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
// Rename the file, by moving the file
NSString *filePath2 = [documentsDirectory stringByAppendingPathComponent:#"file2.txt"];
// Attempt the move
if ([fileMgr moveItemAtPath:filePath toPath:filePath2 error:&error] != YES)
NSLog(#"Unable to move file: %#", [error localizedDescription]);
// Show contents of Documents directory
NSLog(#"Documents directory: %#",
[fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]);
http://iosdevelopertips.com/data-file-management/iphone-file-system-creating-renaming-and-deleting-files.html