A SwiftUI-based camera app with video recording, sharing, playback, and deletion functionalities.
Available on the AppStore now!





SwiftUI: For building the user interface. AVFoundation: For camera and video recording functionalities. Swift-Concurrency: For reactive programming and handling data flow. MVVM: Application architecture. UIKit: Lightweight integrations with existing UIKit views.
The swift-sharing library makes it possible to easily preview the app in different states - such as when a user is missing specific permissions.

AVCaptureVideoPreviewLayer allows you to connect the camera to the UI. The app uses compiler directives to let you preview the camera directly in SwiftUI previews.

Swift structured concurrency is used to create a timer that increments every second. Swift-issue-reporting is used to provide an unimplemented closure to execute once the timer is finished.

A custom swift-navigation view-modifier was created to drive the overlay thru a binding.

PhotoKit allows you to work with image & video assets that the photos app mangages. Main
model listens for changes and caches them to shared state, for the Library
feature to observe.
final class MainModel {
...
func task() async {
await withThrowingTaskGroup(of: Void.self) { taskGroup in
taskGroup.addTask {
let photosContext = try await self.fetchOrCreateAssetCollection(
withTitle: PhotosContext.title
)
await MainActor.run {
self.$photosContext.assetCollection.withLock {
$0 = photosContext
}
}
for await fetchResult in await self.photos.streamAssets(
.videos(in: photosContext)
) {
await self.syncVideos(with: fetchResult)
}
}
}
}
VideoPlayer
model allows you to handle all the logic for the video player.
@MainActor
@Observable
final class VideoPlayerModel {
let video: PhotosContext.Video
...
@CasePathable
enum Destination {
case share(ActivityModel)
}
}
UIActivityViewController allows you to present the share sheet dynamically, such as when a user taps a button. A SwiftUI view modifier was created to let you model the destination without dropping down to UIKit.
@MainActor
@Observable
final class ActivityModel: Identifiable {
let id: UUID
let activityItems: [UIActivityItemProvider]
let applicationActivities: [UIActivity]
var completionWithItemsHandler: UIActivityViewController
.CompletionWithItemsHandler
}