ExtraDigits Documentation

Learn how to integrate +2 and +5 supplemental barcode scanning into your iOS and Android apps.

API Key Required

You'll need an active subscription to use ExtraDigits. Subscribe here to get your API key.

Installation

Swift Package Manager (iOS)

Add ExtraDigits to your Xcode project using Swift Package Manager:

Open Package Dependencies

In Xcode, go to File > Add Package Dependencies...

Enter Repository URL

Paste the following URL:

URL
https://github.com/extradigits/extradigits-ios.git

Select Version

Choose "Up to Next Major Version" and click Add Package.

CocoaPods (Alternative)

Add to your Podfile:

Ruby
pod 'ExtraDigits', '~> 1.2'

Quick Start

Get scanning in under 5 minutes with this minimal implementation:

Swift
import SwiftUI import ExtraDigits struct ContentView: View { @State private var scannedCode: String? var body: some View { VStack { ExtraDigitsner( apiKey: "ed_live_your_api_key_here" ) { result in switch result { case .success(let barcode): scannedCode = barcode.fullCode case .failure(let error): print("Scan error: \(error)") } } if let code = scannedCode { Text("Scanned: \(code)") .font(.headline) .padding() } } } }

iOS Project Setup

Camera Permission

Add camera usage description to your Info.plist:

XML
<key>NSCameraUsageDescription</key> <string>Camera access is required to scan barcodes</string>

Initialize the SDK

Initialize ExtraDigits early in your app lifecycle, typically in your App struct:

Swift
import SwiftUI import ExtraDigits @main struct MyApp: App { init() { // Initialize with your API key ExtraDigits.configure(apiKey: "ed_live_your_api_key_here") } var body: some Scene { WindowGroup { ContentView() } } }

Basic Scanning

The ExtraDigitsner view handles camera setup, permission requests, and barcode detection automatically.

Swift
struct ScannerView: View { @State private var isScanning = true @State private var lastBarcode: SupplementBarcode? var body: some View { ZStack { ExtraDigitsner( apiKey: "ed_live_your_api_key_here", isScanning: $isScanning, supplementTypes: [.ean2, .ean5] // Scan both types ) { result in switch result { case .success(let barcode): lastBarcode = barcode isScanning = false // Pause after successful scan // Haptic feedback let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.success) case .failure(let error): handleError(error) } } // Overlay with scan result if let barcode = lastBarcode { ResultOverlay(barcode: barcode) { lastBarcode = nil isScanning = true // Resume scanning } } } } func handleError(_ error: ScanError) { switch error { case .cameraUnavailable: print("Camera not available") case .permissionDenied: print("Camera permission denied") case .invalidApiKey: print("Invalid or expired API key") case .subscriptionInactive: print("Subscription is not active") default: print("Unknown error: \(error)") } } }

Customization

Customize the scanner appearance with the ScannerStyle configuration:

Swift
let customStyle = ScannerStyle( // Viewfinder appearance viewfinderColor: .white, viewfinderLineWidth: 3, viewfinderCornerRadius: 12, viewfinderSize: CGSize(width: 280, height: 100), // Scanning line animation showScanLine: true, scanLineColor: Color.red, // Background dimming overlayColor: Color.black.opacity(0.6), // Feedback enableHaptics: true, enableSoundFeedback: true, successSound: "scan_success" // Custom sound file ) ExtraDigitsner( apiKey: "ed_live_your_api_key_here", style: customStyle ) { result in // Handle result }

Handling Results

The SupplementBarcode object contains all scanned data:

Property Type Description
mainCode String The primary EAN-13 or UPC-A barcode
supplement String? The +2 or +5 supplemental code (nil if none)
supplementType SupplementType .ean2, .ean5, or .none
fullCode String Combined main + supplement code
timestamp Date When the barcode was scanned
Swift
func processBarcode(_ barcode: SupplementBarcode) { print("Main code: \(barcode.mainCode)") // Example: "012345678905" if let supplement = barcode.supplement { print("Supplement: \(supplement)") // Example: "12345" (for +5) or "09" (for +2) switch barcode.supplementType { case .ean2: // Magazine issue number let issueNumber = Int(supplement) ?? 0 print("Magazine issue #\(issueNumber)") case .ean5: // Could be price, issue, or variant info parseEAN5Supplement(supplement) case .none: break } } print("Full code: \(barcode.fullCode)") // Example: "012345678905-12345" } func parseEAN5Supplement(_ code: String) { // For books: First digit indicates currency, rest is price // 5 = USD, 6 = CAD, etc. let currencyCode = code.prefix(1) let priceValue = code.dropFirst() if currencyCode == "5" { let price = (Double(priceValue) ?? 0) / 100 print("Suggested price: $\(price)") } // For comics: Issue (3 digits) + Variant (1) + Print (1) if code.count == 5 { let issue = String(code.prefix(3)) let variant = code[code.index(code.startIndex, offsetBy: 3)] let printing = code.last! print("Issue: \(issue), Variant: \(variant), Print: \(printing)") } }

ISBN OCR Recognition

ExtraDigits includes powerful OCR capabilities to recognize ISBN numbers from text - no barcode required. ISBN-10 numbers are automatically converted to ISBN-13 format on the fly. This is perfect for cataloging older books, processing donations, or scanning damaged barcodes.

Included Free

ISBN OCR is included with your ExtraDigits subscription at no additional cost.

Basic ISBN OCR Usage

Use the ISBNScanner view for text-based ISBN recognition:

Swift
import ExtraDigits struct BookCatalogView: View { var body: some View { ISBNScanner( apiKey: "ed_live_your_api_key_here", mode: .textRecognition // OCR mode for printed/handwritten text ) { result in switch result { case .success(let isbn): print("Found ISBN: \(isbn.number)") print("Format: \(isbn.format)") // .isbn10 or .isbn13 print("Valid: \(isbn.isValid)") // Check digit validated case .failure(let error): print("Error: \(error)") } } } }

ISBN Scanner Modes

The ISBNScanner supports multiple scanning modes:

Mode Description Best For
.textRecognition OCR for printed ISBN text anywhere on page Copyright pages, title pages, older books
.handwriting Advanced OCR for handwritten ISBN numbers Inventory sheets, catalog cards, notes
.barcode Standard ISBN barcode scanning Books with Bookland EAN barcodes
.hybrid Combines barcode + text recognition Maximum flexibility, scans anything

Handling ISBN Results

The ISBNResult object provides validated ISBN data with automatic conversion options:

Swift
// Enable automatic ISBN-10 to ISBN-13 conversion ISBNScanner( apiKey: "ed_live_your_api_key_here", mode: .hybrid, autoConvertToISBN13: true // All results returned as ISBN-13 ) { result in // result.number is always 13 digits } func processISBN(_ isbn: ISBNResult) { // The raw ISBN number (digits only) let number = isbn.number // "9780134685991" // Formatted with hyphens let formatted = isbn.formatted // "978-0-13-468599-1" // Original format detected (before conversion) switch isbn.originalFormat { case .isbn10: print("Originally 10-digit, auto-converted to 13") case .isbn13: print("Already 13-digit ISBN") } // Check digit validation if isbn.isValid { // ISBN passed check digit verification lookupBookInfo(isbn: number) } else { // May be a misread - prompt user to verify showVerificationPrompt(isbn: number) } // Manual conversion methods (if autoConvert is off) let isbn13 = isbn.toISBN13() // Convert ISBN-10 to ISBN-13 let isbn10 = isbn.toISBN10() // Convert ISBN-13 to ISBN-10 (978 prefix only) // Source of the ISBN switch isbn.source { case .barcode: print("Scanned from barcode") case .printedText: print("Recognized from printed text") case .handwriting: print("Recognized from handwriting") } }

Android Project Setup

Now Available

The Android/Kotlin SDK is available via Gradle or Maven. Your subscription includes access to both platforms at no additional cost.

API Reference

ExtraDigitsner

The main SwiftUI view for barcode scanning.

Parameter Type Required Description
apiKey String Yes Your ExtraDigits API key
isScanning Binding<Bool> No Control scanning state programmatically
supplementTypes [SupplementType] No Types to scan. Default: [.ean2, .ean5]
style ScannerStyle No Custom appearance configuration
onResult Closure Yes Called with Result<SupplementBarcode, ScanError>

Supported Barcode Types

Type Format Common Uses
EAN-13 + 2 13 + 2 digits Magazines, periodicals (issue numbers)
EAN-13 + 5 13 + 5 digits Books (price), comics (issue/variant/print)
UPC-A + 2 12 + 2 digits US/Canada periodicals
UPC-A + 5 12 + 5 digits US/Canada books, weighted products

Troubleshooting

Invalid API Key Error

If you receive an invalidApiKey error:

Subscription Inactive Error

This error occurs when:

Visit your dashboard to update payment or reactivate.

Scanning Not Detecting Supplements

If the main barcode scans but supplements are missed:

Need Help?

Contact us at support@extradigits.dev for technical assistance.