Hello everyone, Apple has rejected our application because we store files for offline viewing under localStorage (/Documents)
This is an extract of the message, we received :
Data that can be recreated but must persist for proper functioning of your app - or because customers expect it to be available for offline use - should be marked with the "do not back up" attribute. For NSURL objects, add the NSURLIsExcludedFromBackupKey attribute to prevent the corresponding file from being backed up. For CFURLRef objects, use the corresponding kCFURLIsExcludedFromBackupKey attribute.
How can we do this with Adobe Air using Flex SDK 4.6?
Believe it or not, Adobe has not made anything about this, and there are no plans to do so, either, so we have to rely in a third party (not developed by Adobe) native extension to set this attribute:
I think this should be natively implemented, since it's a requirement from Apple, not optional, maybe in the form of an attribute change method. If you agree, please vote here: https://bugbase.adobe.com/index.cfm?event=bug&id=3104319
Please go through the following blos post http://blogs.adobe.com/airodynamics/2012/03/05/app-compliance-with-app le-data-storage-guidelines/ to find details about apple storage guidelines. I agree there is no way to set the donot back up attribute but as a work around you can store the images in the caches directory instead of the Documents directory since these files are can be recreated/downloaded again.
Thanks for your reply. The problem is with data you never want purged such as files stored for offline viewing. Users do not want offline files to be automatically removed without any prior notice, even in low space conditions, because they want to access that content while there's no connection. That's the reason to use the DoNotBackup native API.
However, the article you link talks about "Application Support Directory" and says it's never purged under low memory conditions. This is the first time I hear about such a directory. The iOS Data Storage Guidelines never mention this:
So what's this directory and how do we access it?
You can find more details about Application Support Directory in http://developer.apple.com/library/mac/#documentation/FileManagement/C onceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOver view.html. Also, use File.applicationStorageDirectory to store files in Application Support Directory.
Reading the document at the above link, it specifically says:
In iOS 5.0.1 and later, put support files in the <Application_Home>
/Library/Application Support directory and apply the
com.apple.MobileBackup extended attribute to them. This attribute prevents the files from being backed up to iTunes or iCloud.
I don't see how Adobe considers this a solution. As I read this, it seems to imply you still need to mark the files or subfolder with the DoNotBackUp attribute.
Please correct me if I'm wrong.
I only know of one Native Extension for this (Jampot), but it doesn't have any documentation other than a silent YouTube video showing you only how to install the ANE.
Is there any other info you can provide regarding how we can set the DoNotBackUp flag for AIR for iOS?
http://www.jampot.ie/ane/ane-ios-data-storage-set-donotbackup-attribut e-for-ios5-native-extension/ contains details how to use the ane. As mentioned, you can simply pass that directory to the ANE MobileBackup doNotBackup() method.Sample project is also available.
Yeah, I checked it out. They talk about why we need it and what the ANE does, but there are no clear, specific instructions on how to implement it within a project. (And the sample file is a Flex project that I can't open in Flash CS6.)
Any chance one of you guys at Adobe could put together a tutorial for us noobs?
I downloaded the project and am coying the relevant lines of code for you here
public var mobileBackupInstance : MobileBackup = new MobileBackup();
mobileBackupInstance.doNotBackup(<file or directory path you want to apply this attribute to>);
Thanks! Seems simple enough.
Pardon my ignorance, but does this flag need to be set each time the app is launched? Also, how do you test it out to see if it worked?
(In my case, I want to include a folder bundled within the app and marked "DoNotBackUp" which I can add downloaded media files and folders into. Not sure if I'm way off base on this...)
You wont need to set that attribute again and again! Just set it once and you will be done! In case you have to copy that bundled folder to the desired location and then mark it with donotbacku attribute!
I am not aware of a way to check whether this ane worked or now. But you can compare the permissions of a backed up folder with a non backed up folder and caches folder.
Varun Bhatia wrote:
I am not aware of a way to check whether this ane worked or now. But you can compare the permissions of a backed up folder with a non backed up folder and caches folder.
But the application itself can't do this itself, correct? So if there's no way to check if "donotbackup" flag is true or not, then how do we avoid this method from being run each launch?
Thanks so much for helping me understand this concept!
An added note of concern is Apple has updated the "donotbackup" API for iOS 5.1.
Not sure what this means for apps using Jampot's ANE heading into iOS 6...
So here is how I understand this.
Based on the different articles on the web, the jampot extension sets the file attribute "com.apple.MobileBackup" to flag files and folders that you want to be excluded for backup. But for IOS 5.1 and above, you have to now set the "NSURLIsExcludedFromBackupKey" instead. We can still use the jampot extension but Apple is saying that the "com.apple.MobileBackup" way of doing things will soon be depreciated.
So is there another extension that works for IOS 5.1 and above as required by Apple?
FWIW, they did not respond to the first wave of these issues when com.apple.MobileBackup was the "correct" solution, so I doubt they would hurry to respond to the 2nd wave. Having said that, our "sole option" is not being depricated. The extension from jampot can be modified, although not easily, to use the new 5.1 Do Not Backup method. I don't have the source with me, but I will look over it tonight and post a few lines that can be changed to use the 5.1 method. We have done this, we have apps using it on the store. The only caveat is we do not use the 5.0.1 and 5.1 method in tandem, so the app must be marked 5.1 required.
"FWIW, they did not respond to the first wave of these issues when com.apple.MobileBackup was the "correct" solution"
Yes, they mentioned this ANE could be a "solution" for tighter control over this function. But yes, it is dissapointing the official Adobe response for iCloud storage compliance is to simply use the caches folder (which is potentially unreliable for long-term file persistence, of course).
"our "sole option" is not being depricated."
According to Apple, if your app requires 5.1 or above, it is. This sounds to me like a warning to developers that the old method may not work at some point. Can you explain to me otherwise?
"The extension from jampot can be modified, although not easily, to use the new 5.1 Do Not Backup method. I don't have the source with me, but I will look over it tonight and post a few lines that can be changed to use the 5.1 method."
Yes, it would be interesting to see how you handled this. However, if it involves C+ code or re-building the ANE or other such witchcraft :-) , I'm afraid it may be way over my head. (Others may benifit from your findings, however).
What I'm saying is that com.apple.MobileBackup is not our sole option, although it is being depricated. This method is not an Adobe developed solution, neither would be a modified version of the jampot extension. Their official response has been, as you say, to use the cache folder, which is completely and totally not an option for many applications.
The modified jampot extension would require changes to the native objective-c code before compiling. I'll try to get more details or possibly a binary linked later.
Hi gtr and christophertotty,
We had the jampot version working fine (althouth not without some diffuclty to set up) until iOS 6 was released. It no longer prevents the data being picked up by iCloud.
How about we collaborate to get the issue resolved? We can commit some dev time and/or a little monerary incentive as we have some apps already on the appstore using it as well.
No worries, our intention is to post whatever solution we come up with somewhere. We are kind of working on this at the moment.
I've been very vocal with Adobe about these things. I think there is a certain numbers of features where they should be posting ANE's and maintaining them ... Anyhow, I will save the rant for another time
Alright, again I must emphasize that this is not an easy thing to get going, at least it wasn't for me. However, I have a 5.1+ solution made building on the jampot extension available here:
Replacing the ANE file in the zip provided by jampot with the one linked below should then cause calls to that extension to follow the new 5.1 method.
The extension documentation has more info on how to use it, but for a quick start, we use something like:
if (flash.system.Capabilities.version.substr(0,3).toUpperCase() == "IOS")
var noBackupSetter : MobileBackup = new MobileBackup();
var result:Boolean = noBackupSetter.doNotBackup(DataStorage.filePrivate.nativePath);
This will set the entire File.applicationStorageDirectory to DoNotBackup. Files that are saved within the directory will obey the DoNotBackup rule for the containing folder.
Make sure you have the MobileBackup class from the files provided by jampot in your project and that you have included the native extension in your project and packaging. If you have trouble with any of that, please reference the jampot link above, with the exception of using the 2nd link's ANE file.
Two important notes--
First, I have only had success compiling my project using this ANE on a Mac against Air 3.3 with the project pointed directly to my iOS 5.1 SDK folder, found at
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform /Developer/SDKs/iPhoneOS5.1.sdk . (I am using Xcode version 4.4.1, I do not know if this sdk is available in later versions, but it may be possible to find an upload of someone's copy on the web)
Second, the code the modified ANE uses requires iOS 5.1. If you submit an app that uses this ANE and it is installed by a pre-5.1 device, the app will immediately crash. To keep your app from being installed on pre-5.1 devices, modify your AppName-app.xml file in the root of your project to set the MinimumOSVersion like so:
I'm sorry I don't have access to the changes I made to source at this time, but I will post again when I can to include the specific changes made. There really was not much change to the objective-c code. The hard part was getting the ANE built and working with Flash Builder.
Thanks a lot for your effort! Any clues about how to do it in Windows?
I can't believe we have to rely in hacking an already third party solution made by some random guy in the Internet to address an issue that Adobe AIR should have addressed in the first place.
Also, I don't like having to block older versions of iOS. I think I'll wait for now before updating to setting the new attribute. Also, why does have Apple to mess around so much with this? I don't see any advantage in the new method over the old one.
I'm sorry, I never could get it to work in Windows. I can tell you this... the reason why I need Mac is because it requires iOS 5.1 SDK to compile in Flash Builder. I believe Air 3.4 include iOS 5.1 support. It may be possible to use this ANE in Windows compiled against Air 3.4. However, my app has other issues with Air 3.4, so I do not use it. I would try compiling against a Flex sdk folder with Air 3.4 or maybe Air 3.5 beta overlayed and see if you get better results.
I spent the better part of a day wrestling with the command line compiler to pass the platform-sdk folder, etc etc. on Windows, but I never had any luck. This was all before the Air 3.4 release, so give that a go.
As promised, here are the source changes I made to the jampot extension. The original files can be found here: http://www.jampot.ie/ane/
The modified capiextension.m is available here: http://bit.ly/UQeQDV
All I did was stumble my way through swapping to the new method of calling for Do Not Backup and recompiling the ANE through Xcode and the adt command line builder. I have removed a few trace lines from the source that were included in the build above, but that should be the only difference.
I make no claim that the ANE or code for it are my property. I do highly recommend that you just use the pre-built ANE linked in my post above, or a new one from jampot if they make the same changes, since the hoops to build from source are small and plentiful.
Sorry for the noobish question... How were you able to check that the old jampot ane was not working on IOS 6?
I tried using it on our project and I just used the boolean return value to check if it was working or not. Using it on the Application Storage directory always shows false but after placing the files into the Private Documents directory it would then return as true. Is the boolean return value the proper way to test if it is working?
The only way I know of for sure to know if the files will not be backed up by iCloud is to install your app and run it a bit to add your files (we copy a database at first startup, so it is obvious), and then you should check the phones Settings -> iCloud -> Storage & Backup -> Manage Storage -> Your Device Name. Look at the list of apps and find yours. The space should be very small, less than 100 bytes. If it is higher than that, then the files you have downloaded are going to be backed up to iCloud.
The way to be 100% sure, is to go into the "iCloud" settings, then to "Storage and BackUp" then "Manage Storage", then chose your device (if you have more than one) and look for your application icon. (You may need to click also on "Show all apps" if you have a lot apps installed)
Check if the app being backed up by iCloud.
For example, our applications loads a few pdf files when it loads and we store the pdf's in a folder mark to "Do Not Back Up". If the ANE is working, our app will not show up at all or it will show something between 1 to 4K to back up (this is normal). However when it does not work, it marks 25MB+ to back up, as it is adding the weight of the pdf files.
If it is showing "No Data", then yes, your app is not sending anything to iCloud at this time. When we did our testing on 5.1, I believe we had data still being sent even when using the previous jampot extension. Either way, keep in mind that the functionality it uses is now deprecated, which means that Apple may not continue to support that function in future releases of iOS. Also, Apple has stated that the new method is required for apps that target iOS 5.1. I take that to mean that using the com.Apple.MobileBackup method only would potentially be cause for an app rejection, but I do not know for certain that would happen.
"iOS 5.1 introduces a new API to mark files or directories that should not be backed up. For NSURL objects, add the NSURLIsExcludedFromBackupKey attribute to prevent the corresponding file from being backed up. For CFURLRef objects, use the corresponding kCFURLIsExcludedFromBackupKey attribute.
Apps running on iOS 5.1 and later must use the newer attributes and not add the com.apple.MobileBackup extended attribute directly, as previously documented. The com.apple.MobileBackup extended attribute is deprecated and support for it may be removed in a future release."
Any updates on this issue?
I have to make a decision on which method to use (Jampot or caches) to store larger downloadable files very soon. Has anyone heard anything from Jampot on if this will be updated? Any word on if Adobe will get around to supporting this core iOS feature?
Yes. However, having re-read #23, I see that you posted a compiled ANE, where inititally, I was under the impression it needed to be built & compiled (which is over my head).
Thanks for your work on this! Have you successfully submitted any apps to Apple using the modified Jampot ANE yet?
Yes, I have multiple apps on the store at this time using the modified ANE. If you have the Jampot ANE working, it should be as simple as dropping the modified ANE file into the location you have the Jampot ANE stored.
is there any solution new?
i tried all of them, but not work. why don't adobe work about it?
i make ios application with flash cs6 air but apple reject me becouse of "do not back up". i spent a lot of time for make this app. please help.
With AIR 3.6 latest prerelease,
A new property, preventBackup is introduced in the File API, which when set prevents a file or a folder from getting backed up on the iCloud. This property works on iOS 5.1 devices and later.
Another static property, File.cacheDirectory has been added, which points to the <APPLICATION_HOME>/Library/Caches directory on iOS devices, and files in this directory are not backed up.
You can find additional details on this feature here<http://labsdownload.adobe.com/pub/labs/flashruntimes/shared/air3-6_fla shplayer11-6_releasenotes.pdf>