// ProofMode iOS Integration Example
// This file shows how to integrate the ProofMode library into your iOS app
import Foundation
import UIKit
import SwiftUI
// MARK: - Basic ProofMode Integration
class ProofModeManager: ObservableObject {
private let proofMode = ProofMode()
@Published var isInitialized = false
@Published var proofs: [String] = []
// Initialize ProofMode with your configuration
func initialize() async {
do {
let documentsPath = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask).first!
let storagePath = documentsPath.appendingPathComponent("proofs").path
try proofMode.initialize(
storagePath: storagePath,
email: "user@example.com",
passphrase: "secure_passphrase"
)
await MainActor.run {
isInitialized = true
}
} catch {
print("Failed to initialize ProofMode: \(error)")
}
}
// Generate proof for image data
func generateProof(for imageData: Data,
description: String? = nil,
location: CLLocation? = nil) async -> String? {
guard isInitialized else {
print("ProofMode not initialized")
return nil
}
do {
var metadata: [String: String] = [:]
if let description = description {
metadata["description"] = description
}
if let location = location {
metadata["latitude"] = "\(location.coordinate.latitude)"
metadata["longitude"] = "\(location.coordinate.longitude)"
metadata["altitude"] = "\(location.altitude)"
metadata["accuracy"] = "\(location.horizontalAccuracy)"
}
let proofHash = try proofMode.generateProof(
mediaData: imageData,
metadata: metadata.isEmpty ? nil : metadata
)
await MainActor.run {
proofs.append(proofHash)
}
return proofHash
} catch {
print("Failed to generate proof: \(error)")
return nil
}
}
// Verify a proof
func verifyProof(_ hash: String) async -> Bool {
guard isInitialized else { return false }
do {
return try proofMode.verifyProof(hash: hash)
} catch {
print("Failed to verify proof: \(error)")
return false
}
}
}
// MARK: - Camera Integration Example
struct CameraView: UIViewControllerRepresentable {
@Binding var capturedImage: UIImage?
@Environment(\.presentationMode) var presentationMode
func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
picker.sourceType = .camera
picker.allowsEditing = false
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: CameraView
init(_ parent: CameraView) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
parent.capturedImage = image
}
parent.presentationMode.wrappedValue.dismiss()
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
parent.presentationMode.wrappedValue.dismiss()
}
}
}
// MARK: - Location Provider Implementation
class LocationProvider: NSObject, ObservableObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
@Published var currentLocation: CLLocation?
@Published var authorizationStatus: CLAuthorizationStatus = .notDetermined
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func requestPermission() {
locationManager.requestWhenInUseAuthorization()
}
func startLocationUpdates() {
guard authorizationStatus == .authorizedWhenInUse ||
authorizationStatus == .authorizedAlways else {
requestPermission()
return
}
locationManager.startUpdatingLocation()
}
func stopLocationUpdates() {
locationManager.stopUpdatingLocation()
}
// MARK: - CLLocationManagerDelegate
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
authorizationStatus = manager.authorizationStatus
if authorizationStatus == .authorizedWhenInUse ||
authorizationStatus == .authorizedAlways {
startLocationUpdates()
}
}
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.last
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print("Location error: \(error)")
}
}
// MARK: - Complete SwiftUI Example
struct ProofGenerationView: View {
@StateObject private var proofMode = ProofModeManager()
@StateObject private var locationProvider = LocationProvider()
@State private var capturedImage: UIImage?
@State private var showCamera = false
@State private var showImagePicker = false
@State private var description = ""
@State private var isGeneratingProof = false
@State private var lastProofHash: String?
@State private var showAlert = false
@State private var alertMessage = ""
var body: some View {
NavigationView {
VStack(spacing: 20) {
// Image Display
if let image = capturedImage {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxHeight: 300)
.cornerRadius(12)
} else {
RoundedRectangle(cornerRadius: 12)
.fill(Color.gray.opacity(0.3))
.frame(height: 300)
.overlay(
Text("No image selected")
.foregroundColor(.gray)
)
}
// Description Input
TextField("Description (optional)", text: $description)
.textFieldStyle(RoundedBorderTextFieldStyle())
// Action Buttons
HStack(spacing: 15) {
Button("Take Photo") {
showCamera = true
}
.buttonStyle(.borderedProminent)
Button("Choose Photo") {
showImagePicker = true
}
.buttonStyle(.bordered)
}
// Generate Proof Button
Button(action: generateProof) {
HStack {
if isGeneratingProof {
ProgressView()
.scaleEffect(0.8)
}
Text(isGeneratingProof ? "Generating..." : "Generate Proof")
}
}
.buttonStyle(.borderedProminent)
.disabled(capturedImage == nil || isGeneratingProof || !proofMode.isInitialized)
// Status Display
if let hash = lastProofHash {
VStack {
Text("Proof Generated")
.font(.headline)
.foregroundColor(.green)
Text("Hash: \(hash.prefix(16))...")
.font(.caption)
.foregroundColor(.secondary)
}
.padding()
.background(Color.green.opacity(0.1))
.cornerRadius(8)
}
Spacer()
}
.padding()
.navigationTitle("ProofMode")
.sheet(isPresented: $showCamera) {
CameraView(capturedImage: $capturedImage)
}
.sheet(isPresented: $showImagePicker) {
ImagePicker(selectedImage: $capturedImage)
}
.alert("ProofMode", isPresented: $showAlert) {
Button("OK") { }
} message: {
Text(alertMessage)
}
.onAppear {
setupProofMode()
}
}
}
private func setupProofMode() {
Task {
await proofMode.initialize()
}
locationProvider.requestPermission()
}
private func generateProof() {
guard let image = capturedImage,
let imageData = image.jpegData(compressionQuality: 0.8) else {
showAlert(message: "No image data available")
return
}
isGeneratingProof = true
Task {
let hash = await proofMode.generateProof(
for: imageData,
description: description.isEmpty ? nil : description,
location: locationProvider.currentLocation
)
await MainActor.run {
isGeneratingProof = false
if let hash = hash {
lastProofHash = hash
showAlert(message: "Proof generated successfully!\nHash: \(hash)")
} else {
showAlert(message: "Failed to generate proof")
}
}
}
}
private func showAlert(message: String) {
alertMessage = message
showAlert = true
}
}
// MARK: - Image Picker Helper
struct ImagePicker: UIViewControllerRepresentable {
@Binding var selectedImage: UIImage?
@Environment(\.presentationMode) var presentationMode
func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
picker.sourceType = .photoLibrary
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
parent.selectedImage = image
}
parent.presentationMode.wrappedValue.dismiss()
}
}
}
// MARK: - App Integration Notes
/*
To integrate this into your app:
1. Add the ProofMode XCFramework to your project
2. Copy the generated Swift bindings
3. Add the required permissions to Info.plist:
- NSCameraUsageDescription
- NSPhotoLibraryUsageDescription
- NSLocationWhenInUseUsageDescription
4. Initialize ProofMode early in your app lifecycle:
```swift
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
// Initialize ProofMode
}
}
}
}
```
5. Handle background processing if needed:
- Add background modes capability
- Handle app lifecycle events
- Implement proper cleanup
6. Consider security:
- Store PGP keys securely (Keychain)
- Validate user permissions
- Handle sensitive data appropriately
- Implement proper error recovery
*/