Skip to content

36 ‐ Source code conventions

Pierre-Yves Lapersonne edited this page May 22, 2025 · 5 revisions

Linter

Tip

Use SwiftLint and SwiftFormat with our rules

Variables

Keep variables, constants, computed and stored properties sorted. Private items should be below properties non private. Environment variables should be below private variables. Computed properties can be below the body of the views. Filter things by visiblity: open first, then public less higher, then internal, then private. If for the same visiblity we have several wrappers, try to gather them If you think line breaks should be added for clarity reasons to avoid to have big block of proeprties, feel free to add them.

For example:

// Do
struct AwesomeObject: View {

    // MARK: - Properties

    public var something: String

    @Binding var isOn: Bool

    private let isError: Bool
    private let a11yLabel: String
    @State private var someState: Bool
    @Environment(\.isEnabled) private var isEnabled
    @Environment(\.theme) private var theme

    // MARK: - Initializers

    init(isOn: Binding<Bool>) { ... }

    // MARK: - Body

    var body: some View { ... }

    // MARK: - Computed properties

    private var someView: Text { ... }
    private var someProps: String { ... }
}

// Don't
struct DirtyObject: View {

    // MARK: - Properties

    @Environment(\.isEnabled) private var isEnabled
    @Environment(\.theme) private var theme

    @Binding var isOn: Bool

    private let isError: Bool

    @State private var someState: Bool
    private let a11yLabel: String

    public var something: String

    // MARK: - Body

    var body: some View { ... }

    // MARK: - Computed properties

    private var someView: Text { ... }
    private var someProps: String { ... }

    // MARK: - Initializers

    init(isOn: Binding<Bool>) { ... }
}

Other conventions

  1. Public / open objects (struct, class, actor, methods) must be prefixed by OUDS
  2. MARK can be used for the Xcode minimap with a dash to draw a thin line ; use it properly
  3. Make things public / open if and only if needed or exposed through the library
  4. If things can be private, make them private

Localizables

Wording keys follow a logic of patterns shared between platforms. These keys will be managed by a third-party tool which will download the assets with the string entries. Here are the rules explaining how wording keys are defined.

Fragments of key

The key must have several fragments named "where", "what", "type" and "suffix" (optinal).

Where

Path to locate the key:

  • can be: app, component, moreApps, about or common for keys used across multiple places.
  • (optional) is the page where is located the key. Note: The deeper the key is located in the application, the more screens are in the path.
  • (optional) indicates the area in the screen

Note: If a key is common in a part of the app, provides the path to this part followed by "common". Example: app_components_common

What

Description of the key which allows to differentiate several labels, buttons or texts in the same screen.

Type

Type of the key. It can be:

  • button for strings in buttons or icon buttons
  • label for few words of text (tab, menu, title)
  • text for long texts
  • etc.

Suffix

Essentially used for accessibility. It can be:

  • a11y for vocalized strings
  • hint additional vocalized string
  • etc.

Some example

Details button in the accessibility screen of the app about:

  • "app_about_accessibility" + "details" + "button"
  • app_about_accessibility_details_button

Details button a11y in the accessibility screen of the app about:

  • "app_about_accessibility" + "details" + "button" + "a11y"
  • app_about_accessibility_details_button_a11y

List item « Vertical image first card »:

  • "app_components_cards" + "verticalImageFirst" + "label"
  • app_components_cards_verticalImageFirst_label

CGU menu in the about screen of the app:

  • "app_about" + "cgu" + "label"
  • app_about_cgu_label

Accessibility of icon button in top bar:

  • "app_topBar" + "palette" + "button" + "a11y"
  • app_topBar_palette_button_a11y

Use of UIKit

Because UIKit is not available on macOS, the swift package generate-documentation command from swift-docc-plugin fail to build the documentation. In addition, tests are run using swift test command line which cannot handle specific platforms API (see #667). Thus, to still be able to build the documentation, any import and use of UIKit must be on-build-time conditioned. See discussion #626

// Don't
import UIKit

// Do
#if canImport(UIKit)
    import UIKit
#endif
Clone this wiki locally