Tech stack¶
The engine, cache, auth, and sync logic live in the OfemKit Swift
Package (Packages/OfemKit/), linked into both the macOS .app host and
the File Provider Extension.
OfemKit modules¶
Authentication¶
- MSAL for Apple Platforms (MSAL Swift SDK) — public client app,
interactive browser flow, silent refresh, Keychain-backed token cache.
Per-account
PublicClientApplicationinstances, one authority per tenant for clean cache scoping.
HTTP & OneLake¶
- Alamofire
SessionoverURLSessionfor OneLake DFS and Fabric REST calls, pooled per(alias, scope)(Packages/OfemKit/Sources/OfemKit/HTTP/SessionPool.swift): - Token injection via
AuthenticationInterceptor/OfemAuthenticator. RetryAfterRetrier(honorsRetry-After, but only on 429 / 503, bounded tomaxRetries = 5andmaxDelay = 30s) ahead ofJitteredRetryPolicy(aRetryPolicysubclass adding full jitter to the exponential backoff Alamofire would otherwise compute deterministically) in the interceptor chain. Other 5xx statuses (500/502/504) never haveRetry-Afterread — they fall through toJitteredRetryPolicy's jittered backoff alone. Both retriers sharerequest.retryCount/RetryAfterRetrier.maxRetriesas the single source of truth for the combined retry budget, so a 429 that keeps re-triggeringRetry-Aftercannot retry indefinitely.- Per-host connection cap, scoped per audience: 16 for OneLake DFS, 8 for Fabric REST.
Config & data¶
- TOML for config files (
Packages/OfemKit/Sources/OfemKit/Config/). - SQLite (Swift wrapper) for the local file metadata cache (paths, ETags, mtimes, sync state).
Logging¶
os.log(unified logging) — integrates with Console.app out of the box. Structured log entries with privacy annotations.
Telemetry¶
- Custom App Insights client over
URLSession— opt-out, anonymous, tenant IDs only (no UPN / workspace names / file paths). Seedocs/telemetry.md.
IPC (host app ↔ FPE)¶
NSFileProviderService+NSXPCConnection— the standard Apple XPC channel between the host app and the File Provider Extension.
Swift libraries¶
Host app (OneLake/)¶
- SwiftUI (macOS 14+ baseline) for the account-management UI and Settings.
ServiceManagement(SMAppService.mainApp) for the "Open at Login" login-item registration.
File Provider Extension (OneLakeFileProvider/)¶
- Apple's
FileProviderframework. NSFileProviderReplicatedExtensionfor on-demand (placeholder) sync.NSFileProviderServicingto expose the XPC control service to the host app.
Shared (Shared/)¶
OfemClientControlProtocol— the@objcXPC protocol shared between host and FPE.OfemControlInterface— single factory building theNSXPCInterfacefor that protocol (including its secure-coding class registrations), so both sides always wire the exact same interface.OfemConfigKey— canonicalString-backed enum ofsetConfigdotted keys; the FPE'ssetConfigswitches exhaustively over it (nodefault:arm), so a key added here without a matching FPE arm fails to compile.OfemDomainIdentifier— composes/decomposes theofem.<alias>File Provider domain identifier string.XPCAccountInfo,XPCEngineStatus,XPCPausedWorkspace—NSSecureCodingwrappers for XPC transport.
Swift language versions¶
All targets build in Swift 6 language mode:
- OfemKit (
Packages/OfemKit/) —swift-tools-version: 6.0in the package manifest. The CIOfemKit package testsjob runsswift testdirectly against the package. - Host app (
OneLake/) and File Provider Extension (OneLakeFileProvider/) —SWIFT_VERSION = "6.0"inproject.yml.
TOMLKit 0.6.0 compiles cleanly under Swift 6 / Xcode 16.4 with no errors.
The Shared/ XPC payload types (XPCEngineStatus, XPCAccountInfo,
XPCPausedWorkspace) and XPC service types conform to @unchecked Sendable
with justification comments; all other cross-boundary types are value types
or already Sendable-conformant.
Build & release¶
xcodebuildbuilds the Swift.appand.appexfromOneLake.xcodeproj(generated by XcodeGen fromproject.yml).codesign --force --options runtime --sign "Developer ID Application: …"seals the bundle.xcrun notarytool submit … --waitandxcrun stapler staple.- DMG via
create-dmg(Homebrew formulacreate-dmg). - The release workflow uploads the DMG to GitHub Releases and pushes the
rendered cask to the
homebrew-ofemtap repo.
See docs/packaging-homebrew.md for the full pipeline.
Repository layout¶
onelake-explorer-macos/
├── OneLake.xcodeproj # generated by XcodeGen from project.yml
├── project.yml # XcodeGen spec
├── OneLake/ # host app (Swift)
├── OneLakeFileProvider/ # File Provider Extension (Swift)
├── Shared/ # XPC protocol + types shared by both targets
├── Packages/
│ └── OfemKit/ # local Swift Package: engine, auth, cache, sync
├── docs/
├── homebrew/
│ └── Casks/ofem.rb.tmpl # cask template, rendered by the release workflow
├── .github/
├── LICENSE
├── README.md
├── CONTRIBUTING.md
├── SECURITY.md
├── CODE_OF_CONDUCT.md
└── CLAUDE.md