Type-safe networking abstraction layer that associates request type with response type.

Related tags

Networking APIKit
Overview

APIKit

Build Status codecov Carthage compatible Version Platform Swift Package Manager

APIKit is a type-safe networking abstraction layer that associates request type with response type.

// SearchRepositoriesRequest conforms to Request protocol.
let request = SearchRepositoriesRequest(query: "swift")

// Session receives an instance of a type that conforms to Request.
Session.send(request) { result in
    switch result {
    case .success(let response):
        // Type of `response` is `[Repository]`,
        // which is inferred from `SearchRepositoriesRequest`.
        print(response)

    case .failure(let error):
        self.printError(error)
    }
}

Requirements

  • Swift 5.0 or later
  • iOS 8.0 or later
  • Mac OS 10.10 or later
  • watchOS 2.0 or later
  • tvOS 9.0 or later

If you use Swift 2.2 or 2.3, try APIKit 2.0.5.

If you use Swift 4.2 or before, try APIKit 4.1.0.

Installation

Carthage

  • Insert github "ishkawa/APIKit" ~> 5.0 to your Cartfile.
  • Run carthage update.
  • Link your app with APIKit.framework in Carthage/Build.

CocoaPods

  • Insert pod 'APIKit', '~> 5.0' to your Podfile.
  • Run pod install.

Note: CocoaPods 1.4.0 is required to install APIKit 5.

Documentation

Advanced Guides

Migration Guides

Comments
  • Redesign for Swift 2

    Redesign for Swift 2

    Swift 2 is coming! I think redesigning APIKit for Swift 2 is necessary to take full advantage of it.

    • protocol extension makes Reuqest protocol more flexilble.
    • ErrorType is useful to express errors in APIKit.
    • do-try-catch introduced easier error handling model (if process is synchronous).

    Here are tasks:

    • [x] Move default configuration of request to extension of Request.
    • [x] Detailed and comprehensive errors using ErrorType.
    • [x] Adopt do-try-catch in synchronous error handling.

    Any comments are welcome.

    opened by ishkawa 25
  • [WIP] Add mechanism to intercept requests

    [WIP] Add mechanism to intercept requests

    This PR implements a mechanism to intercept each requests for following purposes:

    • Insert common operations before/after each requests.
    • Manage network indicator visibility.

    An interceptor type looks like below:

    class MyRequestInterceptor: RequestInterceptorType {
        func interceptBeforeRequest<T: RequestType>(request: T) {
            /* To be called before each requests */
        }
    
        func interceptAfterRequest<T: RequestType>(request: T, result: Result<T.Response, APIError>) {
            /* To be called after each requests */
        }
    }
    

    Then, append its instance to requestInterceptors of an instance of Session:

    let session = /* Get the session to add interceptors. */
    session.requestInterceptors.append(interceptor)
    
    enhancement 
    opened by ishkawa 12
  • Provide instance to give a change to implement delegate methods of NSURLSession

    Provide instance to give a change to implement delegate methods of NSURLSession

    Users of APIKit may want to implement delegate methods of NSURLSession to hook events or to handle authentication challenge, so I think we have to provide instances for each subclasses of API and re-implement wrapper of NSURLSession using delegate methods (not block). Currently, an instance of API subclass is provided as a singleton because I would like to keep interface simple and multiple clients are not necessary for one web API.

    @ikesyo how do you think?

    opened by ishkawa 11
  • Question about custom interception/retry functionality

    Question about custom interception/retry functionality

    Hey there,

    I have a specific requirement for my app that I'm working on. The API web service uses JSON Web Tokens. It requires me to pass in a valid x-session-token header for each protected API endpoint.

    These session tokens expire every 24h, which means I need to reauthenticate and retry my existing request. Is that currently possible with APIKit? I've seen some PRs about interceptors for version 2.0 but I'm not sure if that's what I need.

    Here's an example of what I mean: Let's say I need to call the GET /user endpoint of my API and it requires me to pass in a valid x-session-token in the header. If the token has expired, I will get an error response, something like this:

    success: false, error: {
        code = E1100;
        hint = Token;
        message = "Session token has expired.";
    }
    

    Now whenever I get an error response with the error.code == "E1100", what I want to do is, automatically call the POST /authenticate_session endpoint, get the new session token and automatically retry the GET /user request with the updated x-session-token header.

    Can you point me in the right direction of how I could best implement this with APIKit?

    I'm currently using a different API library for my app and it's proving to be a pain (I'm literally at the point of where I'm trying to fight and go against how the framework was intended to work). Before I start implementing my API logic from scratch, I'm exploring my options and would like to research if I could accomplish this functionality requirement using APIKit (or any other open source library).

    Thanks for your help.

    opened by jyounus 9
  • Unable to send [Int] value as a parameter

    Unable to send [Int] value as a parameter

    以下のようなリクエストを送っています。 idsというkeyでInt型のArrayを送信したいのですが、パラメータが["(\n 672,\n 669\n)"]こういった形になってしまします。 やり方が悪いのでしょうか...? 何卒よろしくお願いします。

    struct deleteImage: UserImageRequestType {
                typealias Response = Bool
    
                let ids:        [Int]
                let method    = HTTPMethod.DELETE
                var path:       String { return "/v1/user_images/delete" }
                var parameters: [String: AnyObject] { return ["ids": ids] }
    
                func responseFromObject(object: AnyObject, URLResponse: NSHTTPURLResponse) -> Response? {
                     ...
            }
    }
    
    opened by yukitoto 8
  • Carthage issue

    Carthage issue

    Hi, When i use APIKit with Carthage i get some errors, this is my Cartfile github "ishkawa/APIKit" ~> 1.0

    first issue is that it checks out as Checking out APIKit at "1.0.0-beta5" and i think the problem is that you changed beta5 to point style (beta.6) so it always checks out at beta5 and the second issue is that i get this error: A shell task failed with exit code 128: fatal: reference is not a tree: 2e38ee3e7a3e1dd01be31edb94368c2f4a840915

    opened by MarvinNazari 8
  • Upload Progress

    Upload Progress

    Sorry if i ask too many question here, wonder if there is any way we could get a progress when we upload a file like Alamofire upload method. Thanks 👍

    opened by MarvinNazari 7
  • Fix parameter type from [String:AnyObject] to [String:AnyObject?] for nullable value.

    Fix parameter type from [String:AnyObject] to [String:AnyObject?] for nullable value.

    Fixed parameter handling when its value is null.

    For example, there are some scenarios when some_api?query=&page=1 should be replaced as some_api?query&page=1 (no query=).

    opened by inamiy 7
  • [Q] `xcodebuild` with Swift Package Failed

    [Q] `xcodebuild` with Swift Package Failed

    Hi

    Recently we are trying the use SwiftPackage of APIKit into our project. After importing, Xcode build successfully but the xcodebuild command part failed.

    By looking into the log, since APIKit have this code:

    #if SWIFT_PACKAGE
        class AbstractInputStream: InputStream {
            init() {
                super.init(data: Data())
            }
        }
    #endif
    

    and the overriding & super related code failed. It looks like it cannot be archive the correct super one.

    I would be appreciate if you could tell me how we could fix it.

    Best regards

    Here is the script of the failed log:

    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:170:22: property does not override any property from its superclass
    
            override var hasBytesAvailable: Bool {
                                          ^~~~~~~~~~~~~~
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:174:23: method does not override any method from its superclass
    
            override func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength: Int) -> Int {
            ~~~~~~~~     ^
    
    
    
    ❌  SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:127:37: use of undeclared type 'AbstractInputStream'
    
        internal class PartInputStream: AbstractInputStream {
            ~~~~~~~~      ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:259:22: property does not override any property from its superclass
    
            override var streamStatus: Stream.Status {
                                        ^~~~~~~~~~~~~~~~~~~
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:263:22: property does not override any property from its superclass
    
            override var hasBytesAvailable: Bool {
            ~~~~~~~~     ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:267:23: method does not override any method from its superclass
    
            override func open() {
            ~~~~~~~~     ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:271:23: method does not override any method from its superclass
    
            override func close() {
            ~~~~~~~~      ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:275:23: method does not override any method from its superclass
    
            override func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength: Int) -> Int {
            ~~~~~~~~      ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:315:22: property does not override any property from its superclass
    
            override var delegate: StreamDelegate? {
            ~~~~~~~~      ^
    
    
    
    ❌ SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:320:23: method does not override any method from its superclass
    
            override func schedule(in aRunLoop: RunLoop, forMode mode: RunLoop.Mode) {
            ~~~~~~~~     ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:324:23: method does not override any method from its superclass
    
            override func remove(from aRunLoop: RunLoop, forMode mode: RunLoop.Mode) {
            ~~~~~~~~      ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:215:42: use of undeclared type 'AbstractInputStream'
    
        internal class MultipartInputStream: AbstractInputStream {
            ~~~~~~~~      ^
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:51:33: cannot convert value of type 'MultipartFormDataBodyParameters.MultipartInputStream' to expected argument type 'InputStream'
    
                return .inputStream(inputStream)
                                             ^~~~~~~~~~~~~~~~~~~
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:54:48: cannot convert value of type 'MultipartFormDataBodyParameters.MultipartInputStream' to expected argument type 'InputStream'
    
                return .data(try Data(inputStream: inputStream))
                                    ^~~~~~~~~~~
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:154:13: 'super' members cannot be referenced in a root class
    
                super.init()
                                                   ^~~~~~~~~~~
    
    
    
    ❌  /SourcePackages/checkouts/APIKit/Sources/APIKit/BodyParameters/MultipartFormDataBodyParameters.swift:231:13: 'super' members cannot be referenced in a root class
    
                super.init()
    
    
    opened by HevaWu 6
  • Swift4.2 support

    Swift4.2 support

    Hi, there.

    RunLoopMode is remated to RunLoop.Mode at Swift4.2

    In MultipartFormDataBodyParameters.swift: I think these functions

        override func schedule(in aRunLoop: RunLoop, forMode mode: RunLoopMode) {
    
        }
    
        override func remove(from aRunLoop: RunLoop, forMode mode: RunLoopMode) {
    
        }
    

    should be

        #if swift(>=4.2)
        override func schedule(in aRunLoop: RunLoop, forMode mode: RunLoop.Mode) {
    
        }
    
        override func remove(from aRunLoop: RunLoop, forMode mode: RunLoop.Mode) {
    
        }
       #else 
        override func schedule(in aRunLoop: RunLoop, forMode mode: RunLoopMode) {
    
        }
    
        override func remove(from aRunLoop: RunLoop, forMode mode: RunLoopMode) {
    
        }
       #endif
    

    Thanks

    opened by usk2000 6
  • Add defaultURLSession and its delegate instead of instancePair

    Add defaultURLSession and its delegate instead of instancePair

    This resolves #13. This change makes implementation simpler and more obvious.

    • Add defaultURLSession that has a delegate with minimal implementation of NSURLSessionDataDelegate.
    • Remove instance pair, which is singleton instance pair of API and NSURLSession.

    Breaking changes:

    • API does not creates singleton instances for each API subclasses. If an API subclass needs a separated session, defaultURLSession should be overrided.
    • API.instance is no longer available.
    • API.session is no longer available.
    • Delegate methods implemented in API should be moved to custom delegate class, and its instance should be set to delegate of defaultURLSession.

    See the discussion on #13 for more details.

    opened by ishkawa 6
  • Executing multipart request on same Part instance can cause waiting reading eternally

    Executing multipart request on same Part instance can cause waiting reading eternally

    This problem occurred on MultipartFormDataBodyParameters.Part(data: Data).

    The declaration code was like below:

    struct MyFormRequest: Request {
        let baseURL = URL(string: "https://example.com/")!
    
        let method: HTTPMethod = .get
    
        let path = "/"
    
        typealias Response = Void
    
        private let parts: [MultipartFormDataBodyParameters.Part]
    
        init(images: [UIImage]) throws {
            parts = try images.map {
                guard let data = $0.jpegData() else { throw AppError.invalidSession }
                return data
                }.enumerated().map { (i, data) in
                    MultipartFormDataBodyParameters.Part(
                        data: data,
                        name: "images[]",
                        mimeType: "image/jpeg",
                        fileName: "imagae\(i).jpg")
            }
        }
        var bodyParameters: BodyParameters? {
            return MultipartFormDataBodyParameters(
                parts: parts,
                boundary: "0123456789abcdef")
        }
    
        func response(from object: Any, urlResponse: HTTPURLResponse) throws {
        }
    }
    

    Then, call it like below:

    func execute(images: [UIImage]) {
       let request = MyFormRequest(images: images)
       Session.send(request: request) { result in
        if case .success = result { return }
        // retry the request. (with the same instance)
        Session.send(request: request) { result2 in
           // it will be never success or failure!!!
        }
       }
    }
    

    I noticed this problem occured because of the class MultipartFormDataBodyParameters reads InputStream without rewinding or renewing stream.

    # MultipartFormDataBodyParameters.swift:
    
                    case bodyRange:
                        if bodyPart.inputStream.streamStatus == .notOpen {
                            bodyPart.inputStream.open()
                        }
    
                        // this line never finished when calling `read` twice on same instance.
                        let readLength = bodyPart.inputStream.read(offsetBuffer, maxLength: availableLength) 
    
                        sentLength += readLength
                        totalSentLength += readLength
    

    So I resolved it by changing Request class like below finally.

    struct MyFormRequest: Request {
        let baseURL = URL(string: "https://example.com/")!
    
        let method: HTTPMethod = .get
    
        let path = "/"
    
        typealias Response = Void
    
        private let images: [Data] 
    
        init(images: [UIImage]) throws {
            images = try images.map {
                guard let data = $0.jpegData() else { throw AppError.invalidSession }
                return data
                }
            // Do not create Part instance while initialization.
        }
        var bodyParameters: BodyParameters? {
           // Recreate part instance for each request.
           let parts = images.enumerated().map { (i, data) in
                    MultipartFormDataBodyParameters.Part(
                        data: data,
                        name: "images[]",
                        mimeType: "image/jpeg",
                        fileName: "imagae\(i).jpg")
            }
            return MultipartFormDataBodyParameters(
                parts: parts,
                boundary: "0123456789abcdef")
        }
    
        func response(from object: Any, urlResponse: HTTPURLResponse) throws {
        }
    }
    

    To begin with, I think the request instance should not be reuse. But in our project, we have to reuse it. (We wrap APIKit with RxSwift. When the retryable error (network connection error or somethink) occurred, to retry the request, we have to re-subscribe the same stream(Observable) with same request instance)

    I hope this post can help someone.

    Environment: APIKit version 4.0.0, iOS 12.1.4, Xcode 10.2.1(10E1001)

    opened by ecoopnet 0
  • [question] Was develop/4.0 branch abandoned?

    [question] Was develop/4.0 branch abandoned?

    I'm trying to update an app that depended on APIKit 4.0.0-beta.1 (swift 3) to current swift version. The app is using progressHandler. However, 4.0.0-beta.1 tag is on develop/4.0 branch. It seems that the branch is not merged into master and latest release tag 5.0.0.

    opened by hiroshi 4
  • How about using a private queue as default callback queue?

    How about using a private queue as default callback queue?

    Currently if user calls Session.send(request) without setting the callback queue, it will use main thread for processing the callback.

    But APIKit, in layered architecture designing, should be in the infrastructure layer or persistence layer; And on the other side, main queue in iOS, since it mainly handles UI process, is usually considered in the UI layer.

    Therefore, it's probably not a good idea to let APIKit know about the main queue. it's a UI world thing, which an infrastructure world thing probably should not know.

    And by using main queue, which may also be used by any object in the program, as the default queue, it's very easy to cause a deadlock if a user tries to use a semaphore to stop current thread until the response received.

    So my opinion is that in Session's initializer, maybe it's better to set the default value of callbackQueue to DispatchQueue.global() or DispatchQueue(label: someLabel)

    Thanks for considering this issue.

    opened by el-hoshino 0
  • 'NSInvalidArgumentException', reason: '*** -propertyForKey: only defined for abstract class

    'NSInvalidArgumentException', reason: '*** -propertyForKey: only defined for abstract class

    Hi

    I found this exception in Crashlytics crash logs from my production app. I can reproduce and paste it bellow. But I cannot find how to fix it. So, I just report this.

    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -propertyForKey: only defined for abstract class.  Define -[_TtCV6APIKit31MultipartFormDataBodyParameters20MultipartInputStream propertyForKey:]!'
    
    • Xcode 8.3.3
    • iOS 10.3 SDK
    • iPhone Plus (iOS 10.3 simulator)
    import UIKit
    import APIKit
    
    protocol HttpBinRequest: Request {
    
    }
    
    extension HttpBinRequest {
        var baseURL: URL {
            return URL(string: "https://httpbin.org")!
        }
    }
    
    struct PostRequest: HttpBinRequest {
        typealias Response = Any
    
        var method: HTTPMethod {
            return .post
        }
    
        var path: String {
            return "/post"
        }
    
        var bodyParameters: BodyParameters? {
            let p = try! MultipartFormDataBodyParameters.Part(
                value: "value",
                name: "name"
            )
    
            return MultipartFormDataBodyParameters(parts: [p], entityType: .inputStream)
        }
    
        func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
            return object
        }
    }
    
    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let request = PostRequest()
    
            Session.send(request) { result in
                print(result)
                switch result {
                case .success(let response):
                    print(response)
                case .failure(let error):
                    print("error: \(error)")
                }
            }
        }
    }
    
    opened by konomae 1
Releases(5.4.0)
  • 5.4.0(Oct 2, 2022)

    • Fix deprecated class keyword #297
    • Added default implementation of response(from:urlResponse:) when Response is Void #304
    • Drop support for swift 5.3 and below #303
    • Support Swift Concurrency #306
    Source code(tar.gz)
    Source code(zip)
  • 5.3.0(Jan 1, 2022)

    • Fix Demo.playground could not be run #293
    • Change iOS deployment target for Xcode 12 #286
      • The minimum supported version of iOS is now iOS 9 or later.

    Thanks @noppefoxwolf for contributing!

    Source code(tar.gz)
    Source code(zip)
  • 5.2.0(Feb 25, 2021)

    • ExpressibleByDictionaryLiteral for JSONBodyParameters #275
    • Add support for Combine.framework #285
      • Create a Publisher using Session.shared.sessionTaskPublisher(for:).
    • Fix PBXGroup reference at the project.pbxproj file #287

    Thanks @417-72KI and @keisukeYamagishi for contributing!

    Source code(tar.gz)
    Source code(zip)
  • 5.1.0(Dec 28, 2019)

    • Remove to link Result.framework from README.md #274
    • Fix typo #276
    • [Swift 5.1] Enable Module Stability #278

    Thanks @jumperson and @onevcat for contributing!

    Source code(tar.gz)
    Source code(zip)
  • 5.0.0(Apr 17, 2019)

  • 4.1.0(Apr 6, 2019)

  • 4.0.0(Jul 25, 2018)

  • 3.2.0(Dec 24, 2017)

  • 4.0.0-beta.1(Jul 23, 2017)

    • Add progressHandler parameter to sendRequest(_:) method.
    • Introduce Request.DataParser associated type to express various data format such as JSON, URL query and Protobuf.
    • Introduce QueryParameters protocol for custom URL query parsers.
    Source code(tar.gz)
    Source code(zip)
  • 3.1.2(Dec 20, 2016)

  • 3.1.1(Dec 7, 2016)

  • 3.1.0(Nov 28, 2016)

  • 3.0.0(Nov 28, 2016)

  • 3.0.0-beta.2(Sep 23, 2016)

  • 3.0.0-beta.1(Sep 17, 2016)

  • 2.0.5(Jul 12, 2016)

  • 2.0.4(Jun 27, 2016)

  • 2.0.3(Jun 25, 2016)

  • 2.0.2(Jun 25, 2016)

  • 2.0.0(May 23, 2016)

    :tada:

    APIKit 2 introduces 3 major features below:

    • New error handling model
    • Convenience parameters and actual parameters
    • Abstraction of networking backend

    See the migration guide and following summary for more details.

    New error handling model

    The error type of Session.sendRequest(_:) is changed to SessionTaskError:

    public enum SessionTaskError: ErrorType {
        case ConnectionError(ErrorType)
        case RequestError(ErrorType)
        case ResponseError(ErrorType)
    }
    

    These error cases describes where the error occurred, not what is the error. You can throw any kind of error to notify what is happened in the following methods:

    public protocol RequestType {
        ...
    
        // The error thrown here will be the associated value of SessionTaskError.RequestError 
        func interceptURLRequest(URLRequest: NSMutableURLRequest) throws -> NSMutableURLRequest
    
        // The error thrown here will be the associated value of SessionTaskError.ResponseError 
        func interceptObject(object: AnyObject, URLResponse: NSHTTPURLResponse) throws -> AnyObject
    }
    

    Convenience parameters and actual parameters

    Usually, you can specify request parameters in dictionary-literal or array-literal like below:

    struct SomeRequest: RequestType {
        ...
    
        var parameters: AnyObject? {
            return ["q": "Swift"]
        }
    }
    

    var parameters is the convenience parameters. It is define as below:

    public protocol RequestType {
        ...
    
        var parameters: AnyObject? { get }
    }
    

    Actually, we have to translate the literal into HTTP/HTTPS request. There are 2 places to express parameters, URL query and body. RequestType has interface to express them, var queryParameters: [String: AnyObject]? and var bodyParameters: BodyParametersType?. Those are the actual parameters.

    public protocol RequestType {
        ...
    
        var queryParameters: [String: AnyObject]? { get }
        var bodyParameters: BodyParametersType? { get }
    }
    

    If you implement convenience parameters only, the actual parameters are computed from the convenience parameters depending on HTTP method.

    APIKit provides 3 types that conforms to BodyParametersType:

    | Name | Parameters Type | | --- | --- | | JSONBodyParameters | AnyObject | | FormURLEncodedBodyParameters | [String: AnyObject] | | MultipartFormDataBodyParameters | [MultipartFormDataBodyParameters.Part] |

    Abstraction of networking backend

    APIKit uses NSURLSession as networking backend by default. Since Session in APIKit 2 has abstraction layer of backend called SessionAdapterType, you can change the backend of Session like below:

    Demo implementation of Alamofire adapter is available here.

    Source code(tar.gz)
    Source code(zip)
    APIKit.framework.zip(4.68 MB)
  • 2.0.0-beta.7(May 19, 2016)

  • 2.0.0-beta.5(May 16, 2016)

    • [Renamed] HTTPHeaderFields in RequestType is renamed to headerFields.
    • [Renamed] resumedTaskWithURLRequest(_:) is renamed to createTaskWithURLRequest(_:).
    • [Added] resume() is added to SessionTaskType.
    • [Added] StringDataParser is added for unformatted response body.
    • [Changed] Exposed RequestError.
    • [Changed] Type of associated value of SessionTaskError.ConnectionError is changed from NSError to ErrorType.
    Source code(tar.gz)
    Source code(zip)
    APIKit.framework.zip(4.53 MB)
  • 2.0.0-beta.4(May 6, 2016)

    • MultipartFormDataParameters uses NSInputStream for its entity. #160
    • Session.sharedSession is changed to class property for overriding. #158
    • Add callbackQueue parameter to Session.sendRequest(). #157 #156

    Thanks to @jyounus and @kumabook for the contribution!

    Source code(tar.gz)
    Source code(zip)
    APIKit.framework.zip(4.42 MB)
  • 1.4.0(May 4, 2016)

  • 2.0.0-beta.3(Mar 27, 2016)

  • 1.3.0(Mar 27, 2016)

  • 2.0.0-beta.2(Mar 21, 2016)

Owner
Yosuke Ishikawa
Yosuke Ishikawa
DBNetworkStack is a network abstraction for fetching request and mapping them to model objects

DBNetworkStack Main Features ?? Typed network resources ?? Value oriented architecture ?? Exchangeable implementations ?? Extendable API ?? Composable

DB Systel GmbH 33 Jan 10, 2022
Dratini is a neat network abstraction layer.

Dratini Dratini is a neat network abstraction layer. If you are looking for a solution to make your network layer neat, Dratini is your choice. Dratin

Kevin Lin 37 Jan 29, 2022
Network abstraction layer written in Swift.

Moya 14.0.0 A Chinese version of this document can be found here. You're a smart developer. You probably use Alamofire to abstract away access to URLS

Moya 14.4k Jan 1, 2023
Elegant network abstraction layer in Swift.

Elegant network abstraction layer in Swift. 中文 Design Features Requirements Communication Installation Usage Base Usage - Target - Request - Download

null 100 Dec 9, 2022
Lightweight network abstraction layer, written on top of Alamofire

TRON is a lightweight network abstraction layer, built on top of Alamofire. It can be used to dramatically simplify interacting with RESTful JSON web-

MLSDev 528 Dec 26, 2022
Network abstraction layer written in Swift.

Moya 15.0.0 A Chinese version of this document can be found here. You're a smart developer. You probably use Alamofire to abstract away access to URLS

Moya 14.4k Jan 4, 2023
A type-safe, high-level networking solution for Swift apps

What Type-safe network calls made easy Netswift offers an easy way to perform network calls in a structured and type-safe way. Why Networking in Swift

Dorian Grolaux 23 Apr 27, 2022
A barebones Swift HTTP client with automatic JSON response parsing.

HTTP Client A barebones Swift HTTP client with automatic JSON response parsing. Installation Add HTTP Client as a dependency through Xcode or directly

Joe Masilotti 30 Oct 11, 2022
An Alamofire extension which converts JSON response data into swift objects using EVReflection

AlamofireJsonToObjects ?? This is now a subspec of EVReflection and the code is maintained there. ?? You can install it as a subspec like this: use_fr

Edwin Vermeer 161 Sep 29, 2022
Sherlock Holmes of the networking layer. :male_detective:

ResponseDetective is a non-intrusive framework for intercepting any outgoing requests and incoming responses between your app and your server for debu

Netguru 1.9k Dec 24, 2022
Advanced Networking Layer Using Alamofire with Unit Testing

Advanced Networking Layer Using Alamofire with Unit Testing

Ali Fayed 8 May 23, 2022
An elegant yet powerful iOS networking layer inspired by ActiveRecord.

Written in Swift 5 AlamoRecord is a powerful yet simple framework that eliminates the often complex networking layer that exists between your networki

Tunespeak 19 Nov 19, 2022
GXBaseAPI - GARPIX Networking Layer

GXBaseAPI GARPIX Networking Layer URLSession + Combine + Codable + Generics Все

GARPIX iOS team 2 Jan 21, 2022
🤵🏽‍♀️ Janet — A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

????‍♀️ Janet — Just another networking kit — A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveragi

Niklas Holloh 3 Sep 6, 2022
Elegant API Abstraction for Swift

Endpoint (Deprecated) ⚠️ This project has been deprecated. Consider using Moya and MoyaSugar instead. ?? Elegant API Abstraction for Swift. At a Glanc

Suyeol Jeon 35 Mar 29, 2019
APIProvider - API Provider Package for easier API management inspired by abstraction

APIProvider Using APIProvider you can easily communicate with all API endpoints

null 1 Apr 21, 2022
This package is meant to make http request of an easy way inspiren in the architecture of Moya package

NetworkAgent This package is meant to make http request of an easy way inspiren in the architecture of Moya package. This package is 100% free of depe

Angel Rada 19 Sep 8, 2022
Minimalistic Swift HTTP request agent for iOS and OS X

Agent Table of Contents Introduction Usage HTTP Verbs Overloading Method Chaining Response Closure Verbs Methods NSMutableURLRequest Contributing Lice

null 589 Jun 29, 2022
Automatically sets the network activity indicator for any performed request.

BigBrother BIG BROTHER IS WATCHING YOU. BigBrother is a Swift library made for iOS that automatically watches for any performed request and sets the n

Marcelo Fabri 446 Dec 17, 2022