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.
Related
I have an app which displays text data with images and or videos which is displayed in a UITableView. I have a requirement now that the data must be available offline. I am thinking of pruge and store data every time I have a connection i.e new data is being downloaded. How can this be achieved - storing the data in a mysql table or any other solution. Please note that I am using AFNetworking to stream the images in uiimageview. The images and videos should be stored as blob is the local mysql database? Please note that my project is not using coredata.
The best way would probably be to download and store the media files in the caches directory.
Then, when you need to access a file, you can check to see if it exists, and if so, use it, and if not, handle that condition in whatever manner you need.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
if(![fileManager fileExistsAtPath:[cachePath stringByAppendingPathComponent:#"myfile.zip"]]) {
//create it, copy it from app bundle, download it etc.
}
//start using it
The caches directory is not backed up with the rest of your app, so if you have large files you will not impact the user's backup storage sizes this way.
If you absolutely must have the files in the backup, use the Documents directory instead of the caches directory.
You said you were using AFNetworking, which can stream a download to a file just fine, and even has support for turning the task into a background operation so that it can finish after the app has been closed.
I am making a note-taking app but this app won't be a traditional note-taking application. This application will be used by my company's employees and engineer teams in my company.
The notes content will be large because contain some mathematical expressions. Also, files must be sent to dropbox as text and pdf files.
I wonder which is the best method of these for storing large data content:
1- Simply writing notes content to file (like note1.txt) in Documents directory
I am using this function for writing files:
-(IBAction)writeFile:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileNameData=[NSString stringWithFormat:#"%#.txt",fileName.text];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileNameData];
NSString *str = fileContent.text;
[str writeToFile:filePath atomically:TRUE encoding:NSUTF8StringEncoding error:NULL];
}
2- Or storing file contents in database and create a file when user wants to send the note to dropbox and send this created file to dropbox?
I have created note-taking apps before but in this one, files will be large and I am worried about performance.
UPDATE
I did some trials. I tried to write and read the same string using both technique; core data and files.
It takes about 16 seconds to read string from Core Data and about 5 seconds to read from the file with stringWithContentsOfFile method.
I know that is not very accurate results but I guess Core Data is not very proper for me.
If I am wrong, please correct me.
Well this should be done using core data Core Data Usage and for the benefits please read this SO question Why should I use Core Data for my iPhone app?
I made a Notes App myself and used core data and it works fine . Hope this helps.
EDIT :
Or check this link Relating to the Data Storage guidelines. It includes all types of guidelines as given by Apple.
Core data is a pain the in butt to get setup and working. Do you have a incredibly large data set or need to do entity relationship between the files?
If not I would just have a dictionary or array that contains a simple object that has meta data about the file (last access time, title, file location, etc) I would then load this dictionary and use it in a table view for selecting the files.
The files themselves can be loose files on disk in the data directory. To improve the performance of saving just copy the string and then just write it out asynchronously using GCD. When a user selects one file to open again load it using GCD and show a small progress bar. if these files are small it will be close to instant for loading.
CoreData would be quicker than read/write to files. But, you are not worried about performnace when you write to file. You are worried about Performance when you send the files to dropbox How frequent is that? If that is done not so frequently like once a day , then may be text files is a better option than coredata or sqlite.
What is the correct/best way to store files on the iphone?
I would like to save a file in some directory on the iphone. I have read that filing the users home directory isnt good practice.
Where should the files be stored and how can an URL for these files be saved as well? So that after saving a number of files to the users phone, the urls can be stored so that the files can be managed at a later stage.
I would like to store files, keep a handle to the file and store these handles in a data structure as well as retrieve the files later using URLs in the data structure so that the files can be accessed and deleted.
What would be the correct/optimal way to do this?
Files are stored in Documents folder of the App.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
[paths lastObject];
will get you the Document path.
I would then use NSKeyedArchiver and NSKeyedUnarchiver to store the URLS, and also put that into the Documents.
To see what's in the Documents Directory just use NSFileManager contentsOfDirectoryAtPath:error: method, which returns a handy NSArray. Call lastObject and there you go.
Update:
NSURL must be encoded and decoded with NSKeyedArchiver and NSKeyedUnarchiver, as they are not a basic object of plists. Although you could could convert them to strings, which are, then you could use [array writeToFile:file atomically:YES]. The other option is CoreData but that might be a bit much.
It would be best to store all URLs in one file and just overwrite and with changes when urls are being removed and added.
You are not filling the user's Document directory, you are filling the app's document directory. The documents folder is where you but files that the user has generated. In the future you may decide to open up the Document directory to iTunes so the user can add and remove files that way. Things that just relate the app should be stored in the Library folder.
I hope this explains what the hell I was on about a little better. I seemed to got the impression that you wanted to just store URLs as individual files and store the handles. You could get the handles but just knowing the directory you stored everything in. Get an array of the files in that folder and just load them up by using an unarchiver or initWithFileContents: from NSDictionary or NSArray.
i'd like to have the user tap a cell in the tableview and hear audio. the information for the cell is loaded from core data, so i'm assuming i put the path to the audio file in core data as an attribute with type 'string'.
i am completely lost as to where to go from here. how do i call the path? after a lengthy search, i haven't found much on the topic so any help is greatly appreciated.
You should store just the file name in the managed object and then reconstruct the file path each time.
In iOS the name of the app's directory is just a UUID and it is different on every install. Further, the system may change the directories UUID without warning. This is part of the security system.
Suppose you wanted to put the audio files in a directory called AudioFiles in the Library directory. You would do something like this:
NSString *fileName=//... file name from the managed object
NSArray *libraryPaths=NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libPath=[libraryPaths objectAtIndex:0];
NSArray *components=[NSArray arrayWithObjects:libPath,#"AudioFiles",fileName,nil];
NSString *theAudioFilePath=[NSString pathWithComponents:components];
See Low-Level File Management Programming Topics:Standard System Directories
Depending on how you play the audio files, you may need to convert the file path to a file URL.
Your question is quite wide. The best way for you to get started is to work through Apple's avTouch example. It will show you how to load and play audio files.
I display text and images in a UIWebView. Content isn't always the same. I access images within the content using the bundle path. For an inbetween versions update of content, I'd like to allows users the ability to download new content (text & images). This new content will also display in a UIWebView. The problem is I will have to use a disk path rather than my common pattern of using the bundle path. Unless there is a way to repackage the image at runtime into the bundle.
Once the next app store update for the app is availble, all of the previously downloaded images will be in the app bundle. On this update, I'll write overwrite the previous content and use the bundle path for images. Content will be exactly the same minus the image path.
Can anyone give some insight into how this might work or a better approach?
So far as I know you cannot repackage the bundles on the iPhone once your app has been released to the App Store. So go the other way, and put the data from the bundle on the filesystem so you can change it at runtime.
My usual technique for this stuff is:
bundle up the initial data
have a routine that checks for the presence of a versioned file on the iPhone's filesystem at startup
if that routine doesn't find the current version of the file, copy all the data into the iPhone's filesystem
reference the data from the filesystem in my app, rather than using the bundle path
So, essentially your bundle is just a delivery mechanism, a way to preload the filesystem with the stuff you are going to need. Once it's on the filesystem you can change anything you wish.
Agree with Benjamin - you cannot change your bundle contents.
Instead you can (and should) save your downloaded contents to Documents folder of your application sandbox. You can get the path to it this way:
// Look in Documents for an existing plist file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
Moreover contents of this folder persists during updates so it may be not necessary to put downloadable optional contents to the application bundle.