Skip to content

CleanCocoa/swift-icalendar

Repository files navigation

swift-icalendar: Sample implementation of RFC 5545

For the formal specification, see RFC 5545 (there's a copy in this repository).

ics-lint

Demonstration of the package's capabilities: A command-line tool for validating iCalendar files against RFC 5545.

Installation

# 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 ...

Usage

# 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

Exit Codes

Code Meaning
0 Success (no errors; warnings allowed unless --strict)
1 Validation errors found
2 File not found or unreadable

Example Output

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

Library Usage

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)")
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages