Snowflake

April 7, 2026 · View on GitHub

SVG rendering in Swift using native CALayer and UIBezierPath.

Requirements

  • iOS 16+
  • Swift 6

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/onmyway133/Snowflake", from: "3.0.0")
],
targets: [
    .target(
        name: "YourApp",
        dependencies: ["Snowflake"]
    )
]

Or in Xcode: File → Add Package Dependencies and enter the repository URL.

Usage

Document

Create a Document from SVG data:

guard let path = Bundle.main.path(forResource: "xmas", ofType: "svg"),
      let data = try? Data(contentsOf: URL(fileURLWithPath: path)),
      let document = Document(data: data) else { return }

let view = document.svg.view(size: CGSize(width: 100, height: 100))

The rendering pipeline is: SVG element → Shape → UIBezierPath → CALayer

Shapes

Each SVG element maps to a typed Item subclass:

SVG elementSwift type
pathPath
circleCircle
lineLine
polygonPolygon
polylinePolyline
rectRectangle
ellipseEllipse
textText
imageImage

Style

Style attributes are read from both inline attributes and the style attribute:

<!-- Inline attributes -->
<polygon points="100,10 40,198 190,78 10,78 160,198"
         fill="lime" stroke="purple" stroke-width="5" fill-rule="evenodd" />

<!-- style attribute -->
<polygon points="100,10 40,198 190,78 10,78 160,198"
         style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" />

Animation

Because Snowflake renders to CAShapeLayer, all layer properties are animatable:

let animator = Animator()

(svgView.layer.sublayers as? [CAShapeLayer])?.forEach { layer in
    animator.animate(layer: layer)
}

Or build your own:

(svgView.layer.sublayers as? [CAShapeLayer])?.forEach { layer in
    let stroke = CABasicAnimation(keyPath: "strokeEnd")
    stroke.fromValue = 0
    stroke.toValue = 1
    stroke.duration = 3
    layer.add(stroke, forKey: nil)
}

Layers and Scaling

Get scaled CALayer objects directly:

let layers = document.svg.layers(size: CGSize(width: 200, height: 100))

Get a UIView scaled to a given size:

let view = document.svg.view(size: CGSize(width: 100, height: 100))

Image

Supports base64 Data URI embedded images:

<image x="0" y="0" width="100" height="100" href="data:image/png;base64,..."/>

Author

Khoa Pham, onmyway133@gmail.com

License

Snowflake is available under the MIT license. See the LICENSE file for more info.