Technology Stack
Last Updated: 2026-02-03 | Reading Time: 15 minutes
Comprehensive overview of technologies powering PasteShelf.
Table of Contents
Section titled βTable of Contentsβ- Overview
- Core Technologies
- Apple Frameworks
- Third-Party Dependencies
- Development Tools
- Infrastructure
- Technology Decisions
Overview
Section titled βOverviewβPasteShelf is built as a native macOS application using Appleβs latest technologies, prioritizing performance, privacy, and seamless system integration.
Tech Stack Summary
Section titled βTech Stack Summaryβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ PasteShelf Tech Stack ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ LANGUAGE Swift 5.9+ ββ UI FRAMEWORK SwiftUI + AppKit ββ DATA PERSISTENCE CoreData + CloudKit ββ CONCURRENCY Swift Concurrency (async/await) ββ SECURITY Keychain + CryptoKit ββ PLATFORM macOS 14.0+ (Sonoma) ββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββCore Technologies
Section titled βCore TechnologiesβSwift 5.9+
Section titled βSwift 5.9+βRole: Primary programming language
Why Swift?
- Type safety and modern syntax
- Excellent macOS integration
- Strong concurrency model
- Active development by Apple
Key Features Used:
// Swift Concurrencyfunc fetchItems() async throws -> [ClipboardItem] { try await withThrowingTaskGroup(of: ClipboardItem.self) { group in // Parallel processing }}
// Property Wrappers@MainActorclass ViewModel: ObservableObject { @Published var items: [ClipboardItem] = []}
// Result Builders (SwiftUI)var body: some View { VStack { ForEach(items) { item in ItemRow(item: item) } }}
// Macros (Swift 5.9+)@Observableclass AppState { var clipboardItems: [ClipboardItem] = []}SwiftUI
Section titled βSwiftUIβRole: Primary UI framework
Why SwiftUI?
- Declarative, reactive UI
- Native macOS look and feel
- Automatic dark mode support
- Built-in accessibility
Architecture:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ SwiftUI Architecture ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ View ViewModel Model ββ ββββ βββββββββ βββββ ββ ββ ββββββββββββ βββββββββββββββββ ββββββββββββββββ ββ β SwiftUI ββββββΆβ ObservableObj ββββββΆβ CoreData β ββ β View β β @Published β β Entity β ββ ββββββββββββ βββββββββββββββββ ββββββββββββββββ ββ β β ββ β @StateObject β @FetchRequest ββ β @EnvironmentObjβ ββ βΌ βΌ ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β Combine Publishers β ββ β (Reactive data flow) β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββKey Components:
| Component | Usage |
|---|---|
@State | Local view state |
@Binding | Two-way data binding |
@StateObject | ViewModel ownership |
@EnvironmentObject | Shared state |
@FetchRequest | CoreData integration |
@AppStorage | UserDefaults binding |
CoreData
Section titled βCoreDataβRole: Local data persistence
Why CoreData?
- Native Apple framework
- CloudKit integration built-in
- Efficient for large datasets
- Automatic migration support
Configuration:
// NSPersistentCloudKitContainer for sync supportlet container = NSPersistentCloudKitContainer(name: "PasteShelf")
// Multiple store configurationlet localStoreDescription = NSPersistentStoreDescription(url: localURL)localStoreDescription.configuration = "Local"
let cloudStoreDescription = NSPersistentStoreDescription(url: cloudURL)cloudStoreDescription.configuration = "Cloud"cloudStoreDescription.cloudKitContainerOptions = CKContainerOptions( containerIdentifier: "iCloud.com.pasteshelf.PasteShelf")See Database Schema for data model details.
CloudKit β
Section titled βCloudKit ββRole: Cross-device synchronization
Why CloudKit?
- Native Apple integration
- End-to-end encryption
- No server maintenance
- Generous free tier
Architecture:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ CloudKit Architecture ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β Private Database β ββ β (User's iCloud Account) β ββ β β ββ β ββββββββββββββββββββββββββββββββββββββββββββββββββ β ββ β β Custom Zone β β ββ β β "com.pasteshelf.clipboardHistory" β β ββ β β β β ββ β β Record Types: β β ββ β β β’ ClipboardItem β β ββ β β β’ ClipboardContent (asset) β β ββ β β β’ UserPreferences β β ββ β ββββββββββββββββββββββββββββββββββββββββββββββββββ β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ ββ Sync Features: ββ β’ Automatic background sync ββ β’ Conflict resolution (last-write-wins) ββ β’ Incremental changes via CKFetchRecordZoneChangesOperationββ β’ Push notifications for real-time updates ββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββApple Frameworks
Section titled βApple FrameworksβSystem Integration
Section titled βSystem Integrationβ| Framework | Purpose | Tier |
|---|---|---|
| AppKit | Menu bar, floating panel | π |
| Foundation | Core utilities | π |
| Combine | Reactive programming | π |
| OSLog | Unified logging | π |
| MetricKit | Performance metrics | π |
| LocalAuthentication | Biometric auth | π |
| CryptoKit | Encryption | π |
| NaturalLanguage | Text analysis | β |
| CreateML | On-device ML | β |
| Vision | OCR for images | β |
NSPasteboard (Clipboard)
Section titled βNSPasteboard (Clipboard)βCore clipboard monitoring:
import AppKit
class ClipboardMonitor { private var changeCount: Int = 0 private var timer: Timer?
func startMonitoring() { changeCount = NSPasteboard.general.changeCount
timer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { [weak self] _ in self?.checkForChanges() } }
private func checkForChanges() { let currentCount = NSPasteboard.general.changeCount if currentCount != changeCount { changeCount = currentCount captureCurrentContent() } }
private func captureCurrentContent() { let pasteboard = NSPasteboard.general
// Supported types let types: [NSPasteboard.PasteboardType] = [ .string, .rtf, .html, .png, .tiff, .fileURL ]
for type in types { if let data = pasteboard.data(forType: type) { // Process content } } }}Security Framework
Section titled βSecurity FrameworkβKeychain integration:
import Security
class KeychainManager { func save(key: String, data: Data) throws { let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: "com.pasteshelf.PasteShelf", kSecAttrAccount as String: key, kSecValueData as String: data, kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly ]
let status = SecItemAdd(query as CFDictionary, nil) guard status == errSecSuccess else { throw KeychainError.saveFailed(status) } }}CryptoKit
Section titled βCryptoKitβEnd-to-end encryption:
import CryptoKit
class EncryptionManager { private let key: SymmetricKey
init() { // Generate or retrieve from Keychain key = SymmetricKey(size: .bits256) }
func encrypt(_ data: Data) throws -> Data { let sealedBox = try AES.GCM.seal(data, using: key) return sealedBox.combined! }
func decrypt(_ data: Data) throws -> Data { let sealedBox = try AES.GCM.SealedBox(combined: data) return try AES.GCM.open(sealedBox, using: key) }}LocalAuthentication
Section titled βLocalAuthenticationβBiometric authentication:
import LocalAuthentication
class BiometricAuth { func authenticate() async throws -> Bool { let context = LAContext() var error: NSError?
guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else { throw BiometricError.notAvailable }
return try await context.evaluatePolicy( .deviceOwnerAuthenticationWithBiometrics, localizedReason: "Unlock PasteShelf" ) }}Vision Framework β
Section titled βVision Framework ββOCR for image search:
import Vision
class OCREngine { func extractText(from image: CGImage) async throws -> String { let request = VNRecognizeTextRequest() request.recognitionLevel = .accurate request.usesLanguageCorrection = true
let handler = VNImageRequestHandler(cgImage: image, options: [:]) try handler.perform([request])
guard let observations = request.results else { return "" }
return observations .compactMap { $0.topCandidates(1).first?.string } .joined(separator: "\n") }}NaturalLanguage Framework β
Section titled βNaturalLanguage Framework ββSemantic search:
import NaturalLanguage
class SemanticSearch { private let embedding = NLEmbedding.wordEmbedding(for: .english)
func findSimilar(to query: String, in items: [ClipboardItem]) -> [ClipboardItem] { guard let queryVector = embedding?.vector(for: query) else { return [] }
return items .map { item in let similarity = cosineSimilarity(queryVector, item.embedding) return (item, similarity) } .sorted { $0.1 > $1.1 } .map { $0.0 } }}Third-Party Dependencies
Section titled βThird-Party DependenciesβDependency Philosophy
Section titled βDependency PhilosophyβPasteShelf minimizes third-party dependencies to:
- Reduce attack surface
- Avoid licensing complications
- Ensure long-term maintainability
- Keep app size small
Current Dependencies
Section titled βCurrent Dependenciesβ| Dependency | Purpose | License |
|---|---|---|
| None | Pure Apple frameworks | N/A |
Potential Future Dependencies
Section titled βPotential Future Dependenciesβ| Dependency | Purpose | Consideration |
|---|---|---|
| SQLite.swift | Direct SQLite access | If CoreData limitations hit |
| KeychainAccess | Simplified Keychain | If Security API too complex |
| Sparkle | Auto-updates (non-App Store) | Direct distribution only |
Development Tools
Section titled βDevelopment ToolsβRequired Tools
Section titled βRequired Toolsβ| Tool | Version | Purpose |
|---|---|---|
| Xcode | 15.0+ | IDE and build system |
| Swift | 5.9+ | Compiler |
| Git | 2.30+ | Version control |
| SwiftLint | Latest | Code linting |
| SwiftFormat | Latest | Code formatting |
CI/CD Tools
Section titled βCI/CD Toolsβ| Tool | Purpose |
|---|---|
| GitHub Actions | CI/CD automation |
| Fastlane | Build and release automation |
| xcpretty | Prettier Xcode output |
Testing Tools
Section titled βTesting Toolsβ| Tool | Purpose |
|---|---|
| XCTest | Unit and UI testing |
| XCUITest | UI automation |
| Instruments | Performance profiling |
Documentation Tools
Section titled βDocumentation Toolsβ| Tool | Purpose |
|---|---|
| DocC | API documentation |
| Markdown | General documentation |
Infrastructure
Section titled βInfrastructureβDistribution Channels
Section titled βDistribution Channelsβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Distribution Architecture ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ βββββββββββββββββββ βββββββββββββββββββββββββββββββ ββ β App Store β β Direct Distribution β ββ β (Primary) β β (Secondary) β ββ β βββββββββ β β ββββββββββββββ β ββ β β β β ββ β β’ Sandboxed β β β’ DMG download β ββ β β’ Review β β β’ Sparkle updates β ββ β β’ Auto-update β β β’ Notarized β ββ β β’ Payment β β β’ Direct licensing β ββ βββββββββββββββββββ βββββββββββββββββββββββββββββββ ββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββBackend Services π’
Section titled βBackend Services π’βFor Enterprise features:
| Service | Provider | Purpose |
|---|---|---|
| Sync Server | Self-hosted option | Air-gapped sync |
| Analytics | Privacy-respecting | Usage metrics |
Technology Decisions
Section titled βTechnology DecisionsβDecision Records
Section titled βDecision RecordsβADR-001: SwiftUI vs AppKit
Section titled βADR-001: SwiftUI vs AppKitβContext: Choose primary UI framework.
Decision: SwiftUI with AppKit interop.
Rationale:
- SwiftUI for main views (modern, declarative)
- AppKit for menu bar and floating panel (better control)
- Future-proof as SwiftUI matures
ADR-002: CoreData vs SQLite
Section titled βADR-002: CoreData vs SQLiteβContext: Choose persistence layer.
Decision: CoreData with NSPersistentCloudKitContainer.
Rationale:
- Built-in CloudKit sync
- Automatic migration
- Appleβs strategic direction
- Good enough performance for clipboard data
ADR-003: CloudKit vs Custom Backend
Section titled βADR-003: CloudKit vs Custom BackendβContext: Choose sync infrastructure.
Decision: CloudKit for Pro, self-hosted option for Enterprise.
Rationale:
- CloudKit: Zero infrastructure, E2E encryption, Apple integration
- Self-hosted: Enterprise compliance requirements
ADR-004: On-Device ML vs Cloud AI
Section titled βADR-004: On-Device ML vs Cloud AIβContext: Choose AI/ML strategy for semantic search.
Decision: On-device ML using CreateML/CoreML.
Rationale:
- Privacy: No data leaves device
- Performance: Low latency
- Offline: Works without internet
- Cost: No API fees
Version Compatibility
Section titled βVersion CompatibilityβMinimum Requirements
Section titled βMinimum Requirementsβ| Component | Version | Release Date |
|---|---|---|
| macOS | 14.0 (Sonoma) | Sep 2023 |
| Swift | 5.9 | Sep 2023 |
| Xcode | 15.0 | Sep 2023 |
Target Versions
Section titled βTarget Versionsβ| Component | Version | Notes |
|---|---|---|
| macOS | 14.0 - 15.x | Sonoma and later |
| Swift | 5.9+ | Latest stable |
| Xcode | 15.0+ | Latest stable |
Deprecated Support
Section titled βDeprecated Supportβ| Version | Deprecation Date | EOL Date |
|---|---|---|
| macOS 13 | N/A (never supported) | N/A |
Related Documentation
Section titled βRelated Documentationβ| Document | Description |
|---|---|
| Architecture | System architecture |
| Database Schema | Data models |
| Build System | Build configuration |
| Performance | Optimization |
Last updated: 2026-02-03