Thorvg.swift
ThorVG for Swift (Apple System)
Install / Use
/learn @thorvg/Thorvg.swiftREADME
ThorVG for Swift
<p align="center"> <img width="800" height="auto" src="https://github.com/thorvg/thorvg.site/blob/main/readme/logo/512/thorvg-banner.png"> </pThorVG for Swift is a lightweight wrapper around the ThorVG C++ API, providing native support for vector graphics in Swift applications. This package currently only supports rendering Lottie animations and is actively evolving to include more features.
ThorVG Version: v0.14.7 (commit e3a6bf)
Supported Platforms: iOS 13.0+, macOS 10.15+
Contents
Installation
To integrate ThorVGSwift into your Swift project, use Swift Package Manager. Simply add the following line to the dependencies section of your Package.swift file:
dependencies: [
// ...
.package(url: "https://github.com/thorvg/thorvg.swift", from: "0.1.0")
]
Usage
This Swift wrapper currently only supports rendering Lottie animations. As the package evolves, additional support for more content types will be added.
ThorVGSwift provides two levels of API:
- Low-Level API: Direct access to the rendering engine for frame-by-frame control
- High-Level Views API: Ready-to-use SwiftUI and UIKit views with playback controls
Low-Level API (Direct Rendering)
The low-level API closely follows the structure of the original ThorVG API, enabling rendering of Lottie frames to a buffer. This is useful when you need fine-grained control over frame rendering.
To start, create a Lottie instance using a desired local file path.
let url = Bundle.main.url(forResource: "test", withExtension: "json")
let lottie = try Lottie(path: url.path)
If you only have the string data of the Lottie, you can use the alternate String initialiser.
let lottie = try Lottie(string: "...")
Next, initialise a buffer for ThorVG to draw Lottie frame data into.
let size = CGSize(width: 1024, height: 1024)
let buffer = [UInt32](repeating: 0, count: Int(size.width * size.height))
From here, initialise a LottieRenderer instance to handle the rendering of individual Lottie frames.
let renderer = LottieRenderer(
lottie,
size: size,
buffer: &buffer,
stride: Int(size.width),
pixelFormat: .argb
)
[!NOTE] You can use different pixel formats including
.argb,.rgba, etc. (see the complete list here).
By default, the LottieRenderer runs on the main thread. If needed, you can create a custom Engine with multiple threads.
let engine = Engine(numberOfThreads: 4)
let renderer = LottieRenderer(
lottie,
engine: engine,
size: size,
buffer: &buffer,
stride: Int(size.width),
pixelFormat: .argb
)
Once your LottieRenderer is set up, you can start rendering Lottie frames using the render function.
The render function takes three parameters:
frameIndex: the index of the frame to rendercontentRect: the area of the Lottie content to renderrotation(optional): the rotation angle to apply to the renderered frame
let contentRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
try renderer.render(frameIndex: 0, contentRect: contentRect, rotation: 0.0)
And voilà! Your buffer is now filled with the rendered Lottie frame data.
[!TIP] To render all of the frames in a
Lottieanimation, you can iterate through thenumberOfFramesproperty of theLottieclass.
High-Level Views API (SwiftUI & UIKit)
For most use cases, ThorVGSwift provides convenient view components that handle rendering, playback, and animation lifecycle automatically. All animation state is managed through the LottieViewModel, which you create externally and pass to the view.
SwiftUI
import SwiftUI
import ThorVGSwift
struct ContentView: View {
@StateObject private var viewModel: LottieViewModel
init() {
let lottie = try! Lottie(path: "animation.json")
let config = LottieConfiguration(loopMode: .loop, speed: 1.0)
// Size is optional - defaults to animation's intrinsic size
_viewModel = StateObject(wrappedValue: LottieViewModel(
lottie: lottie,
configuration: config
))
}
var body: some View {
LottieView(viewModel: viewModel)
.onAppear { viewModel.play() }
.onChange(of: viewModel.error) { _, error in
if let error = error {
print("Animation error: \(error)")
}
}
}
}
UIKit
import UIKit
import ThorVGSwift
class ViewController: UIViewController {
private var viewModel: LottieViewModel!
private var lottieView: LottieUIKitView!
override func viewDidLoad() {
super.viewDidLoad()
let lottie = try! Lottie(path: "animation.json")
let config = LottieConfiguration(loopMode: .loop, speed: 1.0)
// Size is optional - defaults to animation's intrinsic size
viewModel = LottieViewModel(
lottie: lottie,
configuration: config
)
lottieView = LottieUIKitView(viewModel: viewModel)
// Observe animation errors
lottieView.onError = { error in
print("Animation error: \(error)")
}
view.addSubview(lottieView)
// Add constraints...
viewModel.play()
}
}
Features
The high-level Views API provides:
- ✅ ViewModel-Based State: All animation state managed through
LottieViewModel - ✅ Flexible Sizing: Optional
sizeparameter - defaults to animation's intrinsic dimensions - ✅ Playback Control: Loop modes (playOnce, loop, repeat, autoReverse) and speed adjustment
- ✅ Content Modes: Aspect fit and aspect fill scaling options
- ✅ Progress Tracking: Monitor playback progress and state via published properties
- ✅ Error Handling: Built-in error reporting through Combine publishers
- ✅ Manual Controls: Play, pause, stop, and seek to specific frames or progress
- ✅ Performance Optimized: Reusable CGContext and efficient buffer management
- ✅ Sample App: Interactive iOS app demonstrating all features
Note: Try the ThorVGSampleApp - a standalone iOS app with all examples! Just open
ThorVGSampleApp/ThorVGSampleApp.xcodeprojand run. Learn more →
📖 View Complete Views API Documentation →
The full documentation includes:
- Detailed API reference for
LottieView,LottieUIKitView, andLottieViewModel - Configuration options and best practices
- Complete usage examples and integration patterns
- Testing strategies and troubleshooting guides
Build
For Package Users
Simply add the package dependency to your Package.swift - releases include pre-built XCFramework binaries and require no additional build steps.
dependencies: [
.package(url: "https://github.com/thorvg/thorvg.swift", from: "0.1.0")
]
For Local Development & Contributors
Contributors need to build the XCFramework locally, as it's not included in the repository (only in release tags).
Prerequisites
- Xcode with command-line tools installed
- Meson and Ninja build tools:
brew install meson ninja
Building the XCFramework
Before building the Swift package, generate the ThorVG XCFramework:
# Clone with submodules
git clone --recursive https://github.com/thorvg/thorvg.swift
cd thorvg.swift
# Build the XCFramework (required for local development)
./scripts/build_frameworks.sh
The build script will:
- Automatically detect your Xcode installation and SDK paths
- Build ThorVG for macOS (arm64 + x86_64), iOS (arm64), and iOS Simulator (arm64)
- Create
ThorVG.xcframeworkcontaining all platform binaries - Generate a standalone macOS library in
lib/for local development
Build outputs:
ThorVG.xcframework/- Multi-platform framework (gitignored, only in releases)lib/libthorvg.a- Standalone macOS library (gitignored)
Building the Swift Package
Once the XCFramework is built, you can build and test the Swift package:
swift build # Build the package
swift test # Run tests
Creating a Release
Maintainers can create releases with pre-built binaries:
# This builds the XCFramework and creates a release commit + tag
./scripts/release.sh 0.1.0
See docs/CONTRIBUTING.md for complete release instructions and docs/RELEASE_POLICY.md for the full release policy.
[!NOTE] The build script uses ThorVG's native Meson build system instead of Swift Package Manager compiling C++ directly. This approach simplifies maintenance and ensures consistent builds across platforms.
[!TIP] If you're on an Intel Mac and want x86_64 simulator support, you can modify
scripts/build_frameworks.shto include both architectures for the simulator. By default, only arm64 is built for simulator (Intel Macs can use it via Rosetta 2).
Contributi
Related Skills
node-connect
343.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
92.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
343.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
343.3kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
