Accessing contents of a folder in iOS application bundle - ios

I'm trying to access the contents of a specific folder in my Application Bundle to copy it somewhere else but whenever I go into a folder it seems to be giving me the contents of the entire bundle. Any idea how I can get the contents only in this folder?
My Code
-(void) moveAssets {
NSString * resourcePath = [[NSBundle mainBundle] resourcePath];
NSLog(#"%#", resourcePath);
NSString *newPath = (#"%#/Test/",resourcePath);
NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:newPath error:&error];
for (NSString* currentString in directoryContents){
NSLog(#"%#",currentString);
}
}
Logs
Logs keep giving me all the files and not just the ones in the Test folder

Try:
NSString *newPath = [resourcePath stringByAppendingPathComponent:#"Test"];
(reference).

Related

Could not able to get filePath using Nsfilemanager in Custom FrameWork

I'm working on Apple Watch application, so I have created one custom framework. Currently I'm trying to fetch data from a static JSON file. The JSON file is in my application bundle, but I couldn't parse data from that .json file.
Note: I'm trying to fetch data in custom framework class, my code is here:
NSString *jsonFile = [[NSBundle mainBundle] pathForResource:#"test_json_PCC" ofType:#"json" inDirectory:nil];
NSData *data;
if([[NSFileManager defaultManager] fileExistsAtPath:jsonFile])
{
data = [[NSFileManager defaultManager] contentsAtPath:jsonFile];
}
else
{
NSLog(#"File not exits");
}
I am always getting "File not exits" errors in the console.
try this ....with that u can access the file from your main bundle without using NSFileManager...
NSString *Path = [[NSBundle mainBundle] pathForResource:#"begArray" ofType:#"json"];
contents = [NSMutableString stringWithContentsOfFile:Path
encoding:NSUTF8StringEncoding
error:NULL];//contents is a NSMutableString to store your file data...

Fails to copy writable plist file in document directory in ios8

Am trying to copy a plist file which has a http url written to it from app bundle to documents directory but its getting failed only in ios8 with message "NSInternalInconsistencyException', reason: 'The operation couldn’t be completed. (Cocoa error 4.)'.'" .Its working fine in ios7.Please guide what could be the reason.
//To get the plist file path within app
-(NSString *)ogPath
{
NSString *str = [[NSBundle mainBundle] bundlePath];
str = [str stringByAppendingPathComponent:#"configUrl.plist"];
return str;
}
//To get the plist file path within documents directory
-(NSString *)documentPath
{
NSString *str = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
str = [str stringByAppendingFormat:#"/Documents/configUrl.plist"];
return str;
}
//to copy plist file within app to documents directory
-(void)copytheplistfile
{
NSString *plistpath = [self ogPath];
NSString *docpath = [self documentPath];
NSFileManager *file = [NSFileManager defaultManager];
BOOL fileexist = [file fileExistsAtPath:docpath];
if(!fileexist)
{
NSError *err;
BOOL copyResult=[file copyItemAtPath:plistpath toPath:docpath error:&err];
NSLog(#"error:%#",[err localizedDescription]);
if(!copyResult)
NSAssert1(0, #"Failed to create writable plist file with message '%#'.", [err localizedDescription]);
}
}
In iOS 8 file system layout of app containers has been changed. Applications and their content are no longer stored in one root directory.
Change your document path
-(NSString *)documentPath
{
NSString *str=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
str = [str stringByAppendingFormat:#"/configUrl.plist"];
return str;
}

writing string to txt file in objective c

Pulling my hair out trying to work this out. i want to read and write a list of numbers to a txt file within my project. however [string writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error] doesnt appear to write anything to the file. I can see there is the path string returns a file path so it seems to have found it, but just doesnt appear to write anything to the file.
+(void)WriteProductIdToWishList:(NSNumber*)productId {
for (NSString* s in [self GetProductsFromWishList]) {
if([s isEqualToString:[productId stringValue]]) {
//exists already
return;
}
}
NSString *string = [NSString stringWithFormat:#"%#:",productId]; // your string
NSString *path = [[NSBundle mainBundle] pathForResource:#"WishList" ofType:#"txt"];
NSError *error = nil;
[string writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", error.localizedFailureReason);
// path to your .txt file
// Open output file in append mode:
}
EDIT: path shows as /var/mobile/Applications/CFC1ECEC-2A3D-457D-8BDF-639B79B13429/newAR.app/WishList.txt so does exist. But reading it back with:
NSString *path = [[NSBundle mainBundle] pathForResource:#"WishList" ofType:#"txt"];
returns nothing but an empty string.
You're trying to write to a location that is inside your application bundle, which cannot be modified as the bundle is read-only. You need to find a location (in your application's sandbox) that is writeable, and then you'll get the behavior you expect when you call string:WriteToFile:.
Often an application will read a resource from the bundle the first time it's run, copy said file to a suitable location (try the documents folder or temporary folder), and then proceed to modify the file.
So, for example, something along these lines:
// Path for original file in bundle..
NSString *originalPath = [[NSBundle mainBundle] pathForResource:#"WishList" ofType:#"txt"];
NSURL *originalURL = [NSURL URLWithString:originalPath];
// Destination for file that is writeable
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *documentsURL = [NSURL URLWithString:documentsDirectory];
NSString *fileNameComponent = [[originalPath pathComponents] lastObject];
NSURL *destinationURL = [documentsURL URLByAppendingPathComponent:fileNameComponent];
// Copy file to new location
NSError *anError;
[[NSFileManager defaultManager] copyItemAtURL:originalURL
toURL:destinationURL
error:&anError];
// Now you can write to the file....
NSString *string = [NSString stringWithFormat:#"%#:", yourString];
NSError *writeError = nil;
[string writeToFile:destinationURL atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", writeError.localizedFailureReason);
Moving forward (assuming you want to continue to modify the file over time), you'll need to evaluate if the file already exists in the user's document folder, making sure to only copy the file from the bundle when required (otherwise you'll overwrite your modified file with the original bundle copy every time).
To escape from all the hassle with writing to a file in a specific directory, use the NSUserDefaults class to store/retrieve a key-value pair. That way you'd still have hair when you're 64.

.plist path on iOS device

-(void)login{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"login" ofType:#"plist"];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
[plistDict setObject:#"si" forKey:#"stato"];
[plistDict writeToFile:path atomically: YES];
}
In iOS Simulator the plist has been correctly written, but when I try to write the .plist on my iPhone, it doesn't work. I guess it is because of the wrong .plist path.
Do the iOS devices use different path?
First you have to check if the file exits in your documents directory. If it doesn't exits there then you can copy it to the document directory. You can do it this way
-(void)login{
BOOL doesExist;
NSError *error;
NSString *filePath= [[NSBundle mainBundle] pathForResource:#"login" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * path =[[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:#"login.plist"]];
doesExist= [fileManager fileExistsAtPath:path];
if (doesExist) {
NSMutableDictionary* plistDict=[[NSMutableDictionary alloc] initWithContentsOfFile:path];
}
else
{
doesExist= [fileManager copyItemAtPath:filePath toPath:path error:&error];
NSMutableDictionary* plistDict=[[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
}
[plistDict setObject:#"si" forKey:#"stato"];
[plistDict writeToFile:path atomically: YES];
}
You can't write to the [NSBundle mainBundle] location. In order to write files like a plist, you should save in the documents folder, this way:
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *filePathToSave = [arrayPaths objectAtIndex:0];
If the plist is part of your app, I would recommend you, in the first launch, to already copy it to the documents folder using the same filePathToSave, so you will always look at it there, both to read or to save.
This is a big mistake, as the main bundle only is readable and only composed at compile time in the App Bundle. The App Bundle lives in a separate place, whereas the data you should write to disk should be placed into the Documents, Temporary or Library folder of your sandbox.
To gain more understanding please read the official File System Programming Guide.
Everything you need to know is written there.
You can also write to subfolders and you should choose between the 3 above mentioned main directories in terms of backing up, when syncing with iTunes or iCloud. For instance contents in the tmp Folder won't be backed up.
You can not write to the mainBundle on an iOS device. You will have to save the file to a directory and modify it there.
Just to bring the answers into the modern world - you should really be using the URL based methods for getting directories:
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *URLForDocumentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]

Can't remove files from mainBundle

I am having trouble removing files from my main bundle. When I delete them manually from support files in XCODE 4.2. They still show up when I run my app. I have opened up the app file with "show package contents" and manually deleted them from there and they still show up when I run the app. I have deleted the app from the simulator and from the ~/applications folder in library and the same behavior exists. Am I missing something?
Background: I have a helper app that I can drop files into the "support files" folder and run in order to convert them from KML to custom XML for use in another app via server downloads to the device. I create an array of file names from the main bundle with the code below and pass that to the parser. I have issues because it is including the deleted/removed files from the bundle and I can't figure out why. Any help would be appreciated.
-(NSArray*)findKMLFilesInMainBundle{
NSString *path = [[NSBundle mainBundle]resourcePath];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = [[NSError alloc]init];
NSMutableArray *kmlArray = [[NSMutableArray alloc]initWithCapacity:10];
NSArray *files = [fileManager contentsOfDirectoryAtPath:path error:&error];
unichar buffer[5];
//now seach for the kml files
for (NSString *fileName in files){
NSLog(#"%#",fileName);
int count = [fileName length];
int start = count - 3;
NSRange range = {start,3};
[fileName getCharacters:buffer range:range];
NSString *endString = [NSString stringWithCharacters:buffer length:3];
if ([endString isEqualToString:#"kml"]){
NSString *kmlFileName = [fileName stringByDeletingPathExtension];
NSLog(#"kmlFilename%#",kmlFileName);
[kmlArray addObject:kmlFileName];
}
}
for (NSString *name in kmlArray){
NSLog(#"file = %#",name);
}
return kmlArray;
}
Hold down ⌥ Option and choose Product → Clean Build Folder... from the menu bar. The default shortcut for this action is ⌥⇧⌘K.

Resources