App Distribution, Performance and Security
56.1 App Distribution (Apple Platforms)
Apple Developer Program membership, certificates, identifiers, provisioning profiles (Xcode's automatic signing), App Store Connect, TestFlight (beta testing), App Review guidelines, privacy manifests (PrivacyInfo.xcprivacy), App Privacy labels, in-app purchases (StoreKit 2), notarization for macOS apps outside the App Store.
CI/CD: Xcode Cloud, GitHub Actions (macOS runners), fastlane (automating builds, screenshots, signing, uploads), Bitrise.
56.2 Performance
Prefer value types, final classes, and private/fileprivate (which enable static dispatch). Mark non-overridable classes final.
Use whole-module optimization and -O in release builds. Use generics specialization and @inlinable for hot library APIs.
Avoid unnecessary copies of large structs (borrowing/consuming, copy-on-write wrappers). Reserve capacity (reserveCapacity). Use ContiguousArray for class elements.
Minimize existential (any) use in hot paths. Prefer some/generics.
Measure with Instruments and ContinuousClock. Benchmark with package-benchmark (ordo-one).
SwiftUI: keep body cheap, use @Observable for fine-grained updates, use lazy stacks for long lists, stable ids, and avoid heavy work in init.
App startup: reduce dynamic frameworks, defer work, use the launch time profiler.
56.3 Security
Store secrets in the Keychain (never in UserDefaults or source code). Use CryptoKit for hashing/encryption (SHA256.hash, AES.GCM, P256 signing, Secure Enclave keys).
Enforce HTTPS (ATS), consider certificate pinning for sensitive apps, validate all input (deep links, JSON).
Biometrics with LocalAuthentication (Face ID/Touch ID). Data protection classes for files. App Sandbox (macOS) and entitlements.
Use memory-safe Swift APIs. Isolate unsafe code. Enable strict memory safety checking (6.2) for security-critical modules.
Dependency hygiene: pin versions, review packages, watch for supply-chain risks.
import CryptoKit
let digest = SHA256.hash(data: Data("password".utf8))
let key = SymmetricKey(size: .bits256)
let sealed = try AES.GCM.seal(Data("secret".utf8), using: key)
let opened = try AES.GCM.open(sealed, using: key)