SwiftQuery

0.1.3

Brings TanStack Query (sort of) to Swift so that you can manage Combine operations effectively.
Kajatin/SwiftQuery

What's New

0.1.3

2025-03-08T20:08:22Z

Full Changelog: 0.1.2...0.1.3

SwiftQuery

SwiftQuery is a lightweight, Combine-based query and mutation library for Swift, designed to simplify data fetching and caching while supporting automatic revalidation.

Features

  • 📦 Declarative API – Define queries and mutations with ease.
  • 🔄 Automatic Revalidation – Keep your data fresh with built-in refetching.
  • ❌ Query Invalidations – Invalidate and refetch queries programmatically.
  • ⏳ Retry Mechanism – Automatically retry failed requests.
  • 🚀 Optimized for SwiftUI – Uses @Observable for seamless UI updates.

Installation

SwiftQuery is available via Swift Package Manager (SPM).

Add via Xcode:

  1. Open your project and go to File > Add Package Dependencies...
  2. Enter the package URL: https://github.com/Kajatin/SwiftQuery
  3. Choose "Up to Next Major Version" and click Add Package.

Add via Package.swift:

dependencies: [
    .package(url: "https://github.com/Kajatin/SwiftQuery.git", from: "0.1.0")
]

Usage

You can pass in any Combine compatible query function to be wrapped by Query. A simple example using SwiftUI would be:

import Combine
import SwiftUI
import SwiftQuery

struct UserView: View {
    struct User: Codable, Identifiable {
        let id: Int
        let name: String
    }

    let query = Query<[User]>(
        queryKey: .init(["users"]),
        queryFn: {
            URLSession.shared
                .dataTaskPublisher(for: URL(string: "https://jsonplaceholder.typicode.com/users")!)
                .tryMap { data, response in
                    guard let httpResponse = response as? HTTPURLResponse,
                        (200..<300).contains(httpResponse.statusCode)
                    else { throw URLError(.badServerResponse) }
                    return data
                }
                .decode(type: [User].self, decoder: JSONDecoder())
                .receive(on: DispatchQueue.main)
                .eraseToAnyPublisher()
        }
    )

    var body: some View {
        VStack {
            if userQuery.isLoading {
                ProgressView()
            } else if userQuery.isError {
                Text("Failed to fetch user")
            } else if let user = userQuery.data {
                Text("Hello, \(user.name)!")
            }
        }
    }
}

#Preview {
  UserView()
}

Documentation

The full API documentation is available on the Swift Package Index: SwiftQuery Documentation

Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.

License

This project uses the MIT license.

Description

  • Swift Tools 6.0.0
View More Packages from this Author

Dependencies

  • None
Last updated: Thu May 15 2025 12:37:33 GMT-0900 (Hawaii-Aleutian Daylight Time)