Create temp file for a sandboxed Cocoa application - objective-c

My app is sandboxed (as per the latest App Store guidelines), and I want to create some temporary files.
Am I allowed to do so? If "yes", WHERE am I allowed to do it? Is there any prespecified path? (And a command to access that path?)

You should use the NSTemporaryDirectory() function, which will find and return the appropriate temporary folder for your application (regardless of sandbox status, OS version, and a host of other things). Take a look at this Cocoa With Love post for much more detail about NSTemporaryDirectory() and other temporary directory-related details.

There is a good article about temporary directories on NSHipster:
http://nshipster.com/nstemporarydirectory/
The author suggests this code which is working perfectly with sandboxed apps as well:
NSError *error;
NSString *globallyUniqueString = [[NSProcessInfo processInfo] globallyUniqueString];
NSString *tempDirectoryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:globallyUniqueString];
NSURL *tempDirectoryURL = [NSURL fileURLWithPath:tempDirectoryPath isDirectory:YES];
[[NSFileManager defaultManager] createDirectoryAtURL:tempDirectoryURL withIntermediateDirectories:YES attributes:nil error:&error];

Related

Standard temporary directory in OSX

I'm trying to figure what is the best place where to store temporary files in the OSX version of my application.
The obvious answer /tmp is not good since it is cleaned up at boot and my application may need to continue an interrupted job also after a restart.
I tried also to use the path pointed by the environment variable TMPDIR, that is the same returned by NSTemporaryDirectory(), that changes every boot and is something like:
/var/folders/wx/p4rqqs8d1ws0wlpx9dkwsh_80000gn/T/
.. but also the contents of this path are removed at boot.
There is a standard path where I can place some temporary files, resilient to restarts, or I have to invent my own solution (ie ~/Library/myapplication/temp)?
In Windows I'm using GetTempPath() and it works the way it should.
I've found my answer googling harder that I did before asking here, in this excellent article:
https://www.cocoawithlove.com/2009/07/temporary-files-and-folders-in-cocoa.html
Reading the articles and the various options I found that the Caches directory (NSCachesDirectory) is the correct place where to store my files. Placing them in "Application Support" will cause them to be backed up by time machine.
So here is what I did:
const char *get_temporary_dir()
{
NSString *path = nil;
NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleIdentifier"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
if ([paths count]) {
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:bundleName];
} else {
path = NSTemporaryDirectory();
path = [path stringByAppendingPathComponent:bundleName];
}
return [path UTF8String];
}
... I'm not sure if the fallback to the standard, deletable, directory is needed but it doesn't hurt!
You should use the "application support directory" - this is typically ~/Library/Application Support or for a sandboxed application and equivalent within its container.
To obtain the URL for this directory you use URLForDirectory:inDomain:appropriateForURL:create:error: passing as first argument NSApplicationSupportDirectory.
Within this directory you need to create a directory just for your application, using your app's bundle ID is a common strategy for naming this directory.
This directory is intended to store files needed by your application, but not your user's files.

Can I use my remote cloudant(nosqlDB) path for CDTDatastoreManager directory in IBM Bluemix SDK?

I am migrating my application backend from Parse.com to IBM bluemix.
I do not want the CDTDatastore to take control of my persistent store(Core Data) which already exist.
As per the Blue mix Documentation:
NSError *outError = nil;
NSFileManager *fileManager= [NSFileManager defaultManager];
NSURL *documentsDir = [[fileManager URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsDir URLByAppendingPathComponent:#"cloudant-sync-datastore"];
NSString *path = [storeURL path];
Can I make my "storeURL" to be my remote database URL(https://apikey:apipassword#username.cloudant.com/my_database) i.e Cloudant Database?
I must be in position to create,update,delete,documents in my remote database Directly with out using CDTReplicatorFactory and no offline storage.
Please let me know if further architectural design of my application is required.
This is the pod you should be looking for.
https://cocoapods.org/?q=ObjectiveCloudant
I think no. Please go through their IBM bluemix library. their policy is offline first.
May be create a rest interface with API keys and username given if you want to use core data as persistent store.

ios read content from private network address

I need to read a file that come for example:
\\192.168.0.1\Folder\Readme.txt
how can I read this file from my app into the iPhone
NSString *pathToTextFile;
NSError *readError;
NSString *fileData = [NSString stringWithContentsOfFile:pathToTextFile
encoding:NSUTF8StringEncoding
error:*readError]
NSLog(#"here is your file as string = %#",fileData);
I think in this case you can use a library like ASIHTTP. Link
It should be possible to download the file into a NSString object, and then store this object into a file.
[nsStringObject writeToFile:pathToFile atomically:YES encoding:stringEncoding error:errorHandler];
As you suggest in your question, you need to access your file over SMB protocol (samba or windows share). I don't think iOS supports smb out of the box, however, i stumbled across tango library on github some time ago. The library claims to be a SMB/CIFS implementation for iOS, so i guess you might give it a try.

NSFilemanager and secure delete

Is there any officially supported way of secure-deleting files in Mac OS X 10.5+?
if not, what about if I move all files (using NSFilemanager) to a common folder, and use srm: from a shell script. Would this delete all traces of a file, or would the file still be recoverable because of the move operation?
thanks in advance for any help/suggestions.
AFAIK, move isn't going to copy the bytes, just change the pointers in the file system.
You can use:
NSError *err;
NSFileManager *fileManager = [[NSFileManager alloc] init];
[fileManager removeItemAtPath:path error:&err];
where path is a NSString with the path of the file you want to delete.
you can refer to this book, where it dose secure file wipe in objective-c http://shop.oreilly.com/product/0636920023234.do

NSSearchPathForDirectoriesInDomains returns the wrong directory

I'm using NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) to get the application documents directory in my app, but the array that's returned contains only one object, and it's an unwritable, incorrect directory:
/Users/me/Library/Application Support/iPhone Simulator/Documents
I found this question which indicates that the problem is related to provisioning, but the answer says little more than that. So I guess I'm asking a duplicate question, but the answer to that question is insufficient, so I'm hoping to get an actual answer in this one.
Hmm ... so one reason that the directory returned might be different that what you'd expect for an app could be related to the Xcode target type. This wouldn't happen to be a testing target would it? in which case the correct answer could well be an answer w/o an application GUID in it, since in fact it's not an application. This google group discussion implies that if this is the case, you'd be good with simply creating the directory.
Just for grins, I created the directory /Users/me/Library/Application Support/iPhone Simulator/Documents from the terminal window, and now it appears to run. There are still test errors, but those might be real.
I'd recommend that you change your test app to create the documents directory if it's missing - something like:
if(![[NSFileManager defaultManager] createDirectoryAtPath:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) withIntermediateDirectories:YES attributes:nil error:NULL])
NSLog(#"Error: Create folder failed %#", NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES));
This works for me:
[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
You can try this:
/**
Returns the path to the application's Documents directory.
*/
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
I believe you are only missing the lastObject message.
I'm having the exact same issue, and in my case it's because I'm running the code from an XCTest class.
My guess is that the tests are not run in the application sandbox.
That's because my tests are related to a static library project, included in the main project.
As soon as I run the exact same code from a run of my app, the paths are returned correctly.
Hope this helps.