Day 1. Connectivity and offline mode

First day

  1. Course overview

  2. I assume that you know Swift. Here is a checklist of topics we can review together: The Swift programming language. (We could spend a full day on the Swift review, so if that is something folks need, we can do that later in the week instead of one of the other topics.)

  3. A software tech firm, briefly:

    • The players / division of labor for our purposes in this training: Product, Design, Engineering.

    • Org chart and “levels”

    • Career tracks: Individual Contributor (IC) vs. managerial track

  4. Connectivity and offline mode

Connectivity and offline mode

Google published an Android document called “Connectivity for billions”. What does it mean for iOS development?

  1. Reachability and network interfaces.

  2. What matters in a network connection

    • Bandwidth, latency, packet loss, jitter

    • Stable

    • Secure (Day 2)

    • Cost (for you and for the end users)

    • Restrictions: at a hotel, behind a firewall, no SIM card

  3. Assets already on disk

    • One vector-based < three rasterized images

    • Lottie < videos

    • Lossy vs. lossless compression and the WebP image format

  4. Downloading images

    • Lazy fetching

    • Why download asynchronously?

    • How to cache? (For example, with a third-party library like Nuke.)

    • Detour: to incur a third-party dependency or not?

    • Asking your backend team to serve the image size you need (depending on screen size and current network connection) and how the backend team might implement that using a queue (e.g. SQS) if these same images are coming from other users.

  5. Deduplicating vs. retrying requests

    • We cache to dedupe, but sometimes we really want to retry

    • Idempotency

    • At scale: empathize with the backend. 500 http-code errors and DDoS-ing yourself.

    • Retry policies:

      • Limit at 3 vs. exponential backoff

      • Interceptors

  6. Offline-first architecture

    • Decouple UI from the service/network layer

    • Persisting to disk:

      • Images

        • Placeholders

        • Blobs: why not store in CoreData

        • File system

        • But really avoid if you can

      • Key-value stores and JSON server responses:

        • UserDefaults, privacy manifests, and fingerprinting

        • UbiquitousKeyValueStore

        • Downsides of using the Keychain as a key-value store (which it is not!)

        • Using CoreData as a key-value store

    • Caching in memory:

      • Collections

      • Key-value store

        • Dictionary

        • UserDefaults and CoreData have in-memory caches, so don’t write an extra layer on top of them

      • Transitory data

        • A bounded disk queue (FIFO)

        • LRU Cache (not FIFO, but not LIFO either)

  7. Reachability (and network interfaces if you ever need them, but you shouldn’t)


Day 2. Mobile Cybersecurity

  • Concepts and mindset: blast radius.

    • Watch where you store/transmit PII. Limit to what’s absolutely necessary. …Articulate a PII policy. A ruleset you can automate is better than judgment. (Does PII require judgment and context or is it as simple as “don’t store X in Y”?)

    • Time To Live (TLL) and expiries.

    • Authorization != authentication

  • Swift Package Manager: distributing binaries safely. (Same problem as downloading a Linux distribution from a mirror site.) Binary target’s checksum.

  • Helping the user login

    • Supporting the “password autofill” feature on iOS

    • Third-party/”social” login

    • Magic links (via deeplink or universal link?)

    • Passkeys

  • Onboarding

    • Permission priming

  • Encryption at rest and in transit

    • At rest: Keychain, UIApplicationDelegate::applicationProtectedDataDidBecomeAvailable, and iCloud

    • In transit: https and certificate pinning (yay or nay?)

  • Authentication and authorization

    • SHA, rainbow tables, and salt

    • Access tokens, centralizing http-header logic, and TTLs:

      • Session tokens

      • JWTs and OAuth2


Day 3.

full-stack architecture for iOS developers

Connectivity part 2

  1. Demystifying the backend:

    • Docker with/vs. AWS. (And what other options aside from AWS?)

    • Remember how SwiftUI is supposed to be declarative? A Terraform vs. CloudFormation example.

    • Serverless vs. fully managed vs. self managed

    • Why isn’t S3 a database? (On iOS, we could similarly ask: why isn’t UserDefaults a database?)

    • ORMs and database tables. (Keep this in mind for CoreData later and remember that SQLite is a relational database, but also that it’s a library and not a standalone application.)

  2. Abstracting the backend:

    • Service-Level Agreement (SLA)

    • The BFF pattern and what to do when you do not have a BFF?

    • Pagination (vs. 202 http response code for long-running job vs. streaming)

    • An API as (a) an abstraction and (b) a contract

    • { REST, JSON, and Swagger } vs. { gRPC, protocol buffers, and the protoc compiler and protoc plugins }

    • http/1.1, http/2, http/3. TCP vs. UDP.

    • Dependency Inversion Principle in SOLID. (Not IoC with callbacks, but the use of abstract interfaces.)

  3. Talking to the backend:

  • Tooling: e.g. Proxyman/Charles, curl/grpcurl, throttling your connection

  • URLSession vs. Alamofire. Using enums to organize your networking code.

  • Feature vs. platform:

    • Intercepters: request adapters (e.g. for authentication)

    • Intercepters: request retriers and retry policies

  • Partial updates:

    • JSON Patch

    • Field Masks

  • Streaming (e.g. a “server push”) instead of request-response

  • Push notifications: APNs and using pushes to wake up the app and/or avoid polling

  • MTCP and the Multipath Entitlement


Day 4. Multithreading

Concurrency and thread safety

  1. Watchdog terminations: Code 0x8badf00d

  2. GCD and deadlocks, async vs. sync

  3. How to make objects shared between threads threadsafe? (Also, remember value types?)

  4. Structured concurrency: why async-await is better than completion handlers

  5. Processes vs. threads (same as “coroutines”?)

  6. Concurrency vs. parallelism. For example, DispatchQueue.concurrentPerform function

  7. DispatchGroup (GCD) and TaskGroup (structured concurrency)

  8. Dispatch queues vs. threads. For example, is “main dispatch queue” synonymous with “main thread”?

  9. CoreData crashes: thread containment


Day 5. UI

When “return” isn’t enough

Communication inside an app. For example, between modules or threads, inter-thread or just decoupled.

  1. One to one vs. one to many (a broadcast / “pub-sub”)

  2. Combine (bye bye RxSwift)

  3. One to one:

    1. A callback vs. delegation

    2. A callback vs. completion handler

    3. A completion handler vs. async-await

    4. SwiftUI and a view model

  4. One to many (a broadcast / “pub-sub”):

    1. Callbacks and delegates. (Yes, it’s possible.)

    2. NSNotificationCenter

Localization: “i18n and l10n”

  1. Locale

    • Metric vs. imperial

  2. Languages

    • Specifying in your test scheme / test plan

    • LocalizableStrings

    • Pluralization: SwiftUI vs. UIKit

    • Why export localizations?

  3. Timezones—not exactly an i18n & l10n topic, but should be mentioned

    • UTC

    • Date vs. TimeInterval


Day 6. Git

Git git git. But not only git. But also git.


Day 7. Recap

Recap.

But wait, what about UI? One big topic we haven’t talked about is UI development. There is SwiftUI and UIKit. With UIKit there is programmatic UIKit or storyboards or nibs. If there is time left, we can talk about these. However, there are plenty of resources on this aside from this course, so this training did not focus on these. Also, everything has some opportunity cost and another thing we could talk about is Swift.