Releases: jonathanspiva/zplkit
Releases · jonathanspiva/zplkit
Release list
ZPLKit 1.0.0
First public release.
Breaking changes
These affect anyone who built against pre-release code:
- The
ZPLVerifiermodule (product) was renamed toZPLKitVerifier. Update imports toimport ZPLKitVerifier. The entry type is still namedZPLVerifier. ZPLVerifier.analyze(_:)and theverify(...)overloads are nowasync throws(migrated to the Swift-native Vision API).ZPLKitVerifier's expectation types were renamedText→TextExpectationand
Barcode→BarcodeExpectation, soTextno longer collides withZPLKit.Text
when both modules are imported for the build → render → verify workflow.- Minimum platforms are iOS 26 / macOS 26 / tvOS 26 / watchOS 26, and Swift 6.3
is required (swift-tools-version: 6.3). An earlier pre-release targeted 27 /
Swift 6.4; the floor was lowered so the package installs on a shipping
toolchain rather than a beta OS. Nothing in the library needed the higher
floor: the Swift-native Vision API shipped in iOS 18 / macOS 15, and
NetworkConnectionis macOS 26. - Removed the inert
dpi:parameter fromZPLRenderer.render(_:)and
renderToPNG(_:). Output dimensions are derived from the label's^PW/^LL
dot values, so the parameter never had any effect. ZPLRenderer.renderToPNG(_:)returns aPNGRenderResultstruct instead of a
(data:metrics:)tuple. A tuple return type can never gain a member, so it
would have been frozen at 1.0.- Removed five public error cases that nothing ever threw:
PrinterError.printerNotFound/.receiveFailed,VerifierError.unexpected,
andZPLRendererError.parseError/.unsupportedCommand. They documented
conditions that could not occur, and deleting them after 1.0 would be a break.
ZPLParser.parsekeepsthrowsfor future use. CGImage.pngData()andCoreGraphicsRendererare now internal. The former is
a retroactive extension on a system type, which collides with the same
extension anywhere else in a consumer's dependency graph; the latter is
unreachable in practice (ParsedLabelhas no public initializer) and kept the
internal parse-to-draw pipeline frozen. UseZPLRenderer.render(_:).ZPLTemplate.render(with:)is nowrender(substituting:), matching
ZPLLabel;DataMatrix.size(_:)is nowmoduleSize(_:), matching
moduleWidth(_:)/magnification(_:)on its siblings.PrinterConfiguration.fieldRotationis a typedFieldRotationenum instead of
aString, and its cases spell the same asZPLKit.Rotation
(.normal/.rotated90/.inverted/.rotated270).VerifierError.visionErrorwas removed (no consumers).
Added
ZPLKit (Label Generation)
- Declarative Swift API using result builders for building ZPL labels
- Text elements:
Text,TextBlockwith fonts, rotation, reverse print, baseline positioning - 1D Barcodes:
Barcode128,Code39,EAN13,EAN8,UPCA,UPCE,Interleaved2of5 - 2D Barcodes:
QRCode,DataMatrix,PDF417,Aztec,IntelligentMail - Shapes:
Box,Circle,Ellipse,HorizontalLine,VerticalLine,DiagonalLine - Graphics:
Graphicelement for embedding CGImage content, with dithering (Floyd-Steinberg, Atkinson) and aspect-fill cropping - Utilities:
Comment,SerialNumberfor label metadata and sequential numbering - Label configuration: print quantity, print speed, darkness, reverse print, label home
- Template substitution:
{{variable}}syntax for dynamic label content - Printer commands:
PrinterCommandenum for~WL,~JC,~JR,~JA - Type system:
DPI,Dimension,Position,Rotation,ZPLFonttypes - Full Swift 6 concurrency support with
Sendableconformance on all types - Protocol conformances:
Codable,Equatable,Hashable,CustomStringConvertible
ZPLKitRenderer (Parsing & Rendering)
- Native Swift ZPL parser supporting all major commands
- CoreGraphics-based rendering engine for PNG output
- Bundled Roboto Condensed Bold font for accurate Font 0 rendering
- Barcode rendering: Code128, Code39, EAN-13/8, UPC-A/E, Interleaved 2 of 5, QR, Aztec, PDF417
- Parser sub-modules:
BarcodeParser,ShapeParser,TextParser,GraphicParser ^GFgraphic decoding: binary (^GFB), ASCII run-length compression in^GFA(repeat-count letters,,/!row fills,:row repeat), and^GFC:B64:/:Z64:(zlib) formats- Hex character decoding (
^FHwith_XXsequences) - Render metrics: parse time, render time, image dimensions
ZPLKitPrinter (Network Printing)
ZPLPrinter: Send ZPL to printers via TCP (port 9100)ZPLPrinterBrowser: LAN discovery via Zebra's UDP broadcast protocol (port 4201)DiscoveredPrinter: Printer metadata from network discovery- Two-way communication:
query()method for bidirectional printer queries - Status queries:
queryStatus()for~HS(Host Status) response parsing - Printer info:
queryInfo()for~HI(Host Identification) response parsing - Memory status:
queryMemory()for~HM(Host Memory) response parsing - Configuration:
PrinterConfigurationwith type-safe enums, presets, andapply/setupmethods - Diagnostics: combined status, info, memory, and settings in one call
- Test pages:
printConfigurationLabel(),printNetworkConfigLabel() - Structured response types:
PrinterStatus,PrinterInfo,MemoryStatus - Async/await API with configurable connection and response timeouts, plus an idle timeout for automatic connection cleanup
ZPLKitVerifier (Label Verification)
- Barcode detection via Vision framework (Code128, QR, Code39, EAN-13, Aztec, PDF417, etc.), covering all 24 Vision symbologies
- Text OCR via the Swift-native
RecognizeTextRequest - Discovery mode:
analyze()to discover all barcodes and text in an image - Assertion mode:
verify()with a declarative expectations DSL - Expectation types:
Barcode(symbology, exactly/containing:),Text(exactly/containing:) - Vision hints optimization for faster detection
- Bounds/clipping detection for edge content
- Result types:
AnalysisResult,VerificationResult,DetectedBarcode,DetectedText
Test Fixtures
- 125 ZPL fixture files covering text, barcodes, shapes, and graphics
fixtures.jsonmetadata with descriptions, categories, features, expected barcodes- Reference images from Labelary for comparison
- Visual test harness with HTML comparison output
- Renderer accuracy scoring (90.5% baseline vs Labelary)
Documentation
- DocC documentation for all public types
- Getting Started guide with full API reference
- Test Fixtures guide for parser/renderer validation
- README with quick start examples
Quality
- Unit and integration tests across all modules
- GitHub Actions CI with visual comparison artifacts
- MIT license
Changed
ParsedLabel/ParsedElementand the otherParsed*types are documented as
part of the public, semver-stable API, with doc comments on every property.
ParsedElementmay still gain cases in minor releases, so switch over it with
adefault.BarcodeSymbologyis not@frozen, so future Vision symbologies can be added
without a source break (switch over it with adefaultcase).Expectationprovides a defaultvisionHints, so future protocol
requirements will not break external conformers.PrinterConfiguration.networkConfig(...)/dhcp()(the^NSpath) are
documented as experimental / not hardware-verified: a static-IP change via
^NSP+~JRwas observed not to take effect on a GX420t (V56), so the
emitted command shape and reset sequence are still unconfirmed. Use with
caution and a recoverable printer.- Adopted Swift 6.2's "approachable concurrency" upcoming-feature flags via a shared
swiftSettingsblock applied to every first-party target:NonisolatedNonsendingByDefaultandInferIsolatedConformances. (InferSendableFromCapturesis already enabled by default in Swift 6 language mode, so it is intentionally not enabled explicitly.) Default isolation remainsnonisolated; the package is a library and does not force callers onto the main actor. ZPLVerifier.analyze/verifytiming now usesContinuousClock; the reported*TimeSecondsfields are documented as wall-clock (including time suspended atawait).- Set
swiftLanguageModes: [.v6]explicitly in the manifest. - Migrated
ZPLVerifierto the Swift-native Vision API (DetectBarcodesRequest,RecognizeTextRequest,ImageRequestHandler), replacing the legacyVN-prefixed completion-handler API. ZPLVerifiernow runs barcode and text recognition concurrently (async let), roughly halving analysis latency.- Removed the
Awesomedependency (and theGraphicsTestdev tool that used it); the library now has zero external dependencies. - The README documents which ZPL commands the preview renderer implements, and
what the four unimplemented ones (^LR,^CI,^CC/^CT, raw-binary
^GFB) do on a printer versus in the preview. - CI builds the package at its advertised floor on a GitHub-hosted
macos-26
runner (Xcode 26.6 / Swift 6.3) with-warnings-as-errors, which also gives
fork PRs a CI signal. The self-hosted runner additionally covers the visual
comparison and the opt-in live-printer job, gated behind a minimum accuracy
score and per-job timeouts.
Fixed
Label generation
^BYmodule width is now emitted by every 1-D barcode (Code39,EAN13,
EAN8,UPCA,UPCE, joiningBarcode128/Interleaved2of5), and all expose
amoduleWidth(_:)modifier. Previously a preceding barcode's module width
could leak in via^BYstickiness.EAN13/EAN8/UPCAnow reject a fully-specified value whose trailing check
digit doesn't match the computed one, instead of letting the printer silently
re-derive a different digit.- Template substitution corrupted Code 128 payloads. Inside a
^BCfield a
literal>is an invocation...