For the formal specification, see RFC 5545 (there's a copy in this repository).
Demonstration of the package's capabilities: A command-line tool for validating iCalendar files against RFC 5545.
# Build from source
swift build -c release
# The binary is at .build/release/ics-lint
# Optionally copy to your PATH:
cp .build/release/ics-lint /usr/local/bin/To build and run immediately:
swift run ics-lint ...# Validate a file
ics-lint calendar.ics
# Validate multiple files
ics-lint *.ics
# Show context lines (like ripgrep): 1 before, 2 after
ics-lint -B 1 -A 2 calendar.ics
# JSON output for CI/tooling
ics-lint --format json calendar.ics
# Strict mode: treat warnings as errors
ics-lint --strict calendar.ics
# Quiet mode: only show errors
ics-lint --quiet calendar.ics
# Auto-fix safe issues and output corrected ICS
ics-lint --fix calendar.ics > fixed.ics| Code | Meaning |
|---|---|
| 0 | Success (no errors; warnings allowed unless --strict) |
| 1 | Validation errors found |
| 2 | File not found or unreadable |
calendar.ics - 0 errors, 2 warnings
WARNING line 9: PRIORITY value 15 is out of range (0-9); clamped to 9
│
9│ PRIORITY:15
│
in VEVENT → PRIORITY
WARNING line 10: SUMMARY value has leading whitespace; trimmed
│
10│ SUMMARY: Leading whitespace test
│
in VEVENT → SUMMARY
─────────────────────────────────────────────────────────────────
Summary: 1 VCALENDAR, 1 VEVENT | 0 errors, 2 warnings
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/your-org/swift-icalendar", from: "1.0.0"),
]Parse and validate:
import swift_icalendar
let ics = """
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example//EN
BEGIN:VEVENT
UID:event@example.com
DTSTAMP:20250115T080000Z
DTSTART:20250115T090000Z
SUMMARY:Team Meeting
END:VEVENT
END:VCALENDAR
"""
let output = try VCalendar.parseWithDiagnostics(ics)
let calendar = output.value
let diagnostics = output.diagnostics
for event in calendar.events {
print(event.summary?.value ?? "No title")
}
for diagnostic in diagnostics {
print("\(diagnostic.severity): \(diagnostic.message)")
}