I have an app written in Swift that is similar to a soundboard. Currently I just have a bunch of mp3s in the apps main bundle. Is it possible to remotely add more mp3s into the apps main bundle and then change a variable in the code to account for the new mp3s? I want it so that I can dynamically add new mp3s without going through the whole app review process. Ideally a user would be able to open the app the next day and find that 15 new mp3s have been added without having to download an update. Is this a possibility?
You can’t write to the main bundle on iOS. Its contents are
cryptographically signed as a part of the App Store submission
process; modifying its contents would prevent the application from
running.
Reference from THIS answer.
And you can get more information from this post: File write with [NSBundle mainBundle] fails.
File System Programming Guide:
< Application_Home>/AppName.app
This is the bundle directory containing the app itself. Do not write
anything to this directory. To prevent tampering, the bundle directory
is signed at installation time. Writing to this directory changes the
signature and prevents your app from launching again.
< Application_Home>/Documents/
Use this directory to store critical user documents and app data
files. Critical data is any data that cannot be recreated by your app,
such as user-generated content. The contents of this directory can be
made available to the user through file sharing. The contents of this
directory are backed up by iTunes.
< Application_Home>/Library/
This directory is the top-level directory for files that are not user
data files. You typically put files in one of several standard
subdirectories but you can also create custom subdirectories for files
you want backed up but not exposed to the user. You should not use
this directory for user data files. The contents of this directory
(with the exception of the Caches subdirectory) are backed up by
iTunes. For additional information about the Library directory, see
“The Library Directory Stores App-Specific Files.”
You can read THIS if you want to write a file into document directory.
Hope this will help.
Related
I have a data file that I need to include with my app when I distribute it. When loading any files in the app, I prefix the file name with:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
This works great for anything I create within the app (and for reading back), like files I download in response to a user action. But I can't for the life of me figure out how to place files there when I build my app in Visual Studio.
I've tried making a "Documents" subdirectory in the special "Resources" folder, but that didn't work (I tried setting the "Build Action" to both BundleResource and Content). When I look at the folder for my app (from using the simulator) I can see that in the "Documents" folder there's all the files I downloaded, but I can't find my data file that I'm trying to bundle ahead of time. I even searched my entire hard drive on the Mac and still couldn't find said data file.
The data file isn't an image, if it matters. Just raw binary data. How do I set it up so that this file goes into the proper documents directory at compile time, so that I can read it using the SpecialFolder.MyDocuments prefix? Thanks.
You can't. You can include files in your app bundle, and then at startup copy them from the bundle into a user folder. But this won't happen automatically.
I am implementing a resumable upload protocol that uploads in the background on iOS, which means I have to use an NSURLSessionUploadTask with a file. Since it's a resumable upload protocol, the file needs to be truncated based on the data that has already been received by the server, so I need to save a new temporary file to disk that has only the bytes to be uploaded within it.
If I can create that temporary upload file in the tmp/ or /Library/Caches/, can I trust that it will be kept as long as the NSURLSession is running?
EDIT: When an upload fails, the server will be saving the bytes it has already received and communicating that to the client. The client then should only send part of the file, which is why I need to create a smaller temporary file that must not be deleted mid-upload.
Huh? You provide the entire file, and the system takes care of managing the partial upload/download, and notifies you once the transfer is complete. In the case of a download, t hands you a temporary file once the download is complete and you have to save it to a permanent location.
You should not be mucking around with partial files at all.
EDIT:
You don't have access to tmp or /Library/Caches/, except through the sandbox. You can get access to the caches directory with the call
[NSSearchPathForDirectoriesInDomains(
NSCachesDirectory,
NSUserDomainMask, YES) lastObject];
It's my understanding that the caches directory only gets purged on restart, or if the device gets critically low on space, but I seem to remember that the docs are vague on when, exactly, the caches directory gets cleared.
You would probably be better off saving your file to the documents directory, then deleting it once you're done with it.
The answer to your question is no. NSURLSessionUploadTask's description appears to support keeping the source file around but it's misleading:
"In iOS, when you create an upload task for a file in a background session, the system copies that file to a temporary location and streams data from there"
But it says nothing about whether it will keep the original source file in the tmp directory. Specifically for your case where your server supports uploading partial files and you need to restart them after failures. Or in the more common situation where you need to manually restart an entire failed upload, for example from a retry-able server error, or if user killed your app and then restarted it (iOS doesn't continue uploads for user killed apps).
In these cases you can't count on the file still being around if you create it in the apps tmp directory. The file system programming guide tells us this.
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
"Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when they are no longer needed; however, the system may purge this directory when your app is not running. The contents of this directory are not backed up by iTunes or iCloud."
So any tmp directory files can be deleted by iOS when your app stops running, and I can confirm I've seen this in production releases of our app. If you think you may need the source file for the upload again, you must store it in your own app directory, and manage deleting it yourself when done with it. Sorry, extra work, but I don't know of any way around it.
I recently had my application rejected, by Apple for:
"Your app has the UIFileSharingEnabled key set to true in the Info.plist, but files and folders not intended for file-sharing are contained within its Documents folder..."
I am storing my application data in the documents directory, images and the core data database. This is a very simple progress, that allows the user to backup and import data. Below are the major steps:
The user can backup the data, which zips the folder.
The user can then use iTunes file sharing to take out the backup.
The user can import, the zip file which overwrites the data in the documents directory.
Has anyone else experienced similar issues? It seems like I am using this correctly.
You should put the zip file in the Documents folder, not any other files. The fact that you also put your core-data files (and some of the other files the user shouldn't see) in the Documents folder is why it was rejected.
You can store any files that the user shouldn't see in another folder such as the Application Support folder.
Since ios5, the file in the NSDocument would be upload to iCloud automatically, if the file in NSDocument is too large Apple would reject the app.
I want to know what path should I store the downloaded file, and what path to store un-completed file (Would not be deleted when application terminate)?
The Caches directory is suitable for files that can be replaced if they were to disappear. In other words, if the file you download can simply be downloaded again if it were to be deleted, then the Caches directory is a good place.
If the downloaded file isn't replaceable and the downloaded file is something that the user initiates as data for the app, then the Documents directory is actually a good place and shouldn't cause rejection.
I'm a bit confused. I'm including in the bundle a Core Data file that will not be modified by the user. Apple rejected my app after I started copying the file to /Documents (due to the new iCloud requirements), so I now I copy the file over to /Library/myprivatedir/
The question is why do I need to copy over to /Library in the first place. What's wrong with it staying in the Bundle after all?
There's nothing wrong with opening a CoreData store from within the bundle. Just be sure to pass the NSReadOnlyPersistentStoreOption as part of the options to -addPersistentStoreWithType:configuration:URL:options:error:
Skimming the docs for iOS Data Storage Guidelines (apple id required) I found this
... Data that can be downloaded again or regenerated should be stored in the <Application_Home>/Library/Caches directory. Examples of files you should put in the Caches directory include database cache files and downloadable content, such as that used by magazine, newspaper, and map applications.
Because it is easily regenerated they may have taken issue with it.
A couple of points down may be useful if you did have a read/write database scenario
... Use the "do not back up" attribute for specifying files that should remain on device, even in low storage situations. 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. These files will not be purged and will not be included in the user's iCloud or iTunes backup. Because these files do use on-device storage space, your app is responsible for monitoring and purging these files periodically.