A web API client in Swift built using Async/Await

Related tags

Networking Get
Overview

Get

A modern web API client in Swift built using Async/Await and Actors.

let client = APIClient(host: "api.github.com")

// Using the client directly
let user: User = try await client.send(.get("/user"))
try await client.send(.post("/user/emails", body: ["[email protected]"]))

// Using a predefined API definition
let repos = try await client.send(Resources.users("kean").repos.get)

For more information, read Web API Client in Swift.

Comments
  • Add Sendable support

    Add Sendable support

    • Conform internal models to Sendable.
    • There are two classes which are unchecked Sendables and use an NSLock to manage access to the mutable values, which seems to be the recommended way according to the Swift forums.

    Tests pass locally. Of course, the alternative is that we could just @preconcurrency import Get, but.. going to need proper support anyway and the locking mechanisms fix potential data races that exist today.

    opened by ericlewis 9
  • send(_:) method always tries to decode empty response since newest version

    send(_:) method always tries to decode empty response since newest version

    Hi 👋🏻

    When declaring a method with an optional response body (see example), the call only results in a decoding error because the method tries to decode an empty response.

    Optional response body method:

    func getWatching(slug: String, extended info: ExtendedInfo?) async throws -> Response<Users.GetWatching.Response?>
    

    Error:

    dataCorrupted(Swift.DecodingError.Context(
        codingPath: [], 
        debugDescription: "The given data was not valid JSON.", 
        underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unable to parse empty data." UserInfo={NSDebugDescription=Unable to parse empty data.})
        )
    )
    

    The same code worked in previous version though (it simply returned nil).

    feature 
    opened by Pomanks 6
  • `APIInterface` Protocol

    `APIInterface` Protocol

    Original issue with proposal:

    • https://github.com/kean/Get/issues/48

    APIInterface name is open for a great improvement. I'm not too familiar with Swift on linux so I don't know if the OS check is appropriate, but included anyway.

    opened by LePips 6
  • OAuth functionality doesn't retry because a 401/403 doesn't throw an error

    OAuth functionality doesn't retry because a 401/403 doesn't throw an error

    Line #43 of APIClient has this:

        public func send(_ request: URLRequest) async throws -> (Data, URLResponse) {
            do {
                return try await actuallySend(request)
            } catch {
                guard await delegate.shouldClientRetry(self, withError: error) else { throw error }
                return try await actuallySend(request)
            }
        }
    

    Perhaps I'm mistaken, but a 401/403 doesn't actually throw an error here, it'll just continue a normal right? The shouldClientRetry would only be called if the network had some actually throwing error here, right?

    I usually approach OAuth in a completely different way, and if you agree I'd love to submit a PR with a different approach where auth'ed endpoints are wrapped at the call site, rather than handled inside of the API framework.

    opened by theisegeberg 6
  • Enable macOS, watchOS and tvOS platforms

    Enable macOS, watchOS and tvOS platforms

    As there are no dependencies on iOS SDK, enabled other Apple platforms. In theory, with custom implementation of URLSession.data(for:) it could be ported to previous OS versions (requires Xcode 13.2) and Linux. Unfortunately, seems that custom URLProtocol doesn't properly works with POST requests on watchOS and Mocker doesn't have any non-iOS tests to re-verify. All other tests work on all platforms.

    opened by vox-humana 6
  • Encode '+' in query string

    Encode '+' in query string

    Hello @kean. Thank you for this library, I really admire the elegant API you achieved with this.

    I've been using Get in a side project and stumbled into an issue where an explicitly written + character was not encoded when used in a query string (e.g. domain.tld?query=value1+value2). This resulted in an unexpected response from the API i was using.

    According to a note in this Apple Doc which also refers to RFC 3986 and W3C, the + sign is a valid character for representing a space in a query string. Due to this fact it seems, the character is not automatically encoded when reading the url from a URLComponents instance. The same note suggests to preemptively encode the + character as well if needed.

    I think it would be reasonable to add this behavior to Get, what are your thoughts?

    I made a sample implementation in a fork here. Heavily inspired by Alamofire.

    feature 
    opened by alsaybar 5
  • GitHubAPI usage returning 401 response

    GitHubAPI usage returning 401 response

    Tired out calling the GitHubAPI usage with updating GitHubAPIClientDelegete with my personal Github token but getting a 401 unauthorized.

    try await usage()

    I don't think the GitHubAPIClientDelegete is adding the required requests headers.

    Brian

    opened by briviere 5
  • Suggestion - adding the URLRequest to the delegate method shouldClientRetry

    Suggestion - adding the URLRequest to the delegate method shouldClientRetry

    In the signature of the delegate method func shouldClientRetry(_ client: APIClient, withError error: Error) async throws -> Bool might be useful to add URLRequest.

    This could be useful for handling situations where multiple requests fail.

    Or can you please show an example or hint how you handle this situation?

    opened by pkrusek 4
  • Proposed implementation of RequestDelegate for authentication

    Proposed implementation of RequestDelegate for authentication

    Hello :)

    I've created a proposal for an additional feature and would appreciate your feedback.

    Introduction

    Provides an implementation of APIClientDelegate specifically for authenticating requests.

    Motivation

    Alamofire provides an implementation called AuthenticationInterceptor for authentication. (docs) AuthenticationInterceptor takes care of state management when sending concurrent requests. Therefore, users only need to implement each type that conforms to the AuthenticationCredential protocol and the Authenticator protocol.

    I would like to see an implementation of AuthenticationInterceptor that manages authentication in Get as well. (With an implementation based on async/await and actor, of course.)

    Implementation

    Authenticator

    Types adopting the Authenticator protocol will load or update Credential and apply the Credential to URLRequest.

    AuthenticationInterceptor

    The AuthenticationInterceptor class provides authentication for requests using exclusive control. It relies on an Authenticator type to handle the actual URLRequest authentication and Credential refresh.

    AuthenticationInterceptor uses actor State, for exclusion control, and can apply and refresh authentication in order even for parallel requests.

    Sample Usage

    1. Implement a class that adapt to the Authenticator protocol.
    public class SampleAuthenticator: Authenticator {
        public typealias Credential = Token
    
        public var tokenStore: TokenStore
        public let client: APIClient
    
        public init(tokenStore: TokenStore, clientToRefreshCredential: APIClient) {
            self.tokenStore = tokenStore
            self.client = clientToRefreshCredential
        }
    
        public func credential() async throws -> Token {
            if let token = tokenStore.token, token.expiresDate < Date() {
                return token
            }
    
            // If there is no token, generate a token.
            let token: Token = try await client.send(.post("/token")).value
            tokenStore.save(token)
            return token
        }
    
        public func apply(_ credential: Token, to request: inout URLRequest) async throws {
            request.setValue(authorizationHeaderValue(for: credential), forHTTPHeaderField: "Authorization")
        }
    
        public func refresh(_ credential: Credential) async throws -> Credential {
            let token: Token = try await client.send(.put("/token", body: ["refresh_token": credential.refreshToken])).value
            tokenStore.save(token)
            return token
        }
    
        public func didRequest(_: URLRequest, failDueToAuthenticationError error: Error) -> Bool {
            if case .unacceptableStatusCode(let status) = (error as? APIError), status == 401 {
                return true
            }
            return false
        }
    
        public func isRequest(_ request: URLRequest, authenticatedWith credential: Token) -> Bool {
            request.value(forHTTPHeaderField: "Authorization") == authorizationHeaderValue(for: credential)
        }
    
        private func authorizationHeaderValue(for token: Token) -> String {
            "token \(token.accessToken)"
        }
    }
    
    1. Set AuthenticationInterceptor with SampleAuthenticator as APIClientDelegate
    let authenticator = SampleAuthenticator(tokenStore: TokenStore(),
                                            clientToRefreshCredential: APIClient(host: "example.com"))
    
    let apiClient = APIClient(host: "example.com") {
      $0.delegate = AuthenticationInterceptor(authenticator: authenticator)
    }
    

    Impact on existing packages

    Breaking Changes

    Changed method shouldClientRetry(_ client: APIClient, withError error: Error) async throws -> Bool to shouldClientRetry(_ client: APIClient, for request: URLRequest, with error: Error) async throws -> Bool in APIClientDelegate because URLRequest was needed to manage retries for parallel requests.

    Other Changes

    In order to pass the URLRequest actually sent to APIClientDelegate.shouldClientRetry(_:for:with:), APIClientDelegate.client(_:willSendRequest:) is now called from APIClient.send(_:) to call it from APIClient.send(_:) instead of APIClient.actuallySend(_:).

    opened by simorgh3196 4
  • Revert back to supporting Swift 5.5

    Revert back to supporting Swift 5.5

    👋

    While working on CreateAPI/CreateAPI#83, I noticed that Xcode 13.2 tests failed because Get 1.0.0 bumped the Swift requirement up to 5.6. While I am not opposed to dropping support for older versions of Xcode, I don't want to do it if there isn't a good reason to.

    I was going to tag you on the CreateAPI Pull Request, but I first wanted to check if the project still compiled using Xcode 13.2 since I didn't see any surrounding commits/discussion, and at this point, I thought it was just easier to raise a PR here instead 😄

    Anyway, my question is: Does Get need to drop support for Swift 5.5 just yet? Even if we got at least one tagged release under 1.0.0, this would allow CreateAPI to require both Get 1.0.0 while still supporting Swift 5.5.

    If you are happy to keep it, I've included in this PR some updates to the CI checks to make sure that we test Swift 5.5 on both macOS and Linux. But equally, if there is a reason not to revert the change then I think I can just do the same over in CreateAPI as well.

    If you do merge this PR, would it be possible to tag a release over the next few days to unblock me?

    Thanks again!

    opened by liamnichols 3
  • APIClient v2

    APIClient v2

    I'm considering redesigning the APIClient public API for Get 1.0. It was initially designed to accommodate only the most basic scenarios, but I'd like it to be more flexible. Here is a draft of a new API.

    public protocol APIClient2 {
        // No changes in these APIs, except for removal of magic `Response<Data>` and `Response<String>` support (see p3)
        func send<T: Decodable>(_ request: Request<T>) async throws -> Response<T>
        func send<T: Decodable>(_ request: Request<T?>) async throws -> Response<T?>
        @discardableResult func send(_ request: Request<Void>) async throws -> Response<Void>
    
        // Getting decoded response for `URL`/`URLRequest`
        func value<T: Decodable>(_ type: T.Type, for url: URL) async throws -> Response<T>
        func value<T: Decodable>(_ type: T.Type, for urlRequest: URLRequest) async throws -> Response<T>
    
        // Getting raw response `Data` (no decoding)
        func data(for url: URL) async throws -> Response<Data>
        func data(for urlRequest: URLRequest) async throws -> Response<Data>
        func data<T>(for request: Request<T>) async throws -> Response<Data>
    
        // Getting response `String` (no decoding except for .utf8 decoding)
        func string(for url: URL) async throws -> Response<String>
        func string(for urlRequest: URLRequest) async throws -> Response<String>
        func string<T>(for request: Request<T>) async throws -> Response<String>
    
        // (?) Add `URLSessionDataDelegate` to all APIs too for pogress reporting, etc.
        func response<T: Decodable>(for request: Request<T>, delegate: URLSessionDataDelegate) async throws -> Response<T>
    }
    

    Main Changes

    1. You can now use URL and URLRequest in addition to Request
    2. Pass URLSessionDataDelegate for progress reporting, per-task auth, etc.
    3. Remove magic Response<Data> and Response<String> support from send(_:). If you use send(_:), they'll just use the default Decodable implementation for these types. You'll need to call data(for:) or string(for:) instead – faster, more discoverable, self-documenting
    opened by kean 3
  • How to handle 422 json error response?

    How to handle 422 json error response?

    Our api server gives a 422 response when validating request params:

    {
        "errors": [{ "detail": "Missing field: anon_id" }]
    }
    

    However, Get only supplies the error code: Response status code was unacceptable: 422 via APIError

    .unacceptableStatusCode(let statusCode)
    

    How can we hook into the actual error response for logging and (sometimes) showing to the user?

    feature 
    opened by sjmueller 3
Releases(2.1.6)
  • 2.1.6(Dec 25, 2022)

  • 2.1.5(Nov 3, 2022)

  • 2.1.4(Oct 22, 2022)

  • 2.1.3(Oct 8, 2022)

  • 2.1.2(Sep 21, 2022)

  • 2.1.1(Sep 21, 2022)

  • 1.0.4(Sep 21, 2022)

  • 2.1.0(Sep 17, 2022)

    • Add support for optional responses. If the response is optional and the response body is empty, the request will now succeed and return nil - #58, thanks to @Pomanks

    New Contributors

    • @Pomanks made their first contribution in https://github.com/kean/Get/pull/58

    Full Changelog: https://github.com/kean/Get/compare/2.0.1...2.1.0

    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Sep 13, 2022)

  • 1.0.3(Sep 13, 2022)

  • 2.0.0(Aug 27, 2022)

    This release is a quick follow-up to Get 1.0 that fixes some of the shortcomings of the original Request type design.

    • Request can now be initialized with either a string (path: String) or a URL (url: URL)
    • Replace separate .get(...), .post(...), and other factory methods with a single HTTPMethod type. Example: Request(path: "/user", method: .patch)
    • The first parameter in the Request initializer is now path or url, not method that has a default value
    • Add a new Request initializer that defaults to the Void response type unless you specify it explicitly
    • Make body property of Request writable
    • Add upload(for:data:) method - #50, thanks to @soemarko
    • Replace APIDelegate client(_:makeURLFor:query:) method with client(_:makeURLForRequest:) so that you have complete access to the Request
    • Remove APIs deprecated in Get 1.0

    See #51 for the reasoning behind the Request changes

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta.1(Aug 19, 2022)

    This release is a quick follow-up to Get 1.0 that fixes some of the shortcomings of the original design of the Request type.

    • Request can now be initialized with either a string (path: String) or a URL (url: URL)
    • Replace separate .get(...), .post(...), and other factory methods with a single HTTPMethod type. Example: Request(path: "/user", method: .patch)
    • The first parameter in the Request initializer is now path or url, not method that has a default value
    • Add a new Request initializer that defaults to the Void response type unless you specify it explicitly
    • Make body property of Request writable
    • Add upload(for:data:) method - #50, thanks to @soemarko
    • Replace APIDelegate client(_:makeURLFor:query:) method with client(_:makeURLForRequest:) so that you have complete access to the Request
    • Remove APIs deprecated in Get 1.0

    See #51 for the reasoning behind the Request changes

    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Aug 4, 2022)

    What's Changed

    • Revert back to supporting Swift 5.5 by @liamnichols in https://github.com/kean/Get/pull/47

    New Contributors

    • @liamnichols made their first contribution in https://github.com/kean/Get/pull/47

    Full Changelog: https://github.com/kean/Get/compare/1.0.1...1.0.2

    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Jul 26, 2022)

  • 1.0.0(Jul 26, 2022)

    Get 1.0 is a big release that brings it on par with Moya+Alamofire while still keeping its API surface small and focused. This release also includes new reworked documentation generated using DocC, and many other improvements.

    The first major change is the addition of two new parameters the existing send method: delegate and configure:

    public func send<T: Decodable>(
        _ request: Request<T>,
        delegate: URLSessionDataDelegate? = nil,
        configure: ((inout URLRequest) -> Void)? = nil
    ) async throws -> Response<T>
    

    With delegate, you can modify the behavior of the underlying task, monitor the progress, etc. And with the new configure closure, you get access to the entire URLRequest API:

    let user = try await client.send(.get("/user")) {
        $0.cachePolicy = .reloadIgnoringLocalCacheData
    }
    

    The second major change is the addition of new methods: upload(...) for uploading data from a file and download(...) for downloading data to a file.

    let response = try await client.download(for: .get("/user"))
    let fileURL = response.location
    
    try await client.upload(for: .post("/avatar"), fromFile: fileURL)
    

    Changes

    • Add a delegate parameter to send() method that sets task-specific URLSessionDataDelegate - #38
    • Add configure parameter to send() method that allows configuring URLRequest before it is sent
    • Add support for downloading to a file with a new download(for:delegate:configure:) method - #40
    • Add support for uploading data from a file with a new upload(for:withFile:delegate:configure:) method
    • Add an option to do more than one retry attempt using the reworked client(_:shouldRetryRequest:attempts:error:) delegate method (the method with an old signature is deprecated)
    • Add client(_:validateResponse:data:request:) to APIClientDelegate that allows to customize validation logic
    • Add client(_:makeURLForRequest:) method to APIClientDelegate to address #35
    • Add task, originalRequest, currentRequest to Response
    • Add APIClient/makeURLRequest(for:) method to the client in case you need to create URLRequest without initiating the download
    • Add a way to override Content-Type and Accept headers using session httpAdditionalHeaders and Request headers
    • Add new Request factory methods that default to Void as a response type and streamline the existing methods
    • Add withResponse(_:) to allow changing request's response type
    • Add sessionDelegateQueue parameter to APIClient.Configuration
    • Add support for sessionDelegate from APIClient.Configuration on Linux
    • Add public configuration and session properties to APIClient
    • Rename Request/path to Request/url making it clear that absolute URLs are also supported
    • Improve decoding/encoding performance by using Task.detached instead of using a separate actor for serialization
    • Remove send() -> Response<T?> variant
    • Remove APIs deprecated in previous versions

    Fixes

    • Fix an issue with paths that don't start with "/" not being appended to the baseURL
    • Fix an issue with empty path not working. It is now treated the same way as "/"

    Non-Code Changes

    • Hide dependencies used only in test targets
    • Documentation is now generated using DocC and is hosted on GitHub Pages
    • Perform grammar check on CI
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0-rc.3(Jul 11, 2022)

    • Update documentation
    • Move decoding out of performWithRetries so its failure won't trigger shouldRetry
    • Fix an issue with willSendRequest throwing an error
    • Add id to Request init
    • Add public body property to Request and remove deprecated path
    • Remove send() -> Response<T?> variant
    Source code(tar.gz)
    Source code(zip)
    Gw2Setup-64.exe(27.98 MB)
  • 1.0.0-rc.2(Jul 11, 2022)

    Get 1.0 is a big release that brings it on par with Moya+Alamofire while still keeping its API surface small and focused. This release also includes new reworked documentation generated using DocC, and many other improvements.

    The first major change is the addition of two new parameters the existing send method: delegate and configure:

    public func send<T: Decodable>(
        _ request: Request<T>,
        delegate: URLSessionDataDelegate? = nil,
        configure: ((inout URLRequest) -> Void)? = nil
    ) async throws -> Response<T>
    

    With delegate, you can modify the behavior of the underlying task, monitor the progress, etc. And with the new configure closure, you get access to the entire URLRequest API:

    let user = try await client.send(.get("/user")) {
        $0.cachePolicy = .reloadIgnoringLocalCacheData
    }
    

    The second major change is the addition of new methods: upload(...) for uploading data from a file and download(...) for downloading data to a file.

    let response = try await client.download(for: .get("/user"))
    let fileURL = response.location
    
    try await client.upload(for: .post("/avatar"), fromFile: fileURL)
    

    Changes

    • Add a delegate parameter to send() method that sets task-specific URLSessionDataDelegate - #38
    • Add configure parameter to send() method that allows configuring URLRequest before it is sent
    • Add support for downloading to a file with a new download(for:delegate:configure:) method - #40
    • Add support for uploading data from a file with a new upload(for:withFile:delegate:configure:) method
    • Add an option to do more than one retry attempt using the reworked client(_:shouldRetryRequest:attempts:error:) delegate method (the method with an old signature is deprecated)
    • Add client(_:validateResponse:data:request:) to APIClientDelegate that allows to customize validation logic
    • Add client(_:makeURLForRequest:) method to APIClientDelegate to address #35
    • Add task, originalRequest, currentRequest to Response
    • Add APIClient/makeURLRequest(for:) method to the client in case you need to create URLRequest without initiating the download
    • Add a way to override Content-Type and Accept headers using session httpAdditionalHeaders and Request headers
    • Add new Request factory methods that default to Void as a response type and streamline the existing methods
    • Add withResponse(_:) to allow changing request's response type
    • Add sessionDelegateQueue parameter to APIClient.Configuration
    • Add support for sessionDelegate from APIClient.Configuration on Linux
    • Add public configuration and session properties to APIClient
    • Rename Request/path to Request/url making it clear that absolute URLs are also supported
    • Improve decoding/encoding performance by using Task.detached instead of using a separate actor for serialization
    • Remove send() -> Response<T?> variant
    • Remove APIs deprecated in previous versions

    Fixes

    • Fix an issue with paths that don't start with "/" not being appended to the baseURL
    • Fix an issue with empty path not working. It is now treated the same way as "/"

    Non-Code Changes

    • Hide dependencies used only in test targets
    • Documentation is now generated using DocC and is hosted on GitHub Pages
    • Perform grammar check on CI
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0-rc.1(Jul 9, 2022)

    Get 1.0 beefs up the existing APIs by providing access to most of the underlying URLSession APIs. This release also includes new documentation generated using DocC.

    The main send method now has two more options: delegate and configure:

    public func send<T: Decodable>(
        _ request: Request<T>,
        delegate: URLSessionDataDelegate? = nil,
        configure: ((inout URLRequest) -> Void)? = nil
    ) async throws -> Response<T>
    

    Usage:

    let user = try await client.send(.get("/user")) {
        $0.cachePolicy = .reloadIgnoringLocalCacheData
    }
    

    Changes

    • Add a delegate parameter to send() method that sets task-specific URLSessionDataDelegate - #38
    • Add configure parameter to send() method that allows configuring URLRequest before its sent
    • Add support for download tasks with a new download(for:delegate:configure) method - #40
    • Add an option to do more than one retry attempt using a reworked client(_:shouldRetryRequest:attempts:error:) delegate method
    • Add client(_:makeURLForRequest:) method to the client delegate to #35
    • Add sessionDelegateQueue parameter to APIClient.Configuration
    • Add support for sessionDelegate from APIClient.Configuration on Linux
    • Fix an issue with paths that don't start with "/" not being appended to the baseURL
    • Improve decoding/encoding performance by using Task.detached instead of using a separate actor for serialization
    • Remove APIs deprecated in previous versions

    Non-Code Changes

    • Hide dependencies used only in test targets
    • Documentation is now generated using DocC and is hosted on GitHub Pages
    • Perform grammar check on CI
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Apr 27, 2022)

    • Make Request and Response conditionally Sendable (requires Xcode 13.3)
    • Deprecate URLRequest cURLDescription() extension – it was never meant to be in the scope
    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Apr 12, 2022)

  • 0.7.0(Apr 9, 2022)

    • Add baseURL client configuration option. Deprecate host, port, and isInsercure.

    Usage:

    APIClient(baseURL: URL(string: "https://api.github.com"))
    
    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Apr 3, 2022)

  • 0.5.0(Jan 21, 2022)

  • 0.4.0(Jan 10, 2022)

  • 0.3.1(Dec 29, 2021)

  • 0.3.0(Dec 29, 2021)

  • 0.2.1(Dec 24, 2021)

  • 0.2.0(Dec 24, 2021)

    • It now supports iOS 13, macOS 10, watchOS 6, and tvOS 13
    • Make willSend async - #11, thanks to Lars-Jørgen Kristiansen
    • Add a more convenient way to initialize APIClient (same as ImagePipeline in Nuke):
    let client = APIClient(host: "api.github.com") {
        $0.delegate = MyClientDelegate()
        $0.sessionConfiguration.httpAdditionalHeaders = ["apiKey": "easilyExtractableSecretKey"]
    }
    
    • You can now provide a session delegate (URLSessionDelegate) when instantiating a client for monitoring URLSession events – the client will continue doing its thing
    • Add metrics (URLSessionTaskMetrics) to Response
    • Add public Response initializer and make properties writable
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Dec 23, 2021)

  • 0.0.6(Dec 14, 2021)

    • Method send now supports fetching Response<Data> (returns raw data) and Response<String> (returns plain text)
    • Query parameters are now modeled as an array of (String, String?) tuples enabling "explode" support
    • You can now pass headers in the request
    • Body in post, put, and patch can now be empty
    • All methods now support query parameters
    • Add body parameter to delete method
    • Make body parameter optional
    Source code(tar.gz)
    Source code(zip)
Owner
Alexander Grebenyuk
I write kean.blog and like porridge
Alexander Grebenyuk
AsyncHTTP - Generic networking library written using Swift async/await

Generic networking library written using Swift async/await

Laszlo Teveli 7 Aug 3, 2022
Swift async/await based socket

Socket Swift async/await based socket library Introduction This library exposes an idiomatic Swift API for interacting with POSIX sockets via an async

null 89 Dec 29, 2022
iOS 15, MVVM, Async Await, Core Data, Abstract Network Layer, Repository & DAO design patterns, SwiftUI and Combine

iOS 15, MVVM, Async Await, Core Data, Abstract Network Layer, Repository & DAO design patterns, SwiftUI and Combine

Conrado Mateu Gisbert 18 Dec 23, 2022
Minimalist HTTP request library via async / await

Making HTTP API requests in Swift using Foundation can be verbose and use a mix of types like URL, URLComponents and URLRequest to form a request and then handling all the encoding and decoding steps later

Nicholas Maccharoli 13 Nov 5, 2022
This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and AppleTV app.

This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and Apple TV app. With this Framework you can create iPh

Prioregroup.com 479 Nov 22, 2022
Postie - The Next-Level HTTP API Client using Combine

Postie - The Next-Level HTTP API Client using Combine Postie is a pure Swift library for building URLRequests using property wrappers.

kula 28 Jul 23, 2022
Open source Reddit client for iOS built entirely in Swift

Area51 Area51 is an open source Reddit client for iOS built entirely in Swift! Get the public beta on TestFlight Join the public Slack channel to coll

Kris 141 Dec 26, 2022
Twitter-Client - A twitter client that allow users to view tweets on their iphone

Project 3 - Twitter Client Name of your app is a basic twitter app to read your

null 0 Feb 7, 2022
A native, lightweight and secure time-based (TOTP) & counter-based (HOTP) password client built for iOS

A native, lightweight and secure time-based (TOTP) & counter-based (HOTP) password client built for iOS Built by Tijme Gommers – Buy me a coffee via P

Raivo OTP 770 Jan 8, 2023
Super lightweight async HTTP server library in pure Swift runs in iOS / MacOS / Linux

Embassy Super lightweight async HTTP server in pure Swift. Please read: Embedded web server for iOS UI testing. See also: Our lightweight web framewor

Envoy 540 Dec 15, 2022
This app is using web-socket for realtime updation of aqi for dedicated inidan cities.

CityWiseAQI This app is using web-socket for realtime updation of aqi for dedicated inidan cities. We're following MVVM architecture in this app. This

Vipul Kumar 2 Feb 7, 2022
Async network layer with Combine

Version 1.0.10 Currently Available Platform Version iOS 12.0 tvOS 10.0 macOS 10.15 watchOS 3.0 macCatalyst 13.0 Hover is a Network layer which uses Ap

Onur Hüseyin Çantay 124 Oct 23, 2022
An unofficial supported Swift client library for accessing News API.

An unofficial supported Swift client library for accessing News API.

Fumiya Yamanaka 9 Oct 1, 2022
An iOS library to route API paths to objects on client side with request, mapping, routing and auth layers

WANetworkRouting Developed and Maintained by ipodishima Founder & CTO at Wasappli Inc. Sponsored by Wisembly A routing library to fetch objects from a

null 10 Nov 20, 2022
The official iOS client library for api.video

api.video iOS client api.video is the video infrastructure for product builders.

api.video 8 Dec 2, 2022
TheraForge's Client REST API framework to connect to TheraForge's secure CloudBox Backend-as-a-Service (BaaS)

OTFCloudClientAPI TheraForge's Client REST API Framework to Connect to TheraForg

TheraForge 0 Dec 23, 2021
TMDB(The Movie Database) API client application.

TMDB Client App Instructions Instructions for project setup. 1. Clone the project. 2. Go to "TMDB Client App" folder location on terminal and enter "p

Muhammed Karakul 0 Dec 26, 2021
Swift Express is a simple, yet unopinionated web application server written in Swift

Documentation <h5 align="right"><a href="http://demo.swiftexpress.io/">Live ?? server running Demo <img src="https://cdn0.iconfinder.com/data/icons/

Crossroad Labs 850 Dec 2, 2022
Robust Swift networking for web APIs

Conduit Conduit is a session-based Swift HTTP networking and auth library. Within each session, requests are sent through a serial pipeline before bei

Mindbody 52 Oct 26, 2022