I am trying to creating a file on my MacOS FS from my IPhone app by means of this code
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
path = [path stringByAppendingPathComponent: #"log.txt"];
NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:path];
if(output == nil) {
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
output = [NSFileHandle fileHandleForWritingAtPath:path];
} else {
[output seekToEndOfFile];
}
I guess the code is OK as it works when executed by the Simulator. However I can't actually see where the file is created when executed from the IPhone. If I print the path I get
/var/mobile/Applications/XXX-XXXX-XXX-XXX/Documents/log.txt
On the simulator, you should find them under: /Users/loginname/Library/Application Support/iPhone Simulator/5.1/Applications/594931F3-B9EF-4B2C-833D-76C2DCC61C6B/Documents. You can go to this location from Finder by choosing the Go menu item, holding down the Option key, then choosing Library.
NOTE: Fill in your own loginname and device ID in the path above.
If you are on the device, you can copy the file over to your Mac using XCode, using the organizer (choose Window | Organizer). Highlight the App (after it has been executed, of course) and there is an option to copy the file over. You don't have direct access to the device file system.
You can also use NSLog() which just sends the debug info to the output window in XCode.
EDIT: Added detail on how to show Library folder.
Related
hello i am beginner in iOS In one of my activity i want to ask .....I displayed pdf using WebView ......on screen and save this Pdf then write this type of code ........
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *pdfFilePath =[documentsDir stringByAppendingPathComponent:#"myPDF.pdf"];// your yourPdfFile file here
NSLog(#"pdf file %#",pdfFilePath);
NSURL *url = [NSURL fileURLWithPath:pdfFilePath];
UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:url];
docController.delegate = self;
[docController presentOpenInMenuFromRect:CGRextZero inView:self.view animated:YES];
When we run this code on simulator (using Xcode) then show path and I got this Pdf file successfully in documents folder .......
but when we run this code in iPhone device then I got this type of path......
/var/mobile/Applications/D33A80AA-C0AD-4211-ADE3-4906372CDA40/Documents/myPDF.pdf
So I don't know where is my Pdf in iPhone device and how to got this Pdf and open .....when i want ......
If your PDF is in the documents folder, you should retrieve the path like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
Don't try to use anything related to the absolute path as you see it in the simulator.
One reason you might not find a file on the device where you do find it on the simulator is that the simulator is case-insensitive but the device is case-sensitive, so be sure your names match exactly.
But! Be aware that the Documents folder is now perhaps not where you want to be storing things - unless you are sure you want them backed up with iCloud. The File System Programming Guide says to use Documents ONLY for documents that cannot be recreated by the app, "critical" documents. A lot of the time it makes sense to store them in the user Library folder instead. In that case the arguments to NSSearchPathForDirectoriesInDomains would be:
(NSLibraryDirectory, NSUserDomainMask, YES)
So my app keeps on crashing and losing all the logs outputed in console. I decided to jailbreak the phone, and use this code to write to a file:
+(void)Log:(NSString *)content
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* docDir = [paths objectAtIndex:0];
NSString * logFile = [docDir stringByAppendingString:#"/log.txt"];
NSData *dataToWrite = [content dataUsingEncoding: NSUTF8StringEncoding];
NSFileHandle* outputFile = [NSFileHandle fileHandleForWritingAtPath:logFile];
[outputFile seekToEndOfFile];
[outputFile writeData:dataToWrite];
[outputFile closeFile];
}
if I put a break point, the value of outputFile looks like this:
/var/mobile/Applications/B8AB0D75-7FBE-4C5B-8D48-2ABCE9C7564D/Documents/log.txt
I installed vim on my phone via cydia, and there is no log.txt in the said directory! (I've SSH'd into my iPhone using iphone tunnel as root SSH. On another attempt, I manually created the log.txt using vim and ran the code again.. still nothing gets appended to the file.. any ideas?
turns out to be a writing permission to the file.. so i just chmod'ed it and it works fine.. D'OH!
my app is creating a CSV file out of a db. I want to browse and open the file to test. How do I access the iphone simulator's storage ?
All data of the Simulator is stored as local files on your Mac.
The path for the user data of iOS apps in the Simulator is:
~/Library/Application Support/iPhone Simulator/[OS version]/Applications/[appGUID]/
You'll want to print out the location of where you store your file when you run the app in the simulator.
You can use this code to get the location of the Library/Cache folder here:
-(NSString *) mediaPathForFileName:(NSString *) fileName
{
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDirectory = [directoryPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", cachesDirectory, fileName];
return filePath;
}
Pass in a random file name like "test.txt":
// somewhere in your viewDidLoad method
[self mediaPathForFileName:#"test.txt"];
This will print out the path to your app Library/Cache folder.
you need get the path of that file by using NSLog and then user Shift+Cmd+G to go to that path.
pritn this path
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
I am building an add-on to my app where the user can search for an item in a list that is pre-populated with data from a .plist file. It is an NSDictionary. If the term, the user searched for, does not exist, the user can tap a + button and add it so it is there the next time.
First of I thought it would be as easy as using the NSUserDefaults, but a few problems arises.
To have the list included I must place it in the bundle, but if it is there I can not add new key/value pairs to it. This I can only do with files situated in the Documents folder.
So I guess I have to bundle the plist, then on first run I'll move it to the documents folder and access it there.
This opens up the problem when I need to update the app, I guess it will overwrite the values the user put in.
Is there a secure, easy-understandable, right way to achieve the functionality I describe?
Thanks for any help given:)
Edit: **** the actual approach, as suggested by TheSquad and TomH *****
+ (NSMutableDictionary*) genericProducts {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"GenericProducts.plist"];
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *bundlePlistPath = [bundlePath stringByAppendingPathComponent:#"GenericProducts.plist"];
if([fileManager fileExistsAtPath:documentPlistPath]){
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
return documentDict;
} else {
NSError *error;
BOOL success = [fileManager copyItemAtPath:bundlePlistPath toPath:documentPlistPath error:&error];
if (success) {
NSMutableDictionary *newlySavedDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
return newlySavedDict;
}
return nil;
}
}
And for adding a new product to the list:
+ (void) addItemToGenericProducts:(NSString*) newProduct {
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"GenericProducts.plist"];
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
[documentDict setObject:newProduct forKey:[MD5Checksum cheksum:newProduct]];
[documentDict writeToFile:documentPlistPath atomically:YES];
}
I had the same thoughts with my sqlite database...
I end up doing exactly that, copy the bundled file into documents in order to be able to modify it.
What I have done is checking at each startup if the file exist, if it does not, copy it.
If you do an update of your App, the documents folder will not be touch, this means the copied file from the previous version will still be present.
The only issue is that if you want your plist to be upgraded you will have to handle that in your application. If you have to do so I suggest you use the NSUserDefault to check if a previous version of the app existed before...
The contents of the documents directory is not altered when an application is updated.
The contents of the documents directory are deleted when the user deletes the app.
When the app is run the first time write a flag to NSUserDefaults. On subsequent runs of the app, check for existence of the flag. (alternatively, you can just check for existence of the plist in he documents directory)
NSString *myfile = [[NSBundle] mainBundle] pathForResource:#"fileName" ofType:#"plist"];
NSMutableArray *mydata= [[NSMutableArray alloc] initWithContentsOfFile:myfile];
/* code to modify mydata */
[mydata writeToFile:myfile atomically:YES]
In case of simulator 'fileName.plist' is modified but in case of iphone device file remains unchanged. There is no exception seen either.
Is the above code expected to work fine on both iphone and simulator ?
Also in the debugger when I hover over 'mydata' I see different values in case of simulator and device. In case of simulator I see for example, '5 objects' but in case of actual device it shows '{(int)[$VAR count]}'. Could this be related to file not being written ?
You can't write to files in a bundle's resource directory. On top of that you wouldn't want to, because any changes would be overwritten when you update your app. The documents directory persists across versions and (I believe) it is backed up via itunes.
Here is a snippet that checks the documents directory for a plist. if the file doesn't exist it copies a plist out of the resources into the documents directory.
BOOL success;
NSFileManager* fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"score.plist"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return success;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"score.plist"]];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
return success;