Skip to main content

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([], +)
    }
}
memorykeeper