Last updated: July 12, 2026
Snap & Summon is designed to work locally on your device. The developer does not collect, transmit, sell, or share personal data from the app.
Snap & Summon uses the camera when you choose to photograph something. You may
| func playAHAP(_ name: String) { | |
| guard | |
| let engine = try? CHHapticEngine(), | |
| let url = Bundle.main.url(forResource: name, withExtension: "ahap") | |
| else { return } | |
| try? engine.start() | |
| let player = try? engine.makePlayer(with: CHHapticPattern(contentsOf: url)) | |
| try? player.start(atTime: CHHapticTimeImmediate) | |
| } |
| let event = CHHapticEvent( | |
| eventType: .hapticContinuous, | |
| parameters: [ | |
| CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0), | |
| CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0), | |
| ], | |
| relativeTime: 0, | |
| duration: 60 | |
| ) |
| override func layoutSubviews() { | |
| super.layoutSubviews() | |
| let filter = (NSClassFromString("CAFilter") as! NSObject.Type) | |
| .perform(NSSelectorFromString("filterWithType:"), with: "variableBlur")! | |
| .takeUnretainedValue() as! NSObject | |
| filter.setValue(20, forKey: "inputRadius") | |
| filter.setValue(makeMaskImage(), forKey: "inputMaskImage") | |
| filter.setValue(true, forKey: "inputNormalizeEdges") |
| private final class VariableBlurUIView: UIVisualEffectView { | |
| override func layoutSubviews() { | |
| super.layoutSubviews() | |
| let filter = (NSClassFromString("CAFilter") as! NSObject.Type) | |
| .perform(NSSelectorFromString("filterWithType:"), with: "variableBlur")! | |
| .takeUnretainedValue() as! NSObject | |
| filter.setValue(20, forKey: "inputRadius") | |
| filter.setValue(makeMaskImage(), forKey: "inputMaskImage") |
| struct ProgressiveBlurView: UIViewRepresentable { | |
| func makeUIView(context: Context) -> UIVisualEffectView { | |
| VariableBlurUIView(effect: UIBlurEffect(style: .light)) | |
| } | |
| func updateUIView(_ view: UIVisualEffectView, context: Context) {} | |
| } |
| func makeUIView(context: Context) -> UIVisualEffectView { | |
| let view = UIVisualEffectView(effect: UIBlurEffect(style: .light)) | |
| let filter = (NSClassFromString("CAFilter") as! NSObject.Type) | |
| .perform(NSSelectorFromString("filterWithType:"), with: "variableBlur")! | |
| .takeUnretainedValue() as! NSObject | |
| filter.setValue(20, forKey: "inputRadius") | |
| view.subviews.first?.layer.filters = [filter] | |
| return view | |
| } |
| struct ProgressiveBlurView: UIViewRepresentable { | |
| func makeUIView(context: Context) -> UIVisualEffectView { | |
| UIVisualEffectView(effect: UIBlurEffect(style: .light)) | |
| } | |
| func updateUIView(_ view: UIVisualEffectView, context: Context) { | |
| view.effect = UIBlurEffect(style: .light) | |
| } | |
| } |
| struct ProgressiveBlurView: UIViewRepresentable { | |
| func makeUIView(context: Context) -> UIVisualEffectView { | |
| UIVisualEffectView(effect: UIBlurEffect(style: .systemThinMaterialLight)) | |
| } | |
| func updateUIView(_ view: UIVisualEffectView, context: Context) { | |
| view.effect = UIBlurEffect(style: .systemThinMaterialLight) | |
| } | |
| } |