I am designing an app that will come bundled with some audio files. They'll total about 50MB in size. The app will allow you to download other audio files via in-app purchase. My goal is to have all of these files stored in one location (the Documents Directory).
What I'm doing in my code is this:
On first launch, copy the bundled songs from Main Bundle Resources to the documents directory.
Delete the files from their original location in the Main Bundle Resources.
I have all of this working fine so I know it's possible to do. My question is can anyone point me to Apple documentation/guidelines that says I'm not allowed to do this? Or, is this perfectly acceptable according to Apple's guidelines? I know they don't want you writing to the Resources folder, but haven't been able to find a definitive answer on deleting.
The documentation you're looking for is in the App Distribution Guide [emphasis mine]:"
Code signing your app allows the operating system to identify who signed your app and to verify that your app has not been modified since you signed it. Your app’s executable code is protected by its signature because the signature becomes invalid if any of the executable code in the app bundle changes. Note that resources such as images and nib files are not signed; therefore, a change to these files does not invalidate the signature.
That said, as I noted in my comments on #Wain's answer, this probably isn't a great thing to do if the files are read-only. It adds a big copy step on first launch, and you have to deal with it again on every upgrade.
It is not acceptable and will not work when running on a device (I guess you're testing on the simulator). You can't edit the bundle contents. The bundle is signed and editing it will invalidate the signature.
It would be advisable to deploy the app without the audio files and then to start downloading them as soon as there is a (suitable) internet connection after first launch (if this is an option for you).
Related
I am working on a library with a very verbose logger module that, on iOS, writes xml logs to NSDocumentDirectory in a consistent file tree. I want to come up with a way for the user of this library to easily access these logs.
I know it is simple to programatically retrieve files from this directory, but is it possible to access this directory on an iOS physical device in any way from outside Xcode to retrieve these logs? I feel like I have seen it somewhere before, something in the manner of extracting the .ipa file and going into the package contents, but I could be wrong.
---------------------------------------------------------EDIT------------------------------------------------------------------
This (Browse the files created on a device by the IOS application I'm developing, on workstation?) is how to do it with Xcode on a device, but I have to assume that there is some way we can create that gets the logs off of a device for a user.
is it possible to access this directory on an iOS physical device in any way from outside Xcode to retrieve these logs?
It is possible to expose the Documents directory by enabling iTunes file sharing. When file sharing is enabled through this method, the contents of Documents directory would be visible to the user in iTunes, which can also be exported. The documents would also be visible for export through some third party desktop apps like iExplorer.
Here is the link to Apple documentation. You may also refer this thread to understand how this is done.
If you're using a simulator (apparently your task doesn't seem to need te real device) you are in luck.
You should go to a folder similar to this one:
/Users/[YOUR_USER_NAME]/Library/Developer/CoreSimulator/Devices/[RANDOM_HASH_YOU_SHOULD_DISCOVER]/data/Containers/Data/Application/[RANDOM_HASH_2_YOU_SHOULD_ALSO_DISCOVER]
Once there, with finder, you'll get the "documents" folder of the simulator and the app you're trying to retrieve your logs from.
You might say: I don't know which 2 RANDOM_HASHES should I go to.
Yes, you're right. If you have MANY simulators installed and or being used, it might be tricky to discover which one is the one you're trying to debug.
The same thing with your APP, your app will live in another RANDOM_HASH folder, and you should browse them, one by one, and then discover your documents folder.
Someone needed to solve this "mess" and created a Xcode Alcatraz Extension that leads you to the exact live simulator and APP you're debugging in any given moment, and then you don't need to guess which 2 random_hash paths you need to navigate to.
If Xcode + Alcartaz plugin extension manager is somewhat out of your reach, you might need to google it. It's not a difficult process.
PS: That magical Alcatraz Extension is named "XCodeWay" (in case you are brave enough to install Alcatraz onto your copy of XCode).
EDIT: Useful link to get Alcatraz: http://alcatraz.io/ Follow its easy instructions and you're done.
EDIT2: If Xcode cannot be used, then the last question in this other thread might come in handy: Browse the files created on a device by the IOS application I'm developing, on workstation?
(Still, an external application in your users machine will be needed )
I've been debugging a problem where my app successfully downloads a file and copies it to the Documents directory. Lately the app cannot open the downloaded file on subsequent launches of the app. I've been printing out file URLs and this is what I see when the file is initially downloaded and opened:
unzipped /var/mobile/Containers/Data/Application/9AC69C00-228E-482F-99D8-DD8F214FCE88/Documents/3.atcase to
/var/mobile/Containers/Data/Application/9AC69C00-228E-482F-99D8-DD8F214FCE88/Library/Application Support/thebundleID/current-case
You can see the UUIDs are the same, but when I launch the app again I see this:
couldn't unzip /var/mobile/Containers/Data/Application/9AC69C00-228E-482F-99D8-DD8F214FCE88/Documents/3.atcase to
/var/mobile/Containers/Data/Application/C18E7EFA-C0D0-4213-AF85-F5BC0D2A4207/Library/Application Support/thebundleID/current-case
This time the UUIDs appear to be different.
I will say tentatively that the answer is yes, the UUID used in the application container folder does seem to change every time the app is run, though I'd love to have some confirmation from a more experienced developer.
The solution to my problem was straightforward: Do not store absolute file URLs in the database. The URLs for the files are now constructed relative to the Documents directory URL every time the app is run. Since I name the files in a regular way, there is no need to store URLs anyway.
I'm making an iPad app which will be distributed from my own web server using Enterprise Distribution Program.
The app itself checks for a newer version on the server and calls itms-services in IOS to update itself. This works perfect.
The app bundle contains a directory with resources like images and movies.
Apple claims that updates will keep the users data if the bundle-identifier is the same.
From: http://help.apple.com/iosdeployment-apps/mac/1.1/#app43ad802c
If you want users to keep the app’s data stored on their device, make sure the new version uses the same bundle-identifier as the one it’s replacing, and tell users not to delete their old version before installing the new one. The new version will replace the old one and keep data stored on the device, if the bundle-identifiers match.
When running the app from Xcode directly to my connected iPad, I can remove the folder with my resources, run the app again, and the folder remains in the bundle on my iPad.
This behavior is what i look for. I'm planning on adding more folders with new resources with new updates. Since the resources are quite heavy, I don't want users to have to download bigger and bigger archives. I want to add just the new stuff.
The problem arises when I make a new archive without the folder and update the app from my web server as users would. Then the folder seems to be deleted.
Any experience with this?
The bundle that you install is always overwritten by the new bundle that you install. The user data referred to in the documentation is the data stored in the Documents and Library folders of the file system. If you wish to be sure that the old bundle files will always be available, you can copy them from the bundle to the Library/Caches folder of the application.
One thing worth mentioning is that the way to ensure that the ad hoc installation overwrites the current bundle is to make sure that you change the bundle version.
hope this helped :)
I am writing an iOS app which download images from a backend server, and store them in the document directory. I know how it is done.
But I need to write a prototype first, which use some pre-given images (not retrieve from the backend server). My question is, is it possible to store images in the document directory during initial installation of the app? I don't want to hardcode them in the bundle directory.
Thanks
Nothing can be done when the app is installed, only when the app is run. The first time the app runs, you can either copy pre-bundled images to the other directory (Documents) or you can download them as needed. It sounds like you want the first option for the prototype.
Basically you need to do what you don't want to do - hardcode them in the bundle.
Remember, the app's sandbox is setup when the app is installed. This includes the creation of the Documents directory. But nothing is put there. Only your running app can store something somewhere in the app's sandbox.
I have an app that is going to display a list of local video files. The app will only have a couple of video files at first, but that number will grow with future updates and in-app purchases. I would like to store all these videos in 1 place and it makes sense to put them in the app's Library directory so they are not user-accessible. Is it possible to publish an app with files already in the app's Library directory? Or do I have to put them in the app's bundle and then copy them to the Library directory when the app is first launched? Although that would result in the 2 videos files being duplicated since I can't remove them from the bundle.
Yes, you do need to copy the files from the app bundle into the Library if you want to treat all the videos in the same way. You cannot change the contents of the app bundle from inside your app and the only files your app has when it first launches are those that are in the app bundle.
If you really wanted (and if the video files don't change), you could make special cases in your code to be able to get the starting videos from the app bundle and the in-app purchase downloaded videos from the Library directory. But, unless the video files are quite large this seems a bit excessive.
A third option would be to have the user download the starter files on first app launch, but that may be suboptimal for other reasons.
Please look at my answer in this thread. It might concern you or at least be interesting to read.
Does updating iOS apps delete library directory files?