Skip to content

Instantly share code, notes, and snippets.

@dillonhafer
Created August 11, 2025 13:08
Show Gist options
  • Save dillonhafer/2e67ca66f43e5972187b4c83f893a5c9 to your computer and use it in GitHub Desktop.
Save dillonhafer/2e67ca66f43e5972187b4c83f893a5c9 to your computer and use it in GitHub Desktop.
QR Code inspector app for macOS
import SwiftUI
import AppKit
internal import UniformTypeIdentifiers
struct ContentView: View {
@State var isPresented: Bool = false
@State var image: Data?
@State var message: String = ""
var body: some View {
VStack {
if let imageData = image {
if let ns = NSImage(data: imageData) {
Image(nsImage: ns)
.resizable()
.frame(width: 200, height: 200)
}
}
if message.count > 0 {
VStack {
Text(message)
.selectionDisabled(false)
Button(action: {
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setString(message, forType: .string)
}) {
HStack {
Text("Copy")
}
}
}
}
Button(action: {
isPresented = true
}) {
HStack {
Text("Choose file")
}
.fileImporter(isPresented: $isPresented, allowedContentTypes: [.image], onCompletion: { result in
switch result {
case .success(let url):
readFile(url)
case .failure:
}
})
}
}
}
func readFile(_ url: URL) {
message = "No QR Code found"
do {
if url.startAccessingSecurityScopedResource() {
image = try Data(contentsOf: url)
let context = CIContext()
let options: [String: Any] = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
guard let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: context, options: options) else {
return
}
if let data = image {
if let ciImage = CIImage(data: data) {
let features = detector.features(in: ciImage)
for feature in features {
if let qrCodeFeature = feature as? CIQRCodeFeature,
let messageString = qrCodeFeature.messageString {
message = messageString
}
}
}
}
}
} catch {
}
url.stopAccessingSecurityScopedResource()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment