A modern, Swift-native SDK for the RAWG Video Games Database API.
- β Complete API Coverage: Access to all RAWG API endpoints (games, platforms, genres, stores, creators, and more)
- π Type-Safe: Fully typed responses with Codable models and compile-time safe query filters
- β‘ Modern Swift: Built with async/await and AsyncSequence for clean, readable asynchronous code
- π― Actor-Based Networking: Thread-safe operations with Swift's actor model and request deduplication
- π± Cross-Platform: iOS 15+, macOS 13+, watchOS 8+, tvOS 15+, visionOS 1+
- π¨ Fluent Query Builder: Type-safe API with enums for platforms, genres, stores, and ordering
- π Auto-Pagination: Stream large result sets efficiently with AsyncSequence support
- πΎ Smart Caching: In-memory NSCache with TTL and automatic memory management
- π Automatic Retries: Configurable retry policy with exponential backoff for failed requests
- π Structured Logging: Built-in logging with os.Logger for debugging and monitoring
- π Comprehensive Documentation: Full DocC documentation with examples and best practices
- β¨ Strict Concurrency: Sendable-compliant for safe concurrent usage
- Swift 5.9+
- iOS 15.0+ / macOS 13.0+ / watchOS 8.0+ / tvOS 15.0+ / visionOS 1.0+
- Xcode 15.0+
Add RAWGKit to your project via Xcode:
- File β Add Packages...
- Enter package URL:
https://github.com/pespinel/RAWGKit - Select version and add to your target
Or add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/pespinel/RAWGKit", from: "1.0.0")
]- Visit https://rawg.io/apidocs
- Create an account or log in
- Get your free API key
import RAWGKit
// Initialize the client
let client = RAWGClient(apiKey: "your-api-key-here")
// Fetch popular games
let games = try await client.fetchGames(
pageSize: 10,
ordering: "-rating"
)
for game in games.results {
print("\(game.name) - Rating: \(game.rating)")
}
// Get game details
let gameDetail = try await client.fetchGameDetail(id: 3498)
print(gameDetail.description ?? "No description")
// Get screenshots
let screenshots = try await client.fetchGameScreenshots(id: 3498)
for screenshot in screenshots.results {
print(screenshot.image)
}// Type-safe query with enums (recommended)
let response = try await client.gamesQuery()
.search("witcher")
.orderByRating()
.year(2015)
.platforms([.pc, .playStation4, .xboxOne])
.genres([.rpg, .action])
.metacriticMin(80)
.pageSize(20)
.execute(with: client)
print("Found \(response.count) games")RAWGKit provides type-safe enums for common filters:
// Platforms
.platforms([.pc, .playStation5, .xboxSeriesX, .nintendoSwitch])
.parentPlatforms([.playStation, .xbox, .nintendo])
// Genres
.genres([.action, .rpg, .adventure, .shooter])
// Stores
.stores([.steam, .epicGames, .playStationStore, .nintendoStore])
// Ordering
.ordering(.metacriticDescending)
.ordering(.releasedDescending)// Games released this year
.releasedThisYear()
// Games from a specific date range
.releasedBetween(from: startDate, to: endDate)
// Games released in the last 30 days
.releasedInLast(days: 30)
// Games released after a date
.releasedAfter(someDate)
// Games released before a date
.releasedBefore(someDate)Automatically paginate through all results:
// Iterate through all games matching a query
for try await game in client.allGames(search: "zelda") {
print(game.name)
}
// Iterate through all genres
for try await genre in client.allGenres() {
print(genre.name)
}
// Also available: allPlatforms(), allDevelopers(), allPublishers(),
// allStores(), allTags(), allCreators()// Simple search
let results = try await client.fetchGames(
search: "The Witcher",
ordering: "-rating"
)
// Advanced search with query builder (recommended)
let filtered = try await client.gamesQuery()
.search("cyberpunk")
.searchExact()
.platforms([.pc])
.genres([.action])
.releasedBetween(from: startDate, to: endDate)
.metacritic(min: 80, max: 100)
.execute(with: client)// Get all genres
let genres = try await client.fetchGenres()
for genre in genres.results {
print("\(genre.name): \(genre.gamesCount ?? 0) games")
}
// Get genre details
let genreDetails = try await client.fetchGenreDetails(id: 4)
print(genreDetails.description ?? "")
// Get platforms
let platforms = try await client.fetchPlatforms()
// Get parent platforms (PlayStation, Xbox, PC, etc.)
let parentPlatforms = try await client.fetchParentPlatforms()
// Get developers
let developers = try await client.fetchDevelopers()
// Get developer details
let devDetails = try await client.fetchDeveloperDetails(id: 1)
// Get publishers
let publishers = try await client.fetchPublishers()
// Get stores
let stores = try await client.fetchStores()
// Get tags
let tags = try await client.fetchTags()let gameId = 3498 // GTA V
// Get full game details
let game = try await client.fetchGameDetail(id: gameId)
print(game.name)
print(game.description ?? "")
print("Rating: \(game.rating)")
print("Metacritic: \(game.metacritic ?? 0)")
// Get screenshots
let screenshots = try await client.fetchGameScreenshots(id: gameId)
// Get trailers/movies
let movies = try await client.fetchGameMovies(id: gameId)
// Get achievements
let achievements = try await client.fetchGameAchievements(id: gameId)
for achievement in achievements.results {
print("\(achievement.name): \(achievement.percent ?? "0")%")
}
// Get DLC and editions
let additions = try await client.fetchGameAdditions(id: gameId)
// Get games in the same series
let series = try await client.fetchGameSeries(id: gameId)
// Get development team
let team = try await client.fetchGameDevelopmentTeam(id: gameId)
// Get where to buy
let gameStores = try await client.fetchGameStores(id: gameId)
// Get Reddit posts
let redditPosts = try await client.fetchGameRedditPosts(id: gameId)// Get all creators
let creators = try await client.fetchCreators()
// Get creator details
let creator = try await client.fetchCreatorDetails(id: "78")
// Get creator roles/positions
let roles = try await client.fetchCreatorRoles()The main client for interacting with the RAWG API.
let client = RAWGClient(apiKey: "your-api-key")fetchGames(...)- Get a list of games with optional filtersfetchGameDetail(id:)- Get detailed game informationfetchGameScreenshots(id:page:pageSize:)- Get game screenshotsfetchGameMovies(id:)- Get game trailersfetchGameAdditions(id:page:pageSize:)- Get DLC and editionsfetchGameSeries(id:page:pageSize:)- Get games in the same seriesfetchGameParentGames(id:page:pageSize:)- Get parent gamesfetchGameDevelopmentTeam(id:page:pageSize:)- Get development teamfetchGameStores(id:page:pageSize:)- Get store linksfetchGameAchievements(id:)- Get achievementsfetchGameRedditPosts(id:)- Get Reddit postsfetchGameTwitchStreams(id:page:pageSize:)- Get Twitch streamsfetchGameYouTubeVideos(id:page:pageSize:)- Get YouTube videos
fetchGenres(page:pageSize:ordering:)- Get all genresfetchGenreDetails(id:)- Get genre details
fetchPlatforms(page:pageSize:ordering:)- Get all platformsfetchPlatformDetails(id:)- Get platform detailsfetchParentPlatforms(page:pageSize:ordering:)- Get parent platforms
fetchDevelopers(page:pageSize:)- Get all developersfetchDeveloperDetails(id:)- Get developer details
fetchPublishers(page:pageSize:)- Get all publishersfetchPublisherDetails(id:)- Get publisher details
fetchStores(page:pageSize:ordering:)- Get all storesfetchStoreDetails(id:)- Get store details
fetchTags(page:pageSize:)- Get all tagsfetchTagDetails(id:)- Get tag details
fetchCreators(page:pageSize:)- Get all creatorsfetchCreatorDetails(id:)- Get creator detailsfetchCreatorRoles(page:pageSize:)- Get creator roles
Basic game information for list views.
Detailed game information including description, ratings, platforms, genres, developers, publishers, and more.
Resource models with basic information and game counts.
Related content models.
You can order results using the ordering parameter:
"name"- Sort by name (A-Z)"-name"- Sort by name (Z-A)"released"- Sort by release date (oldest first)"-released"- Sort by release date (newest first)"rating"- Sort by rating (lowest first)"-rating"- Sort by rating (highest first)"metacritic"- Sort by Metacritic score (lowest first)"-metacritic"- Sort by Metacritic score (highest first)"added"- Sort by date added to RAWG"-added"- Sort by date added to RAWG (newest first)
do {
let games = try await client.fetchGames()
// Handle success
} catch NetworkError.unauthorized {
print("Invalid API key")
} catch NetworkError.rateLimitExceeded(let message) {
print("Rate limit: \(message)")
} catch {
print("Error: \(error.localizedDescription)")
}The free tier has rate limits:
- Be respectful of the API
- Cache responses when possible
- Consider upgrading for higher limits
- β Free for personal use (with attribution)
- β Free for commercial use (<100k MAU or <500k page views/month)
- β No cloning the RAWG website
- π Attribution required: Link to RAWG.io
See RAWG API Terms for full details.
- iOS 15.0+ / macOS 13.0+ / watchOS 8.0+ / tvOS 15.0+
- Swift 5.9+
- Xcode 15.0+
RAWGKit includes smart caching with automatic memory management:
// Caching is enabled by default
let client = RAWGClient(apiKey: "your-api-key")
// Disable caching if needed
let clientNoCache = RAWGClient(apiKey: "your-api-key", cacheEnabled: false)
// Clear cache manually
await client.clearCache()
// Get cache statistics
let stats = await client.cacheStats()
print("Cached entries: \(stats.totalEntries)")Features:
- NSCache-based: Automatic eviction under memory pressure
- TTL support: Entries expire after 5 minutes by default
- Thread-safe: Safe to use from any thread/task
RAWGKit is designed for optimal performance and reliability:
Prevents duplicate simultaneous requests to the same URL, reducing API quota usage and improving performance:
// Multiple concurrent calls to the same endpoint
// Only makes ONE actual network request
async let games1 = client.fetchGameDetail(id: 3328)
async let games2 = client.fetchGameDetail(id: 3328)
let (result1, result2) = try await (games1, games2)Configurable retry policy with exponential backoff for transient failures:
- Retries on network timeouts, connection losses, and server errors (5xx)
- Respects
Retry-Afterheaders for rate limiting - Default: 3 retries with exponential backoff
- Does NOT retry on client errors (4xx) or decoding errors
All network operations use Swift's actor model for thread safety:
- Prevents data races and synchronization issues
- Safe concurrent access from multiple tasks
- No need for locks or dispatch queues
Built-in logging with os.Logger for debugging and monitoring:
- Network requests and responses
- Cache hits and misses
- Decoding errors with JSON output
- Performance metrics
RAWGKit maintains high code quality standards with automated tooling and comprehensive tests:
- 113+ tests with Swift Testing framework
- Unit tests for all core components
- Integration tests with real API
- AsyncSequence pagination tests
- Concurrency and actor isolation tests
- 100% test pass rate on CI
- SwiftLint: Enforces Swift style and conventions (strict mode)
- SwiftFormat: Automatic code formatting in pre-commit hooks
- Strict Concurrency Checking: Enabled for maximum safety
- Continuous Integration: Automated testing on macOS 13 & 14
The project uses GitHub Actions for:
- β Linting (SwiftLint)
- β Formatting (SwiftFormat)
- β Testing on multiple macOS versions
- β Code coverage reporting
Contributions are welcome! Please read our Contributing Guide for details on our development process, code style, and how to submit pull requests.
- Set up your development environment:
# Install tools and git hooks
make setupOr manually:
brew install swiftlint swiftformat
make install-hooks- The project includes a
Makefilewith helpful commands:
make help # Show all available commands
make setup # Install tools and git hooks
make lint # Run SwiftLint
make format # Run SwiftFormat
make test # Run tests
make pre-commit # Format, lint, and test
make check # Run all checks (CI simulation)# Run all checks
make pre-commit
# Or run CI simulation
make checkThe CI will also run these checks on your PR.
MIT License - see LICENSE file for details
- Data provided by RAWG.io
- Built with β€οΈ using Swift
Check out the Examples/ directory for comprehensive usage examples:
- BasicUsage.swift - Client initialization, fetching games, searching, error handling, caching
- AdvancedQueries.swift - Query builder, filtering, date ranges, complex queries
- AsyncSequences.swift - Streaming large datasets, pagination, task cancellation
- π RAWG API Documentation
- π Report Issues
- π¬ Discussions