SkillAgentSearch skills...

StandardPaths

StandardPaths is a category on NSFileManager for simplifying access to standard application directories on iOS and Mac OS and abstracting the iCloud backup flags on iOS. It also provides support for working with device-specific file suffixes, such as the @2x suffix for Retina displays, or the -568h suffix for iPhone 5 and can optionally swizzle certain UIKit methods to support these suffixes more consistently.

Install / Use

/learn @nicklockwood/StandardPaths
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Purpose

iOS and the Mac App Store place quite strict conditions on where files should be stored, but it's not always clear where the right place is. As of iOS 5.0 it's even more complex because of the need to ensure that certain files aren't backed up to iCloud or aren't wiped out when the device gets full.

Also, since the advent of Retina displays and hybrid apps, it is often hard to identify the correct file path for resources such as images or nib files because on different devices they may have different suffixes such as @2x or ~ipad, and whilst many iOS and Mac OS APIs manage these suffixes automatically, they do so in an inconsistent and opaque way.

Support for the -568h file suffix for targeting the iPhone 5 screen is also frustratingly limited to only the launch image, and is not generally supported for loading images, nib files, etc.

StandardPaths provides a simple set of NSFileManager extension methods to access files in a clear and consistent way across platforms, and abstracts the complexity of applying the mobile backup attribute to disable iCloud backup on iOS 5 and above.

StandardPaths also provides NSString extension methods for manipulating file suffixes for Retina graphics, iPhone 5 and device idioms (phone/pad/desktop) to simplify loading device-specific resources.

Finally, StandardPaths swizzles some of the methods in UIKit and AppKit so that they gain additional intelligence when loading device-specific resources. This enables you to load the correct images and nib files for iPhone5 based on the file suffix instead of ugly runtime code checks of the display size. This swizzling can be disabled if you would prefer not to mess with the standard behaviour (see below for details).

Supported OS & SDK Versions

  • Supported build target - iOS 11.2 / Mac OS 10.12 (Xcode 9.2)
  • Earliest supported deployment target - iOS 8.0 / Mac OS 10.11
  • Earliest compatible deployment target - iOS 7.0 / Mac OS 10.7

NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this OS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.

ARC Compatibility

StandardPaths work with both ARC and non-ARC projects. There is no need to exclude StandardPaths files from the ARC validation process, or to convert StandardPaths using the ARC conversion tool.

Thread Safety

You can call the StandardPaths methods safely from any thread.

Installation

To use the StandardPaths in your project, just drag the StandardPaths.h and .m files into your project. It has no dependencies.

NSFileManager extension methods

StandardPaths extends NSFileManager with a collection of useful standard directories. Most methods come in two versions, one that returns just the path to the directory and a second that returns a path for a specific file name or path fragment within that directory. In the interests of concision, these methods are paired together in the documentation below.

- (NSString *)publicDataPath;
- (NSString *)pathForPublicFile:(NSString *)file;

Return the path for the user Documents folder. On iOS this a good place to store user-created documents. You can make these documents available for the user to access through iTunes by setting UIFileSharingEnabled to YES in the application's Info.plist. For this reason it's a bad idea to store private application data files in the Documents folder as you lose this flexibility. You should store these in Library/Application Support instead. Note also that the Mac App Store sandbox rules prohibit accessing files in Documents without requesting explicit permission from the user.

- (NSString *)privateDataPath;
- (NSString *)pathForPrivateFile:(NSString *)file;

Returns the path for Library/Application Support on iOS, or Library/Application Support/<AppName> on Mac OS and creates it if it does not exist. This is a good place to store application data files that are not user editable and so shouldn't be stored in the Documents folder.

- (NSString *)cacheDataPath;
- (NSString *)pathForCacheFile:(NSString *)file;

Returns the path to the Application's Library/Caches folder. On Mac OS, the path will include a subfolder named after the Application's bundle ID to prevent namespace collisions. If your app downloads data from the Internet, or caches the result of expensive calculations, this is a good place to store the result. On iOS 5 and above these files will be deleted automatically when the device runs low on space, so if the data is important you should store it using the offlineDataPath instead.

- (NSString *)offlineDataPath;
- (NSString *)pathForOfflineFile:(NSString *)file;

Returns the path for Library/Application Support/Offline Data on iOS, or Library/Application Support/<AppName>/Offline Data on Mac OS and creates it if it does not exist. This is not a standard defined path, but it is a safe place to put cache files that you do not wish to be automatically deleted when the device runs low on disk space. On iOS 5.0.1 the com.apple.MobileBackup attribute is set on this folder to prevent it from being automatically backed up to iCloud. This flag is deprecated in iOS 5.1, so when compiling for 5.1 and above, a new API is used. These mechanisms are not available prior to iOS 5.0.1, so users on iOS 5.0 will find that these files are synced to their cloud space. Previous releases of the StandardPaths library stored offline data files in Library/Caches, but this would cause inconvenience for users upgrading from iOS 4/5 to 5.0.1 that is probably not justified, so as of version 1.1, offlineDataPath no longer does this.

- (NSString *)temporaryDataPath;
- (NSString *)pathForTemporaryFile:(NSString *)file;

Returns the path for the temporary data folder. This is a good place to store temporary files e.g. during some complex process where the data can't all fit in memory. Files stored here may be deleted automatically when the application is closed, or when the device runs low on memory, but it's a good idea to delete them yourself anyway when you've finished with them.

- (NSString *)resourcePath;
- (NSString *)pathForResource:(NSString *)file;

Returns the path for files in the application resources folder. This basically just maps to [[NSBundle mainBundle] resourcePath]. Files in this folder are read-only. Note that unlike the [[NSBundle mainBundle] pathForResource:ofType:] method, pathForResource: does not return nil if the file does not exist.

- (NSString *)normalizedPathForFile:(NSString *)fileOrPath;
- (NSString *)normalizedPathForFile:(NSString *)fileOrPath ofType:(NSString *)ext;

This method takes a file name or path and normalizes them by performing the following operations:

  1. It can take a path fragment or file name and convert it to a complete path by prefixing the application bundle resources path. Secondly, it replicates the behaviours of Mac OS and iOS when finding different versions of resource files such as @2x image files or files suffixed with ~ipad or ~iphone (and adds a ~mac extension option for cross-platform consistency).

  2. It supports the iPhone 5 "-568h" suffix for files designed specifically for the taller screen. Apple don't provide any built-in support for this suffix other than on the Default.png startup image, but the normalizedFilePathForFile: method will detect and use any file with this extension (with or without the @2x) when running on an iPhone 5 and use it in preference to non-suffixed files with the same name. This is very useful for loading iPhone 5-specific images and nib files automatically without ugly runtime code checks.

  3. It implements the Cocos2D -hd suffix pseudo-standard to indicate image files that should be used both for Retina iPhones and standard definition iPads/Macs. This allows you to support 2 or 3 platforms with the same code base without bloating your app with duplicate images that are identical apart from the file name.

  4. It correctly maps .png image paths to the multi-page HiDPI TIFF files used on Mac OS 10.7+ for combining standard and Retina scale images into a single file.

These behaviours will work with any file, not just images or nibs, so it can be useful if you want to load device-specific versions of nib files, 3D models or shaders for OpenGL applications without writing a lot of branching code. Unlike the other NSFileManager extension methods, this method will return nil if the file does not exist. This method makes multiple filesystem calls, so may be relatively slow the first time it is called for each path, however it caches the result for a given input so the next time it will be faster. See the Image file suffixes section below for more information.

The ofType: form of the method takes an optional file extension to use if the file does not already have an extension. Unlike the built-in [[NSBundle mainBundle] pathForResource:ofType:] method, the extension will be ignored if the file already has a type.

NSString extension methods

StandardPaths extends NSString with some additional methods for manipulating file paths by adding, deleting and retrieving the standard and pseudo-standard path extensions used for Retina-resolution images and device-specific resources. See the Image file suffixes section below for more information.

- (NSString *)stringByReplacingPathExtensionWithExtension:(NSString *)extension;

This method replaces a string path extension with the specified value.

- (BOOL)hasPathExtension;

This method returns YES if the string has a path extension.

- (NSString *)stringByAppending
View on GitHub
GitHub Stars337
CategoryProduct
Updated2mo ago
Forks45

Languages

Objective-C

Security Score

80/100

Audited on Jan 5, 2026

No findings