Can't download a file in ios - ios

Here is my code to download a book
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *resourceDocPath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle]resourcePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:#"Documents"]];
NSString *filePath= [resourceDocPath stringByAppendingPathComponent:_bookname];//in _bookname i am already getting the value ,say abcd.pdf
NSLog(#"The bookfilepath is %#",filePath);
NSLog(#"the lenght of recieved data is %d", _recievedData.length);//here i get the correct file size also
[_recievedData writeToFile:filePath atomically:YES];
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: filePath] == YES)
{
flag=1;
NSLog (#"File exists");
}
else
{
NSLog (#"File not found"); //always this happens in the log
}
}
No file exists at the filePath. Why?
The funny part is _recievedData.length is returning the correct file size.

Because you cannot write into the app bundle ([[NSBundle mainBundle] resourcePath]).
Write to the documents folder instead.

It appears that this code getting the resource path, stripping off the last path component and then adding Documents. That's not the right way to get to the Documents folder. Instead, use NSSearchPathForDirectoriesInDomains:
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:_bookname];

Related

How to get List of files/Upload/rename/write/read files in ios device programmatically?

I am creating an app in which user will have to upload the files and images like xls, pdf, txt, jpg, png etc. I want to show the user all the files present in his iOS device please help me any one.
First of all you should read NSFileManager concept in Apple Documentation then automatically you should know how to do this::
what you can access is within your app only, nothing more –
Can you please see the following code . i hope it will be helpful to you
(1). #pragma mark
#pragma mark -- list all the files exists in Document Folder in our Sandbox.
- (void)listAllLocalFiles{
// Fetch directory path of document for local application.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// NSFileManager is the manager organize all the files on device.
NSFileManager *manager = [NSFileManager defaultManager];
// This function will return all of the files' Name as an array of NSString.
NSArray *files = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
// Log the Path of document directory.
NSLog(#"Directory: %#", documentsDirectory);
// For each file, log the name of it.
for (NSString *file in files) {
NSLog(#"File at: %#", file);
}
}
(2). #pragma mark
#pragma mark -- Create a File in the Document Folder.
- (void)createFileWithName:(NSString *)fileName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSFileManager *manager = [NSFileManager defaultManager];
// 1st, This funcion could allow you to create a file with initial contents.
// 2nd, You could specify the attributes of values for the owner, group, and permissions.
// Here we use nil, which means we use default values for these attibutes.
// 3rd, it will return YES if NSFileManager create it successfully or it exists already.
if ([manager createFileAtPath:filePath contents:nil attributes:nil]) {
NSLog(#"Created the File Successfully.");
} else {
NSLog(#"Failed to Create the File");
}
}
(3). #pragma mark
#pragma mark -- Delete a File in the Document Folder.
- (void)deleteFileWithName:(NSString *)fileName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Have the absolute path of file named fileName by joining the document path with fileName, separated by path separator.
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSFileManager *manager = [NSFileManager defaultManager];
// Need to check if the to be deleted file exists.
if ([manager fileExistsAtPath:filePath]) {
NSError *error = nil;
// This function also returnsYES if the item was removed successfully or if path was nil.
// Returns NO if an error occurred.
[manager removeItemAtPath:filePath error:&error];
if (error) {
NSLog(#"There is an Error: %#", error);
}
} else {
NSLog(#"File %# doesn't exists", fileName);
}
}
(4). #pragma mark
#pragma mark -- Rename a File in the Document Folder.
- (void)renameFileWithName:(NSString *)srcName toName:(NSString *)dstName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePathSrc = [documentsDirectory stringByAppendingPathComponent:srcName];
NSString *filePathDst = [documentsDirectory stringByAppendingPathComponent:dstName];
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePathSrc]) {
NSError *error = nil;
[manager moveItemAtPath:filePathSrc toPath:filePathDst error:&error];
if (error) {
NSLog(#"There is an Error: %#", error);
}
} else {
NSLog(#"File %# doesn't exists", srcName);
}
}
(5).#pragma mark
#pragma mark -- Read a File in the Document Folder.
/* This function read content from the file named fileName.
*/
- (void)readFileWithName:(NSString *)fileName{
// Fetch directory path of document for local application.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Have the absolute path of file named fileName by joining the document path with fileName, separated by path separator.
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
// NSFileManager is the manager organize all the files on device.
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePath]) {
// Start to Read.
NSError *error = nil;
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSStringEncodingConversionAllowLossy error:&error];
NSLog(#"File Content: %#", content);
if (error) {
NSLog(#"There is an Error: %#", error);
}
} else {
NSLog(#"File %# doesn't exists", fileName);
}
}
(6). #pragma mark
#pragma mark -- Write a File in the Document Folder.
/* This function Write "content" to the file named fileName.
*/
- (void)writeString:(NSString *)content toFile:(NSString *)fileName{
// Fetch directory path of document for local application.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Have the absolute path of file named fileName by joining the document path with fileName, separated by path separator.
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
// NSFileManager is the manager organize all the files on device.
NSFileManager *manager = [NSFileManager defaultManager];
// Check if the file named fileName exists.
if ([manager fileExistsAtPath:filePath]) {
NSError *error = nil;
// Since [writeToFile: atomically: encoding: error:] will overwrite all the existing contents in the file, you could keep the content temperatorily, then append content to it, and assign it back to content.
// To use it, simply uncomment it.
// NSString *tmp = [[NSString alloc] initWithContentsOfFile:fileName usedEncoding:NSStringEncodingConversionAllowLossy error:nil];
// if (tmp) {
// content = [tmp stringByAppendingString:content];
// }
// Write NSString content to the file.
[content writeToFile:filePath atomically:YES encoding:NSStringEncodingConversionAllowLossy error:&error];
// If error happens, log it.
if (error) {
NSLog(#"There is an Error: %#", error);
}
} else {
// If the file doesn't exists, log it.
NSLog(#"File %# doesn't exists", fileName);
}
// This function could also be written without NSFileManager checking on the existence of file,
// since the system will atomatically create it for you if it doesn't exist.
}
What you want to is not possible in iOS. An application you create only has access to files in it's Documents folder.
There is no "all files from the phone" notion, each application manages it's own files. The only way you can interact with other applications is through a public API provided by the application developers.
If you want to get all the files inside your Documents directory you can get the path this way:
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [searchPaths objectAtIndex:0];
You also have access to the user's photo library with which you can interact using ALAssets (up to iOS7) or PHAssets (iOS 8 and up).
Hope this helps.

save image to subfolder of /library/Application Support/bundleID_name/... iOS

The following code works without error or exception - but still, it does not do what it should ! I wanted to save an image into the iOS library/Application Support folder. More precisely, the image should be placed into a /library/Application Support/bundleID_name/subfolder/ (and the subfolder being called "location1").
If I check the functionality with the iOS-Simulator, I can see the creation of the subfolder (i.e. .../library/Application Support/bundleID_name/location1/). Also the function "saveImage" works without exception. But there is no image being saved !!!! (i.e.the image-file is missing and the folder remains empty) !!
What could be the mistake ??
Here is my code with the call of two functions (see code below):
UIImage *in_image = [UIImage imageNamed:#"template009c.jpg"];
NSString *locDirectoryName = #"location1";
NSURL *LocationDirectory = [self appendLocationToApplicationDirectory:locDirectoryName];
[self saveImage:in_image :#"image1" :LocationDirectory];
With the corresponding function-Nr1:
- (NSURL*)appendLocationToApplicationDirectory:(NSString*)locationDirName
{
NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
NSFileManager*fm = [NSFileManager defaultManager];
NSURL* dirPath = nil;
// Find the application support directory in the home directory.
NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory
inDomains:NSUserDomainMask];
if ([appSupportDir count] > 0) {
// Append the bundle ID and the location-Foldername to the URL for the Application Support directory
dirPath = [[[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:appBundleID] URLByAppendingPathComponent:locationDirName];
// If the directory does not exist, this method creates it.
// This method call works in OS X 10.7 and later only.
NSError* theError = nil;
if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theError]) {
// Handle the error.
NSLog(#"%#", theError.localizedDescription);
return nil;
}
else {
// Mark the directory as excluded from iCloud backups
if (![dirPath setResourceValue:#YES
forKey:NSURLIsExcludedFromBackupKey
error:&theError]) {
NSLog(#"Error excluding %# from iCloud backup %#", [dirPath lastPathComponent], theError.localizedDescription);
}
else {
NSLog(#"Location Directory excluded from iClud backups");
}
}
}
return dirPath;
}
And function Nr2:
//saving an image
- (void)saveImage:(UIImage*)image :(NSString*)imageName :(NSURL*)pathName {
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *LocationDirectory = [pathName absoluteString];
NSString *fullPath = [LocationDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", imageName]];
/***** THE FOLLOWING LINE DOES NOT SEEM TO DO WHAT IT IS SUPPOSED TO *******/
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
/**** I also tried without the FileManager, but same problem - no file written... ***/
// [imageData writeToFile:fullPath atomically:NO];
NSLog(#"image saved");
}
By the way, getting the "fullPath" with the XCode-Debugger, I get:
"fullPath NSPathStore2 * #"file:/Users/username/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2BCC3345-9M55F-4580-A1E7-6694E33456777/Library/Application%20Support/bundleID_name/image1.png" 0x09d50950
Doesn't that also seem correct ?? But why is [fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; not performing ???
This:
"fullPath NSPathStore2 * #"file:/Users/username/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2BCC3345-9M55F-4580-A1E7-6694E33456777/Library/Application%20Support/bundleID_name/image1.png" 0x09d50950
is not a valid path, it's a URL path but stored in a string. If you are going to use URL's then use ULRs rather than trying to convert to a string:
[imageData writeToURL:pathName atomically:YES];
(preferably naming the parameter as pathURL) and if you want to use paths then don't use a URL at any stage.
Also, where an API method returns an error or status flag, check it in the code as standard.
I'm pretty sure you can't save an image on a path you specify. You can save images on the gallery or in DocumentDirectory. This should be the code to save an image on the DocumentDirectory:
NSString *imgName=[#"imgname.png"];
[[NSUserDefaults standardUserDefaults]setValue:imgName forKey:#"imageName"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:imgName];
UIImage *image = imageView.image; // imageView is my image from camera
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];

How do i create a file in the default documents directory in an iOS app

I'm writing an app that needs to store some persistence information in file but i'm having trouble debugging the createFileAtPath:contents:attributes: function of NSFileManager, i have reduced the problem to the below piece of code.
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSString * fileName = #"newfile.txt";
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent: fileName];
NSLog(#"full path name: %#", filePath);
// check if file exists
if ([filemgr fileExistsAtPath: filePath] == YES){
NSLog(#"File exists");
}else {
NSLog (#"File not found, file will be created");
if (![filemgr createFileAtPath:filePath contents:nil attributes:nil]){
NSLog(#"Create file returned NO");
}
}
Since the function doesn't take an NSError object i'm having trouble finding out why exactly it is returning false.
From other examples i have seen here Write a file on iOS and here How to programmatically create an empty .m4a file of a certain length under iOS using CoreAudio on device? it should be ok to pass nil to both the contents and attributes parameters. I've tried specifying both parameters and receive the same result.
I'm thinking this may be a permissions issue but i'm unsure if the below code is the correct way to check permissions on a directory.
if ([filemgr isWritableFileAtPath:documentsDirectory] == YES){
NSLog (#"File is readable and writable");
}
// Following Code will create Directory in DocumentsDirectory
NSString *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dirName = [docDir stringByAppendingPathComponent:#"MyDir"];
BOOL isDir
NSFileManager *fm = [NSFileManager defaultManager];
if(![fm fileExistsAtPath:dirName isDirectory:&isDir])
{
if([fm createDirectoryAtPath:dirName withIntermediateDirectories:YES attributes:nil error:nil])
NSLog(#"Directory Created");
else
NSLog(#"Directory Creation Failed");
}
else
NSLog(#"Directory Already Exist");
swift5
guard let docdir = NSSearchPathForDirectoriesInDomains(.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first else {
preconditionFailure()
}
let path = (docdir as NSString).appendingPathComponent(yourfilename + "." + yourfilenameExtension)

IOS: delete a file in a directory

In my app I download a pdf file with an ASiHttpRequest and I have these instructions:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[currentDownload setDownloadDestinationPath:[documentsDirectory stringByAppendingPathComponent:#"file.pdf"]];
it work fine at first time, and I can open this file.pdf, but when I download a second time this pdf, it seems that it not replace the file but do a merge.
before I do this, but it doesn't work where is the problem, or what's the best way to delete this file.pdf from its path?
- (void) removeFile{
NSString *extension = #"pdf";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPDF = [paths objectAtIndex:0];
NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectoryPDF error:NULL];
NSEnumerator *e = [contents objectEnumerator];
NSString *filename;
while ((filename = [e nextObject])) {
if ([[filename pathExtension] isEqualToString:extension]) {
[fileManager removeItemAtPath:[documentsDirectoryPDF stringByAppendingPathComponent:filename] error:NULL];
}
}
}
EDIT
now I use this method
- (void) removeFile{
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0]stringByAppendingString:#"/file.pdf"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(#"Documents directory before: %#", [fileManager contentsOfDirectoryAtPath:[paths objectAtIndex:0] error:&error]);
if([fileManager fileExistsAtPath:path] == YES)
{
NSLog(#"file exist and I delete it");
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:path error:&error];
NSLog(#"error:%#", error);
}
NSLog(#"Documents directory after: %#", [fileManager contentsOfDirectoryAtPath:[paths objectAtIndex:0] error:&error]);
}
this method recognize that in directory there is "file.pdf" in NSLog
NSLog(#"Documents directory before: %#", [fileManager contentsOfDirectoryAtPath:[paths objectAtIndex:0] error:&error]);
but it crash after
"NSLog(#"file exist and I delete it");"
and I have only a "lldb" in consolle.
I use this method to delete pdf files from a local cache, with a few modifications you can adapt it to your necessities
- (void)removePDFFiles
{
NSFileManager *fileMngr = [NSFileManager defaultManager];
NSArray *cacheFiles = [fileMngr contentsOfDirectoryAtPath:[self cacheDirectory]
error:nil];
for (NSString *filename in cacheFiles) {
if ([[[filename pathExtension] lowercaseString] isEqualToString:#"pdf"]) {
[fileMngr removeItemAtPath:[NSString stringWithFormat:#"%#/%#", [self cacheDirectory], filename] error:nil];
}
}
}
Most probably you don't remove the file before downloading a new one and ASIHttpRequest sees that there's already a file with the same name and appends data to it instead of replacing the file. I'm not sure about the PDF format, but that shouldn't normally result in a merged readable file. In any case, first you need to use the error mechanism that the filemanager class offers you. Is bad to pass NULL. Very bad. So, create a NSError object and pass it to the contentsOfDirectoryAtPath and removeItemAtPath methods, then check the error, be sure the operations are done successfully. After that, you may want to check the extension upper case as well, as Unix based systems are case sensitive (although the simulator is not, the device is) and a example.PDF file will not get deleted based on your code.
Try the following:
-(BOOL) removePDF
{
BOOL removeStatus = NO;
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString* fileName = #"file.pdf"; //your file here..
NSString* filePath = [NSString stringWithFormat:#"%#/%#", docsDir, fileName];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath] == YES)
{
removeStatus = [[NSFileManager defaultManager] removeItemAtPath:filePath];
}
return removeStatus;
}

Delete image from app directory in iPhone

I want to delete an image from my iPhone app.
I use the method below, passing the name of the image as an argument.
The problem is that the image isn't deleted.
- (void)removeImage:(NSString*)fileName {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat:#"%#.png", fileName]];
[fileManager removeItemAtPath: fullPath error:NULL];
NSLog(#"image removed: %#", fullPath);
NSString *appFolderPath = [[NSBundle mainBundle] resourcePath];
NSLog(#"Directory Contents:\n%#", [fileManager directoryContentsAtPath: appFolderPath]);
}
The last two lines show the content in my app directory and the image I want to delete is still there. What am I doing wrong?
You are trying to delete a file in the Documents directory. You then read the contents of the bundle resources directory. These are not the same directory.
If you're trying to delete a file in the Documents directory, the you should rad that directory in your NSLog() at the end. If you're trying to delete a file inside your bundle, this is impossible. App bundles are signed and cannot be modified.
your code looks ok, so try adding some 'NSError' object to you code:
- (void)removeImage:(NSString*)fileName {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat:#"%#.png", fileName]];
NSError *error = nil;
if(![fileManager removeItemAtPath: fullPath error:&error]) {
NSLog(#"Delete failed:%#", error);
} else {
NSLog(#"image removed: %#", fullPath);
}
NSString *appFolderPath = [[NSBundle mainBundle] resourcePath];
NSLog(#"Directory Contents:\n%#", [fileManager directoryContentsAtPath: appFolderPath]);
}
In the code above I passed a NSError the error parameter of removeItemAtPath. If the system can't delete the file, this method will return NO and fill the error object with the error raised.
Based on your comment I found out that you are trying to delete the default.png and replace it with another one. Unfortunately, this is impossible. The image default.png is a part of your application bundle, which cannot be modified once it has been created and signed (this is a security measure from Apple, so applications cannot change after they have been reviewed). The only locations where you can create and delete files is inside the sandbox given to your application (the Documents folder).

Resources