Do you need to delete imported files from Documents/Inbox? - iphone

I've got an iOS app that imported files from an email attachment.
I've noticed that once i'm finished with it it places the imported file into Documents/Inbox.
Should my app be deleting these files or does the OS eventually get around to clearing them out?
if so, how? i've tried:
[[NSFileManager defaultManager] removeItemAtPath:[self.url path] error:nil];
However it doesn't seem to reference the file in the inbox, even though self.url is the correct path to my import file.

System does not clear imported files, so you should clear them manually when it is necessary, but not to delete the Documents directory.
How to clear the NSDocumentsDirectory you can find here
If you want to delete files from the inbox use the same code adding
...
NSString *path = [NSString stringWithFormat:#"%#/Inbox", documentsDirectory ];
NSArray *directoryContents = [fileMgr contentsOfDirectoryAtPath:error:&error];
...
Read the reference
From apple doc:
Use this directory to access files that your app was asked to open by
outside entities. Specifically, the Mail program places email
attachments associated with your app in this directory; document
interaction controllers may also place files in it.
Your app can read and delete files in this directory but cannot create new files or write to existing files. If the user tries to edit
a file in this directory, your app must silently move it out of the
directory before making any changes.
The contents of this directory are backed up by iTunes.

Related

Loading file from Dropbox

I have been following the dropbox tutorial for the iOS platform. And i came across this line of code to load a file.
[[self restClient] loadFile:dropboxPath intoPath:localPath]
below this line, it has a little description box describing the code above, which states:
Here, srcPath is the path in the user's Dropbox (you probably got this from a metadata object), and destPath is the location on the local device you want the file to be put after it has been downloaded. To find out when the file download either succeeds or fails implement the following DBRestClientDelegate methods:
1) First off, there is no srcPath nor is there a destPath. So the either the code or the description of the code is outdated/incorrect.
2) Secondly, what is dropboxPath? I am assuming it is the file i want to load from dropbox. If so, how do i specify which file i want?
3) If i am loading a .sqlite file from dropbox, where exactly do i want to load that file into?
Any help would be very appreciated!
1) DropboxPath is the online path where your file is stored in respective Dropbox Account.
2) The source path will be DropboxPath and the destination path will be the path on ur mobile i.e. Document Directory. All the files should be downloaded to either document directory or inside other directory of document directory.
3) Your .sqlite file should be loaded in document directory only. But the project code should use this file using its NSPath.
Have a happy Coding.!! Enjoy.!!
The dropboxPath will indicate where within your application's Dropbox directory the file is. For instance, if your app is called APP01, then the users's Dropbox login will have an APP01 directory. To get a file from that you would specify it as #"/theFile.txt" and the Dropbox API should get APP01/theFile.txt from the user's account. Dropbox will sandbox your access to the user account when you create your development IDs to connect to them.
The localPath should be in your app's sandbox, which you can get using something like
+ (NSString*) GetDocumentDirectory
{
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return ((paths != nil) && ([paths count] > 0)) ? [paths objectAtIndex:0] : nil;
}
You can append your local filename to what's returned from GetDocumentDirectory.

Can I save the downloaded files to NSCacheDictionary in iphone?

I am downloading some mp3 files through my application using NSURLConnection. Actually where can I save the downloaded file. Someone says that saving in to NSDocumentDirectory will lead to app rejection.
Can I save the file to NSCacheDictionary and retrieve this from itunes?
I used this bit of code to save files to NSCacheDictionary
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(
NSCachesDirectory, NSUserDomainMask, YES)
objectAtIndex: 0];
NSString *documentsDirectoryPath = [cachesPath stringByAppendingPathComponent:#"music.mp3"];
[receivedData writeToFile:documentsDirectoryPath atomically:YES];
Can I use like this?
If you save the files to NSCacheDictionary you will not be able to retrieve them from itunes.
Edit:
You can store the mp3 files to NSDocumentDirectory and set "do not backup" flag
for setting the flag you can check the Technical Q&A QA1719.
For additional information you can check the docs.
specifically:
Use this attribute with data that can be recreated but needs to
persist even in low storage situations for proper functioning of your
app or because customers expect it to be available during offline use.
This attribute works on marked files regardless of what directory they
are in, including the Documents directory.

pathForResource of file created within app

I've implemented a bit of functionality that uploads a file created within the app to an FTP location, however the 'pathForResource' returns an error where it cannot find the filepath for the resource.
This is the code i'm using:
SCRFTPRequest *ftpRequest = [[SCRFTPRequest alloc] initWithURL:[NSURL URLWithString:#"ftp://79.170.44.42"]
toUploadFile:[[NSBundle mainBundle] pathForResource:self.htmlFilePath ofType:#"text/html"]];
I've been able to upload files that are packaged with my app, for example, files that are standard 'info.plist etc'. How would I be able to specify the location of a file that is created within the app? Do I need to give a full resource path instead of just referencing the object?
[[NSBundle mainBundle]pathForResource] will only work for files that you added to the XCode Project. You need to look for the file right where you stored it when it was created.

Prevent iCloud sync of data (using .nosync?)

EDIT: So far, the best I've been able to come up with is a pop-up to ask the user to disable iCloud sync, along with moving all the data to the Documents directory so it won't get wiped: In iOS5, is it possible to detect if a user has an app set to back up?
I develop offline mapping application for iPhone/iPad.
We used to store all of the data (many gigs potentially) in the Caches directory.
As of iOS5, the files in the Caches directory can be randomly deleted when the user's hard drive starts getting full.
How can I store local data, without the data being synced to iCloud, iTunes, and without it being randomly deleted? My local data is a large directory tree with many small data files, in thousands of subdirectories.
I moved our directory tree from the library cache directory to a data.nosync directory in the documents directory, because we had read this might be a solution. However, the data in the nosync folder is still being backed up to iCloud.
Here is now I create the directory:
NSString* noSyncDirectory() {
static NSString *directory = nil;
if (!directory) {
directory = [[NSString stringWithFormat:#"%#/%#",
documentsDirectory(), #"data.nosync"] retain];
[Constants createDirectoryIfNeeded:directory];
}
return directory;
}
From: https://developer.apple.com/library/ios/#qa/qa1719/_index.html
You can use the following method to set the "do not back up" extended attribute. Whenever you create a file or folder that should not be backed up, write the data to the file and then call this method, passing in a URL to the file.
#include <sys/xattr.h>
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
}
More information can be found: https://developer.apple.com/icloud/documentation/data-storage/
Further note: While the developer documentation incorrectly implies ("These files will not be purged and will not be included in the user's iCloud or iTunes backup.") that the do-not-backup flag doubles as a do-not-purge flag that is not the case. Simply leaving files in the Caches Directory and flagging them do-not-backup will not prevent their wipe.
Perhaps you can disable backup for your app and store data files somewhere else in the app tree. Any stuff that needs to be backed can be put in a common area outside your app.
You might be able to do it in provisioning: invalid code signing app submission
or settings:
When you want to give the user the option to enable or disable iCloud usage entirely for your app. If your app includes a Settings bundle or inline preferences, you could include a preference to toggle whether your app stores content in iCloud at all. For example, an app whose data consists entirely of privately managed files might do this to give the user the choice of how those files are stored.
or by removing the com.apple.developer.ubiquity-container-identifiers entitlement (which could get auto-added) with Xcode: Configuring Your App's iCloud Entitlements
Otherwise you might need to issue a warning with instructions on disabling through the UI:
http://www.pcmag.com/article2/0,2817,2394702,00.asp#fbid=bpIwPLZ1HeQ
Another workaround is to group the maps into collections that are installed as separate applications. That would be a way to store the data without creating any directories that sync or get backed-up. The data will be stored in the the .app directory and will be protected.
Depending on how the cache space reclamation function works, it might not delete recently accessed or modified files. You could try periodically touching them on a timer. You could also add some old files as decoys and detect when they've been deleted or when space is low to at least issue a warning or re-download the deleted objects...
This issue might not have a workaround yet... You could possibly try calling URLForUbiquityContainerIdentifier explicitly, since it does some initialization on the first invocation. Then create a sub-directory with a .nosync suffix (based on this example).
The first time you call this method for a given container directory, iOS extends your application sandbox to include that container directory. Thus, it is important that you call this method at least once before trying to search for files in iCloud. And if your application accesses multiple container directories, you should call the method once for each directory.
The doc on .nosync:
To ensure that the persistent store itself is not synced by iCloud: when you set a value for the NSPersistentStoreUbiquitousContentNameKey, UIManagedDocument puts the persistent store in a .nosync directory inside the document package. If you make use of additional content (using the writeAdditionalContent:toURL:originalContentsURL:error: method), you must make sure that the document directory is not a package. Typically you give the document directory an extension that is not recognized as a document extension.
You may want to ensure you have the com.apple.developer.ubiquity-container-identifiers entitlement.
The iCloud Containers field identifies the list of container directories that your app can access in the user’s iCloud storage. (This field corresponds to the com.apple.developer.ubiquity-container-identifiers entitlement.)
Maybe uncheck "Enable Entitlements" in the summary pane of the project or edit the profile to remove the *ubiquity settings. (Notes for ios 5 beta 7 reference entitlements.)
There is also the setUbiquitous function:
setUbiquitous:itemAtURL:destinationURL:error:
Sets whether the item at the specified URL should be stored in the cloud.
Parameters
flag
Specify YES to move the item to iCloud or NO to remove it from iCloud (if it is there currently).
http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/setUbiquitous:itemAtURL:destinationURL:error:
There is a newer way to prevent iCloud syncing of data without using extended attributes directly:
- (BOOL)addSkipBackupAttributeToItemAtPath:(NSString *) filePathString
{
NSURL* URL= [NSURL fileURLWithPath: filePathString];
assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
NSError *error = nil;
BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
forKey: NSURLIsExcludedFromBackupKey error: &error];
if(!success){
NSLog(#"Error excluding %# from backup %#", [URL lastPathComponent], error);
}
return success;
}
See Apple's Technical Q&A QA1719 for more details.
Did you try just naming the directory ".nosync" without the data in front? It could be generally . directories are ignored, or perhaps that specifically.
But, it seems like the behavior is just as a user would want it - potentially gigs of space used by an application they may not be using currently, where the space could be reclaimed automatically. I am not sure but you would think the system would be smart about reclaiming files created recently only after there was no choice, so if the user had just stored maps recently they would not be deleted unless there was no other choice.
For the purposes of filing a bug I am going to ask for a way to mark a directory for user prompting before deletion - so that if they are syncing a lot of movies and it would clear out a data set like the maps you are talking about, the user would be asked if they want to remove the data "offline maps" from application "MyCoolMapper" to proceed with the sync.

How can I download an entire directory?

Is it possible in Objective-C to download an entire directory to the documents directory so I would end up with a subfolder in the documents directory with a name of my choosing? Then, is it possible to delete that directory and all its contents without looping through all the files? Many thanks in advance.
The short answer is 'Yes, its possible' given that the directory and files in question are not larger than the available space on the device. If you are talking about some text files or some images then I don't see a problem.
Not so sure about deleting all the contents without first getting a pointer to the files but that shouldn't take long in any case.
Were you looking for specific code examples as well?
There is a similar question, and answer [here].1
You cannot download entire folders over the internet, you would have to list the files and download them one by one.
You can use NSFileManager to create, read and remove files in your apps folder. You can delete a complete folder without having to loop through all the items in the folder.
(BOOL)removeItemAtPath:(NSString )path error:(NSError *)error;
Have a look at the NSFileManager documentation:
NSFileManager documentation
Keep in mind that whenever you go outside the "sandbox" of your app, your app will be rejected by apple. So keep those files within your app's bundle.