I am working on project in which I require Custom Image library where
images comes from only specific directory.
so, I am creating one Directory in Document Directory and copy list
of file from Bundle path Directory named "ImageFolder" as shown in
Screenshot.
I tried different code but always I get the Array nil.I know that there is no folder at the path which i get but how to do please tell me.
-What I want >
Create Directory "xyz" in Documents Directory.
copy all files from "ImageFolder" into "xyz".
//================================================================
//================================================================
The screenshot you show of ImageFolder is a group in the Xcode project, that doesn't mean that anything related to that group will be copied into the app. If the images in that app are in your copy bundle resources build phase then they will be copied directly into the app bundle (not a sub folder).
You need to add a new copy files build phase, set the folder name, and move the images into that folder.
Once you have done that, consider why you want to copy the images. Can the user do some editing? If not then copying the images is a waste of space. If the user can 'delete' some of the images then think about storing a 'deleted items' plist or user default to just hide / filter the list of images.
This code works
-(void) copyDirectory:(NSString *)directory {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:directory];
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:directory];
if (![fileManager fileExistsAtPath:documentDBFolderPath]) {
//Create Directory!
[fileManager createDirectoryAtPath:documentDBFolderPath withIntermediateDirectories:NO attributes:nil error:&error];
NSArray *fileList = [fileManager contentsOfDirectoryAtPath:resourceDBFolderPath error:&error];
for (NSString *s in fileList) {
NSString *newFilePath = [documentDBFolderPath stringByAppendingPathComponent:s];
NSString *oldFilePath = [resourceDBFolderPath stringByAppendingPathComponent:s];
if (![fileManager fileExistsAtPath:newFilePath]) {
//File does not exist, copy it
[fileManager copyItemAtPath:oldFilePath toPath:newFilePath error:&error];
} else {
[fileManager removeItemAtPath:newFilePath error:&error];
[fileManager copyItemAtPath:oldFilePath toPath:newFilePath error:&error];
}
}
[self info:#"Copy finish!"];
}
}
In directory add the name of your folder to copy
Edit:
Your folder must be added by reference. Drag your folder into your project in xCode and select "Create folder references for any added folders"
What you have currently is a group (yellow folder icon) (physically they are not in a subfolder) - What you need to do is to create a folder outside Xcode, put in the images that you need then drag it into your project - You should have a blue folder icon and your command should work.
One other thing, just reference it, that way you do not have to keep on introducing your images to Xcode every time it will just pick it up she you compile and put it into the bundle.
Related
I am saving video/image in document directory.Now once the image is saved in document directory I want to save its reference in my local database.So I am thinking I can save URL of the image in the local database.
So is it constant throughout my app?
It's not constant, i have observed every time you launch the app it'll be different, but your data is moved to this new path. You can save your file name in your database, and dynamically append this file name to NSDocument directory.
- (NSString *)documentsFilePath:(NSString *)fileName {
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths firstObject];
NSString *filePath = [docsDir stringByAppendingPathComponent:fileName];
return filePath;
}
- (void)storeFile:(NSString *)fileName {
NSString *filePath = [self documentsFilePath:fileName];
// create if needed
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
// Write your data to file system here...
}
}
- (void)deleteFile:(NSString *)fileName {
NSString *filePath = [self documentsFilePath:fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSError *deleteErr = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&deleteErr];
if (deleteErr) {
NSLog(#"Can't delete %#: %#", filePath, deleteErr);
}
}
}
Please handle nil checks and store only filename in DB
No, it's not constant. Whenever your app reinstall or updated on device the document directory will change, because when app installed on device os made an directory for app with some random id and each install this random it get changed by OS.
So, you need to make it dynamic own your own, like store the file name only and append the document directory path while using it.
I would suggest only saving the filename or subdirectory/filename (if you have a subdirectory) in the database and then only attaching that to the NSDocumentDirectory.
This will ensure that you always know where the file is...
NSDocumentDirectory is however consistent accross updates, so the files should remain in the document directory even if you update...
I am developing an app with openCV and Tesseract framework.
It was working well with "NO 64 bit support" but apple requires 64-bit support in every build now onwards.
So i have updated the tesseract framework to
pod 'TesseractOCRiOS', '3.4.0'
in my project.
Now project runs well with all devices.
But when i scan any image, i always get below errors:
Error opening data file /tessdata/eng.traineddata Please make sure the
TESSDATA_PREFIX environment variable is set to the parent directory of
your "tessdata" directory. Failed loading language 'eng' Tesseract
couldn't load any languages!
I have gone through each link on google with no success.
I can make sure that i have "tessdata" folder added as folder reference in my project.
Anyways, i got the solution.
Just update the pod to latest version so your pod file should look like
pod 'TesseractOCRiOS', '4.0.0'
It automaticaly manages "tessdata" if not found in document directory. You just have to make sure it exists in your application bundle.
Then you can initialize it like
_tesseract = new tesseract::TessBaseAPI();
_tesseract->Init([[self pathToLangugeFIle] cStringUsingEncoding:NSUTF8StringEncoding], "eng");
The function should be like
- (NSString*) pathToLangugeFIle{
// Set up the tessdata path. This is included in the application bundle
// but is copied to the Documents directory on the first run.
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = ([documentPaths count] > 0) ? [documentPaths objectAtIndex:0] : nil;
NSString *dataPath = [documentPath stringByAppendingPathComponent:#"tessdata"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:dataPath]) {
// get the path to the app bundle (with the tessdata dir)
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *tessdataPath = [bundlePath stringByAppendingPathComponent:#"tessdata"];
if (tessdataPath) {
[fileManager copyItemAtPath:tessdataPath toPath:dataPath error:NULL];
}
}
setenv("TESSDATA_PREFIX", [[documentPath stringByAppendingString:#"/"] UTF8String], 1);
return dataPath;
}
I have a bunch of images stored in an images directory within my Supported Files directory in Xcode. I want to be able to show one of those images. What is the best way to obtain a path to that image? Do I have to copy them to the Documents directory first? If so, how can I do that?
EDIT: I've tried the following to copy the image from Supporting Files to the Documents folder in the app. It successfully copies, but I can't get the image to show:
-(void)findImage:(NSString *)imageName
{
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appImagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.jpg",imageName]];
success = [fileManager fileExistsAtPath:appImagePath];
if (success)
{
return;
}
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultImagePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.jpg",imageName]];
success = [fileManager copyItemAtPath:defaultImagePath toPath:appImagePath error:&error];
if (!success)
{
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
self.imageDisplay.image = [UIImage imageNamed:appImagePath];
return;
}
This should do the trick:
[UIImage imageNamed:#"someImageName"];
EDIT:
Some additional information:
-imageNamed: will look through the entire main bundle of the application for an imagefile (preferrably an png) with the filename of "someImageName". You need not worry about its location or its extension, since it will be searched for in the mainbundle. Files that you import through the import-file-dialogue in xcode will be added to he main bundle.
This means:
If i have imported a file called myImage.png, calling [UIImage imageNamed:#"myImage"];from anywhere in my code will get me a UIImage-Object containing that image. Its amazingly simple, and maybe that startled you a bit ;)
Look it up in the docs if you like:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIImage_Class/Reference/Reference.html
I'm trying to copy a downloaded file to a specific folder in the app's documents directory but can't seem to get it working. The code I'm using is:
NSString *itemPathString = #"http://pathToFolder/folder/myFile.doc";
NSURL *myUrl = [NSURL URLWithString:itemPathString];
NSArray *paths = [fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *folderPath = [[paths objectAtIndex:0] URLByAppendingPathComponent:#"folder"];
NSURL *itemURL = [documentsPath URLByAppendingPathComponent:#"myFile.doc"];
// copy to documents directory asynchronously
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSFileManager *theFM = [[NSFileManager alloc] init];
NSError *error;
[theFM copyItemAtURL:myUrl toURL:itemURL error:&error];
}
});
I can retrieve the file OK but can't copy it. Can anyone tell me if there's anything wrong with the above code?
If downloading a file from a server, if it's a reasonably small file (e.g. measured in kb, not mb), you can use dataWithContentsOfURL. You can use that method to load the file into memory, and then use the NSData instance method writeToFile to save the file.
But, if it's a larger file, you will want to use NSURLConnection, which doesn't try to hold the whole file in memory, but rather writes it to the file system when appropriate. The trick here, though, is if you want to download multiple files, you either have to download them sequentially, or encapsulate the NSURLConnection and the NSOutputStream such that you can have separate copies of those for each simultaneous download.
I have uploaded a project, Download Manager that demonstrates what a NSURLConnection implementation might look like, but it's non-trivial. You might rather want to contemplate using an established, third-party library, such as ASIHTTPRequest or RestKit.
If you want to access a folder with a given name you should check if it exists and if not create it. That could quite easy be done like this:
NSString *folder = [documentsPath stringByAppendingPathComponent:folderName];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
if (![fileManager fileExistsAtPath:folder]) {
[fileManager createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:nil error:&error];
}
if (error != nil) {
NSLog(#"Some error: %#", error);
return;
}
EDIT
If you want to check if the folder was created properly on your device got to Organizer -> Devices -> [YourDevelopingDeviceWhereTheAppWasInstalled] -> Applications -> [YourApplication]
In the lower section you should at least see some folders like Documents. And if successful your created folders as well.
You need to create any intermediate directories prior to copying files. Check in the Simulator folder to see wether the "folder" directory is created in the applications Documents-folder.
Path to simulator is /Users/$username/Library/Application Support/iPhone Simulator/
I am using the symbolic link with iPhoneApp.
NSString* js_path = [[NSBundle mainBundle] pathForResource:#"js" ofType:nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if (js_path != nil) {
NSFileManager *fm = [NSFileManager defaultManager];
NSString* move_js_path = [NSString stringWithFormat:#"%#/js", [paths objectAtIndex:0]];
NSError *error;
if ([fm createSymbolicLinkAtPath:move_js_path withDestinationPath:js_path error:&error]) {
} else {}
}
I updated the application program. It becomes impossible to read the file afterwards.
However, the file was able to be read by reinstalling it after the application program had been deleted once.
Is there a problem in this code?
If anyones wondering about this, the reason is the application moves directory every time it's updated, the solution might be to use relative paths bundles are located at /var/mobile/Applications/[unique id that changes every update]/app.app whereas the documents directory is located at /var/mobile/Applications/[unique id that changes every update]/Documents so a symlink from Documents to the bundle will always work if it uses something like ../[bundlepath lastPathComponent]/Documents
ofc it's a good idea to build the relativeness from the directories you get at runtime rather than hard coding it, incase these relative paths change in the future.