MemoryKeeper
01 The Privacy Problem
Most photo apps sync everything to the cloud. MemoryKeeper takes a different approach - all processing happens on your device, keeping your memories truly private.
PhotoProcessor.swift
// Privacy-first architecture
struct PhotoProcessor {
private let mlModel: VNCoreMLModel
func analyzeLocally(_ image: UIImage) async -> [PhotoMetadata] {
// All ML inference runs on-device
let request = VNCoreMLRequest(model: mlModel)
return try await processRequest(request, for: image)
}
}
02 On-Device Intelligence
Core ML powers intelligent photo categorization, face recognition, and scene detection - all without sending a single byte to external servers.
SceneClassifier.swift
// Scene classification with Core ML
func classifyScene(in image: CIImage) -> SceneCategory {
let model = try? SceneClassifier(configuration: .init())
guard let output = try? model?.prediction(image: image) else {
return .unknown
}
return SceneCategory(rawValue: output.classLabel) ?? .unknown
}
03 SwiftUI Experience
A native SwiftUI interface that feels right at home on iOS, with smooth animations and intuitive gestures for browsing your photo library.
MemoryGridView.swift
struct MemoryGridView: View {
@StateObject private var viewModel: MemoryViewModel
var body: some View {
LazyVGrid(columns: columns, spacing: 2) {
ForEach(viewModel.memories) { memory in
MemoryCard(memory: memory)
.onTapGesture { viewModel.select(memory) }
}
}
.animation(.spring(), value: viewModel.memories)
}
}
04 Surfacing Memories
The app intelligently surfaces photos from years past, creating 'On This Day' collections that bring back forgotten moments.
MemoryService.swift
// Find memories from this day in history
func fetchMemories(for date: Date) async -> [Memory] {
let calendar = Calendar.current
let yearsBack = (1...10).map { years in
calendar.date(byAdding: .year, value: -years, to: date)!
}
return await withTaskGroup(of: [Memory].self) { group in
for targetDate in yearsBack {
group.addTask {
await self.photosFrom(date: targetDate)
}
}
return await group.reduce([], +)
}
}