My app got rejected due to not following iOS App Data Storage Guidelines
Asked Answered
A

1

2

My app got rejected due to not follow iOS App Data Storage Guidelines. My binary was rejected by the Apple App Store Review Team.

On launch and content download, your app stores 6.34MB on the user's iCloud, which does not comply with the iOS Data Storage Guidelines.

Next Steps

Please verify that only the content that the user creates using your app, e.g., documents, new files, edits, etc. is backed up by iCloud as required by the iOS Data Storage Guidelines. Also, check that any temporary files used by your app are only stored in the /tmp directory; please remember to remove or delete the files stored in this location when it is determined they are no longer needed.

Data that can be recreated but must persist for proper functioning of your app - or because users 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 kCRUFLIsExcludedFromBackupKey attribute.

What should I do?

Archdiocese answered 19/5, 2016 at 18:38 Comment(0)
A
9

iOS Data Storage Guidelines quick guide

A lot of people are having this problem and often it seems that the review team is automatically claiming that your app does not follow the iOS Storage Guidelines. Either way you need to document where your app store data and what data is stored where. Here's a quick guide that should get you started.

Your app can store files in either /Documents, /Library or /tmp.

iOS File System Storage

Documents/

Use this directory to store user-generated content. The contents of this directory can be made available to the user through file sharing; therefore, his directory should only contain files that you may wish to expose to the user. The contents of this directory are backed up by iTunes.

Library/

This is the top-level directory for any files that are not user data files. You typically put files in one of several standard subdirectories. iOS apps commonly use the Application Support and Caches subdirectories; however, you can create custom subdirectories. Use the Library subdirectories for any files you don’t want exposed to the user. Your app should not use these directories for user data files. The contents of the Library directory (with the exception of the Caches subdirectory) are backed up by iTunes.

tmp/

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.


Put user data in Documents/. This is backed up by iTunes/iCloud

Put app-created support files in the Library/Application support/ This is backed up by iTunes/iCloud

Put temporary data in the tmp/ directory. This is not backed up by iTunes/iCloud

But how do I find out where my files are stored?

Put the script bellow in func application:didFinishLaunchingWithOptions in your appDelegate file. NSSearchPathDirectory is an enum and represents different folder/locations. Some of them are these.

public enum NSSearchPathDirectory : UInt {
case DocumentDirectory 
case LibraryDirectory

}

Change the NSSearhPathDirectory(.DocumentDirectory) to desired locations and check what files you are storing there.

let paths: NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true)
    if let documentDirectory = paths.firstObject{
        do{
            let documents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(documentDirectory as! String)

            for files in documents {
                let urlForm = NSURL.fileURLWithPath((documentDirectory as! String) + "/" + files)

                do{
                    try print("\(files): \(urlForm.resourceValuesForKeys([NSURLIsExcludedFromBackupKey])), with filepath: \(urlForm)")
                 //Prints out folder and files in the desired location

                } catch let error as NSError{
                    print("Can't find key: \(error)")
                }

            }

        }catch let error as NSError{
            print("Can't retrieve contents: \(error)")
        }
    }

My app does not save anything

Lucky you...Write a document to the Apple review team and document your app use of storage. Take screenshots from the logs made out from the script above.

My app saves a lot of user created data

If your app saves a user's data to Documents/ that is fine and write a document documenting that this is made by the user and do follow the iOS Data Storage Guidelines.

If your app downloads data and saves it to the wrong location

Simply follow the iOS Data Storage Guidelines and submit a new binary.


I have files in Documents/ or Library/, but I don't want to back them up

Starting in iOS 5.1, apps can use either NSURLIsExcludedFromBackupKey or kCFURLIsExcludedFromBackupKey file system properties to exclude files and directories from backups. Apps that need to exclude a large number of files can exclude them by creating their own sub-directory and marking that directory as excluded. Apps should create their own directories for exclusion, rather than excluding the system defined directories. Either of these APIs is preferred over the older, deprecated approach of directly setting an extended attribute. All apps running on iOS 5.1 and later should use these APIs to exclude data from backups.

I've created a quick script to handle files that you don't want to backup.

func addSkipBackupAttributeToItemAtPath(filepath: String)-> Bool {

if let url: NSURL = NSURL(fileURLWithPath: filepath) {
    let exist = NSFileManager.defaultManager().fileExistsAtPath(String(url))

    if exist{
        do
        {
            try url.setResourceValues(["YES" : "NSURLIsExcludedFromBackupKey"])
            return true
        }
        catch let error as NSError
        {
            print("\(error)")
            return false

        }

    } else
    {
        print("File does not exist")
        return false
    }

} else
{
    print("Path not recognized")
    return false
}
}

If you believe your app's rejection is false write the review team back and explain the situation and your use of storage


Simple guidelines

Bandwidth, network availability, and storage are limited resources and have real, financial consequences for your users. When you design your schema, store in iCloud only information that can’t be re-created.

iCloud-enabled Core Data apps are not only aware of data created on the device, they’re aware of data on other devices. It’s a good idea to keep this fact in mind when designing your Core Data stack.

When you save a managed object context, Core Data creates, in the ubiquity container, a set of transaction changes that are guaranteed to be applied together on other peers. The size of this transaction set, and the frequency with which you save your context, both directly impact the performance of your app.


Resources:

iOS Data Storage Guidelines - Apple Developer

iCloud Programming Guide for Core Data

File System Programming Guide

Archdiocese answered 19/5, 2016 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.