iOS Team Coding Standards

The standards in this file cover all iOS, macOS, watchOS, and tvOS work.

There are separate documents for Objective-C Code Standards and Swift Code Standards.


Musts

Code Styling

Naming Guidelines

Variables

AppDelegate Usage

Do not use the AppDelegate class for anything except AppDelegate-related activities (launching the app, closing the app, and responding to UIApplicationDelegate messages). Utility methods and global variables do not belong in the AppDelegate. Put utility methods in their own classes or categories/extensions. If necessary, global variables/constants can be exported/exposed from a specific class or singleton or other context—anything but in the AppDelegate.

Internationalization

Always use NSLocalizedString for user-facing strings. Even if your project is never localized, the advantages of NSLocalizedString outweigh the few extra keystrokes required. NSHipster provides more background information.

Documentation

Scripts

Any shell scripts used in an iOS project must conform to Vokal's Shell Script Standards, including but not limited to shell scripts contained within run script build phases.

Testing

See the main testing document for general guidelines regarding test coverage. Since no reliable and consistent UI testing framework exists for iOS at this time, we do not have a minimum percentage for test coverage of iOS apps; the last thing we want to encourage is test cases that exist solely to fulfill a quota without adding any value. Your tests should cover every part of the app that can reliably be tested, including UI elements. We recommend moving logic out of view controllers where possible, to make it easier to unit test that logic.

CVR has a per-project Minimum Passing Line Percent Coverage option that can be set low when a project begins, but that minimum should gradually climb as the app is built and tests are added. For example, if the app reaches 72% test coverage, that should be the new minimum on CVR: unless you're removing tests that have proven to be inconsistent, the test coverage rate on an app should not fall.

Here are some examples of cases where test coverage can be missing:

When you create a new project using our project template, testing targets are created for unit and UI tests. Both sets of tests are run on Travis for every pull request and merge build.

Shoulds

Code Organization

Code Signing and Provisioning Profile Selection

In each target's Build Settings, the Code Signing Identities should always be generic, such as "iPhone Developer" and "Automatic". This allows the build server to select the right cert and key keychain at build time.

Accessibility Best Practices

Accessibility is key both for UI testing and for VoiceOver, which reads accessibility labels out loud to blind users.

Scripts

Run script phases should be renamed to more specifically describe what the phase does. For any run script phase script beyond a couple lines, it is preferable to have the body of the run script phase call out to an external file, as it's easier to edit an external file and the diffs are easier to handle (Xcode mashes the whole body of a run script phase onto a single line in the project file).

App Transport Security

In iOS 9, Apple introduced App Transport Security to encourage secure networking. In practice, this means that HTTP (as opposed to HTTPS) requests are blocked unless the app requests an exception to allow them. Starting January 1, 2017, secure connections will be required for apps in the App Store.

Exceptions for ATS can be put in the Info.plist, both for servers we control and for third-party servers that we don't. Such exceptions can be acceptable for pulling data from third-party servers, but the exceptions for domains under our control must be justified when the app goes to App Store review.

Unless you have a really, really good reason, do not use ATS exceptions.