Easy to use OAuth 2 library for iOS, written in Swift.

Overview

Heimdallr

Heimdallr is an OAuth 2.0 client specifically designed for easy usage. It currently supports the resource owner password credentials grant flow, refreshing an access token, as well as extension grants.

If you are an Android Developer, please take a look at the Android version of Heimdallr.

Build Status

Example

Before requesting an access token, the client must be configured appropriately:

let tokenURL = URL(string: "https://example.com/oauth/v2/token")!
let heimdallr = Heimdallr(tokenURL: tokenURL)

On login, the resource owner's password credentials are used to request an access token:

heimdallr.requestAccessToken(username: "johndoe", password: "A3ddj3w") { result in
    switch result {
    case .success:
        print("success")
    case .failure(let error):
        print("failure: \(error.localizedDescription)")
    }
}

Heimdallr automatically persists the access token. Afterwards, any URLRequest can be easily authenticated using the received access token:

var session: URLSession!
var request: URLRequest!

heimdallr.authenticateRequest(request) { result in
    switch result {
    case .success(let request):
        let task = session.dataTask(with: request) { data, response, error in
            // ...
        }
        
        task.resume()
    case .failure(let error):
        print("failure: \(error.localizedDescription)")
    }
}

Installation

Installation is possible via Carthage or CocoaPods, see below for either method:

Carthage

Carthage is a simple, decentralized dependency manager for Cocoa.

  1. Add Heimdallr to your Cartfile:
github "trivago/Heimdallr.swift" ~> 3.6.1
  1. Run carthage update to fetch and build Heimdallr and its dependencies.

  2. Make sure your application's target links against Heimdallr.framework and copies all relevant frameworks into its application bundle (iOS); or embeds the binaries of all relevant frameworks (Mac).

CocoaPods

  1. Add Heimdallr to your Podfile:

    pod 'Heimdallr', '~> 3.6.1'
  2. Run pod install to fetch and build Heimdallr and its dependencies.

Usage

OAuthClientCredentials

The client credentials, consisting of the client's identifier and optionally its secret, are used for authenticating with the token endpoint:

var identifier: String!
var secret: String!

let credentials = OAuthClientCredentials(id: identifier)
               // OAuthClientCredentials(id: identifier, secret: secret)

Please note that native applications are considered to be public clients.

OAuthAccessTokenStore

An access token store is used to (persistently) store an access token received from the token endpoint. It must implement the following storage and retrieval methods:

protocol OAuthAccessTokenStore {
    func storeAccessToken(accessToken: OAuthAccessToken?)
    func retrieveAccessToken() -> OAuthAccessToken?
}

Heimdallr ships with an already built-in persistent keychain-based access token store. The service is configurable:

var service: String!

let accessTokenStore = OAuthAccessTokenKeychainStore(service: service)

HeimdallrHTTPClient

An HTTP client that can be used by Heimdallr for requesting access tokens. It must implement the following sendRequest method:

protocol HeimdallrHTTPClient {
    func sendRequest(request: URLRequest, completion: (data: Data!, response: URLResponse!, error: Error?) -> ())
}

For convenience, a default HTTP client named HeimdallrHTTPClientURLSession and based on URLSession is provided. It may be configured with an URLSession:

var urlSession: URLSession!

let httpClient = HeimdallrHTTPClientURLSession(urlSession: session)

OAuthAccessTokenParser

You can provide your own parser to handle the access token response of the server. It can be useful for parsing additional parameters sent in the response that your application may need. The parser must implement the following parse method:

protocol OAuthAccessTokenParser {
    func parse(data: Data) -> Result<OAuthAccessToken, Error>
}

Heimdallr

Heimdallr must be initialized with the token endpoint URL and can optionally be configured with client credentials, an access token store and an HTTP client:

var tokenURL: URL!

let heimdallr = Heimdallr(tokenURL: tokenURL)
             // Heimdallr(tokenURL: tokenURL, credentials: credentials)
             // Heimdallr(tokenURL: tokenURL, credentials: credentials, accessTokenStore: accessTokenStore)
             // Heimdallr(tokenURL: tokenURL, credentials: credentials, accessTokenStore: accessTokenStore, accessTokenParser: accessTokenParser)
             // Heimdallr(tokenURL: tokenURL, credentials: credentials, accessTokenStore: accessTokenStore, accessTokenParser: accessTokenParser, httpClient: httpClient)
             // Heimdallr(tokenURL: tokenURL, credentials: credentials, accessTokenStore: accessTokenStore, accessTokenParser: accessTokenParser, httpClient: httpClient, resourceRequestAuthenticator: resourceRequestAuthenticator)

Whether the client's access token store currently holds an access token can be checked using the hasAccessToken property. It's not checked whether the stored access token, if any, has already expired.

The authorize method takes the resource owner's password credentials as parameters and uses them to request an access token from the token endpoint:

var username: String!
var password: String!

heimdallr.requestAccessToken(username: username, password: password) { result in
    // ...
}

The completion closure may be invoked on any thread.

Once successfully authorized, any URLRequest can be easily altered to include authentication via the received access token:

var request: URLRequest!

heimdallr.authenticateRequest(request) { result in
    // ...
}

If the access token has already expired and a refresh token is available, Heimdallr will automatically refresh the access token. Refreshing requires network I/O. The completion closure may be invoked on any thread.

HeimdallrResourceRequestAuthenticator

By default, Heimdallr authenticates a request by setting the HTTP header field Authorization. This behavior can be changed by passing another resource request authenticator implementing HeimdallrResourceRequestAuthenticator to the initializer.

About

Heimdallr was built by trivago 🏭

Credits

Contains code for query string escaping taken from Alamofire (MIT License)

Comments
  • [WIP] Swift 3.0

    [WIP] Swift 3.0

    This adds support to Swift 3.0. It's still WIP:

    • [x] Update core
    • [x] Update core tests
    • [x] Update RAC
    • [x] Update RAC tests
    • [ ] Update podspec
    • [x] Point OHHTTPStubs to https://github.com/AliSoftware/OHHTTPStubs/pull/201 or wait until that is merged
    • [x] ~~Update tests to run on iOS 10: they seem to be failing on the Simulator with the same issue mentioned here: https://forums.developer.apple.com/thread/51071 and http://stackoverflow.com/questions/38456471/secitemadd-always-returns-error-34018-in-xcode-8-beta-4-in-ios-10-simulator~~ I think this should be done on a later PR, since it'll probably need to create an app target so the unit tests could be run on a host app (with an Entitlements file)
    • [ ] Lock dependencies to releases (some of them are referring to branches)
    opened by marcelofabri 15
  • Reactive extension

    Reactive extension

    I think we should use ReactiveCocoa 2 because 3 seems to be far from being usable in production. Should we put this into this repo or into a separate one?

    opened by tibr 6
  • Support for Swift Package Manager ?

    Support for Swift Package Manager ?

    Hi,

    Thanks for the great library. It's could be great if you consider adding support for Swift package manager.

    This is an example of Package.swift to add to the root of your repository. But you will still have to remove all code that is not available on Linux to make it work.

    // swift-tools-version:4.0
    import PackageDescription
    
    let package = Package(
        name: "Heimdallr",
        products: [
            .library(name: "Heimdallr", targets: ["Heimdallr"]),
        ],
        dependencies: [
            .package(url: "https://github.com/antitypical/Result.git", .upToNextMajor(from: "3.0.0")),
        ],
        targets: [
             .target(
                name: "Heimdallr",
                dependencies: ["Result"],
                path: "Heimdallr",
                exclude: [
                    "HeimdallrTests",
                    "script",
                    "Carthage",
                    "Heimdallr/Supporting Files",
                    "bin"]),
        ],
        swiftLanguageVersions: [3]
    )
    

    Errors that I get when I try to build it for SPM(Swift Package Manager).

    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:13:27: error: use of undeclared type 'Date'
        public let expiresAt: Date?
                              ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:27:68: error: use of undeclared type 'Date'
        public init(accessToken: String, tokenType: String, expiresAt: Date? = nil, refreshToken: String? = nil) {
                                                                       ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:43:87: error: use of undeclared type 'Date'
        public func copy(accessToken: String? = nil, tokenType: String? = nil, expiresAt: Date?? = nil, refreshToken: String?? = nil) -> OAuthAccessToken {
                                                                                          ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:78:36: error: use of undeclared type 'Data'
        public class func decode(data: Data) -> OAuthAccessToken? {
                                       ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:60:63: error: use of undeclared type 'Date'
            func toDate(_ timeIntervalSinceNow: TimeInterval?) -> Date? {
                                                                  ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:60:45: error: use of undeclared type 'TimeInterval'
            func toDate(_ timeIntervalSinceNow: TimeInterval?) -> Date? {
                                                ^~~~~~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:71:49: error: use of undeclared type 'TimeInterval'
            let expiresAt = (json["expires_in"] as? TimeInterval).flatMap(toDate)
                                                    ^~~~~~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:79:31: error: use of unresolved identifier 'JSONSerialization'
            guard let json = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions(rawValue: 0)),
                                  ^~~~~~~~~~~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:79:81: error: use of unresolved identifier 'JSONSerialization'
            guard let json = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions(rawValue: 0)),
                                                                                    ^~~~~~~~~~~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: @objc attribute used without importing module 'Foundation'
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:78:36: error: use of undeclared type 'Data'
        public class func decode(data: Data) -> OAuthAccessToken? {
                                       ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:43:87: error: use of undeclared type 'Date'
        public func copy(accessToken: String? = nil, tokenType: String? = nil, expiresAt: Date?? = nil, refreshToken: String?? = nil) -> OAuthAccessToken {
                                                                                          ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthError.swift:90:36: error: use of undeclared type 'Data'
        public class func decode(data: Data) -> OAuthError? {
                                       ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:13:27: error: use of undeclared type 'Date'
        public let expiresAt: Date?
                              ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:5:32: error: use of undeclared type 'NSObject'
    public class OAuthAccessToken: NSObject {
                                   ^~~~~~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
    @objc
    ~^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessTokenKeychainStore.swift:14:48: error: use of undeclared type 'Data'
        internal func dataForKey(_ key: String) -> Data? {
                                                   ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessTokenKeychainStore.swift:38:35: error: use of undeclared type 'Data'
        internal func setData(_ data: Data, forKey key: String) {
                                      ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessTokenKeychainStore.swift:51:38: error: use of undeclared type 'Data'
        internal func updateData(_ data: Data, forKey key: String) {
                                         ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessToken.swift:13:27: error: use of undeclared type 'Date'
        public let expiresAt: Date?
                              ^~~~
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessTokenKeychainStore.swift:117:17: error: use of unresolved identifier 'Date'
                    Date(timeIntervalSince1970: expiresAtInSeconds)
                    ^~~~
    CoreFoundation.CFDate:1:14: note: did you mean 'CFDate'?
    public class CFDate : _CFObject {
                 ^
    /Users/jmacko/code/vapor/Heimdallr.swift/Heimdallr/OAuthAccessTokenKeychainStore.swift:93:2: error: @objc attribute used without importing module 'Foundation'
    @objc public class OAuthAccessTokenKeychainStore: NSObject, OAuthAccessTokenStore {
    ~^~~~
    error: terminated(1): /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-build-tool -f /Users/jmacko/code/vapor/Heimdallr.swift/.build/debug.yaml main
    

    Thanks,

    opened by mackoj 4
  • FYI Xcode 8/iOS 10 Keychain issues

    FYI Xcode 8/iOS 10 Keychain issues

    I was having issues authenticating my requests, and after spending some time debugging I found out that the issue is that the Keychain was giving an error when storing a new value. Apparently this is a known issue with iOS 10, there are some threads discussing this here:

    https://forums.developer.apple.com/message/179846

    https://forums.developer.apple.com/thread/51071

    Workaround usually is to add the Keychain Entitlement, but it doesn't solve in my case because I use Heimdallr in a framework.

    Thought I'd create this here if anyone else is running into the same issues (Heimdallr doesn't seem to be reporting this error.)

    opened by dccarmo 4
  • Result version mismatch.

    Result version mismatch.

    I can see that the cart file suggests it has been updated to use Result 2.0:

    # Core
    github "antitypical/Result" ~> 2.0
    

    But, the podspec still referenced 1.0:

      spec.subspec 'Core' do |subspec|
         ...
        subspec.dependency 'Result', '~> 1.0'
         ...
      end
    
    opened by morgz 4
  • Heimdallr doesn't refresh token but get a new access token instead

    Heimdallr doesn't refresh token but get a new access token instead

    My version: github "rheinfabrik/Heimdallr.swift" ~> 3.2

    Using Wireshark, I could monitor Heimdallr calls on my app.

    This is how it refreshes the OAuth token: Wireshark capture when trying to refresh token

    Which is not using refresh_token but requesting a new access_token.

    Also, this is my implementation: I'm using a singleton of Heimdallr

    import Heimdallr
    
    class SharedNetwork {
        static let instance = SharedNetwork()
    
        var heimdallr: Heimdallr!
    
        private init() {
            let loginURL = NSURL(string: NEA.API.login)!
            let credentials = OAuthClientCredentials(id: NEA.API.clientId, secret: NEA.API.clientSecret)
            self.heimdallr = Heimdallr(tokenURL: loginURL, credentials: credentials)
        }
    }
    
    //Call in it like this
    
    let accountInfoRequest = NSURLRequest(URL: NSURL(string: "http://foobar.com/api/account/info")!)
    SharedNetwork.instance.heimdallr.authenticateRequest(accountInfoRequest) { result in
        //...
    }
    
    opened by Kalzem 4
  • Read extra parameters on token response

    Read extra parameters on token response

    Hi! My authorization server returns some extra parameters in the access token response and I need a way to read them.

    For reference, check out example_parameter in this example in the spec

    opened by poislagarde 4
  • Unify authorization and token refresh

    Unify authorization and token refresh

    Credentials are now fully optional. If both an identifier and secret are provided, they are used for Basic HTTP Authentication; if only an identifier is provided, it's encoded with the other parameters in the POST request's body.

    Authorization and token refresh has been unified and is very extensible. We should probably split up the authorize method (before merge?)..

    opened by felixvisee 4
  • Prevent firing multiple requests?

    Prevent firing multiple requests?

    From what I've seen in the code, no special treatment is done to prevent multiple network calls being fired in authenticateRequest.

    This can be a problem, as a server can invalidate one of the returned tokens. Should the library handle this?

    opened by marcelofabri 3
  • Removing Argo

    Removing Argo

    This fixes #90

    I wasn't able to figure out a way to make Carthage just remove Argo, so I had to run carthage update ..., which updated Nimble, Result and ReactiveCocoa. I hope it's not a problem.

    opened by marcelofabri 3
  • Refresh Token in a different URL

    Refresh Token in a different URL

    So I'm currently working with an API that have a different endpoint for token refresh. How can I let Heimdallr know the refresh token URL (and maybe even allow the application to set parameters)?

    opened by dccarmo 3
  • fix: removed unused pre-action to let Carthage build succeed on XCode 13!!

    fix: removed unused pre-action to let Carthage build succeed on XCode 13!!

    error log as below, it spend my whole day to figure it out

        Build settings from command line:
        CARTHAGE = YES
        CLANG_ENABLE_CODE_COVERAGE = NO
        CODE_SIGN_IDENTITY =
        CODE_SIGNING_REQUIRED = NO
        GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO
        ONLY_ACTIVE_ARCH = NO
        SDKROOT = iphoneos15.5
        SKIP_INSTALL = YES
        STRIP_INSTALLED_PRODUCT = NO
        VALIDATE_WORKSPACE = NO
    
    --- xcodebuild: WARNING: Using the first of multiple matching destinations:
    { platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Any iOS Device }
    { platform:macOS, arch:x86_64, variant:Mac Catalyst, id:2ECD8619-22D6-53EF-A799-5B1BAA38B670 }
    { platform:iOS Simulator, id:dvtdevice-DVTiOSDeviceSimulatorPlaceholder-iphonesimulator:placeholder, name:Any iOS Simulator Device }
    { platform:macOS, variant:Mac Catalyst, name:Any Mac }
    { platform:iOS Simulator, id:7B0E8759-CA0E-46A6-80F2-B34AF94A8746, OS:15.5, name:iPad (9th generation) }
    { platform:iOS Simulator, id:4A8E611F-44A8-49C6-ADBD-727335B49F86, OS:15.5, name:iPad Air (5th generation) }
    { platform:iOS Simulator, id:0EDC5E5F-7AE5-41A7-BB16-0DCA2B04AC9A, OS:15.5, name:iPad Pro (9.7-inch) }
    { platform:iOS Simulator, id:058E636B-43F1-40E1-AC47-A5EB0EE955B4, OS:15.5, name:iPad Pro (11-inch) (3rd generation) }
    { platform:iOS Simulator, id:53BE13E0-F53A-47E1-8408-6D67066FE1EA, OS:15.5, name:iPad Pro (12.9-inch) (5th generation) }
    { platform:iOS Simulator, id:CD24FA06-BE7C-4775-9499-D3AE92F65D34, OS:15.5, name:iPad mini (6th generation) }
    { platform:iOS Simulator, id:612F4042-C77F-41A2-9A04-143321C50222, OS:15.5, name:iPhone 8 }
    { platform:iOS Simulator, id:8469ACC6-397F-4419-B249-2DC91D07042F, OS:15.5, name:iPhone 8 Plus }
    { platform:iOS Simulator, id:1B7B053E-7E84-4A8E-AC9F-76CCCE6FBF0E, OS:15.5, name:iPhone 11 }
    { platform:iOS Simulator, id:C2696932-1782-4FD5-8499-F1B5F5A4F771, OS:15.5, name:iPhone 11 Pro }
    { platform:iOS Simulator, id:3994DD00-605F-4F51-9767-503F5C3DC47B, OS:15.5, name:iPhone 11 Pro Max }
    { platform:iOS Simulator, id:5BEDDF7D-88AC-4152-B5A2-2D3DE30A5E43, OS:15.5, name:iPhone 12 }
    { platform:iOS Simulator, id:97192C28-54F0-4181-82DE-F437A1AADE1B, OS:15.5, name:iPhone 12 Pro }
    { platform:iOS Simulator, id:F2FA3C12-89E9-4F15-9B22-756394C3CA52, OS:15.5, name:iPhone 12 Pro Max }
    { platform:iOS Simulator, id:9F0AD208-017E-45D7-9FF2-7ED93033C7C6, OS:15.5, name:iPhone 12 mini }
    { platform:iOS Simulator, id:ADF4ECCA-2981-4EE1-A7F2-9BAA6A8D7925, OS:15.5, name:iPhone 13 }
    { platform:iOS Simulator, id:511B7CAC-B2CF-4A6D-BAE5-1AADF35BDEAA, OS:15.5, name:iPhone 13 Pro }
    { platform:iOS Simulator, id:D954D9CB-C493-440F-A6F0-F7CB9FE46127, OS:15.5, name:iPhone 13 Pro Max }
    { platform:iOS Simulator, id:FBD75683-4198-4621-BCA1-FDD8DE971D7E, OS:15.5, name:iPhone 13 mini }
    { platform:iOS Simulator, id:93305EA5-5AC3-405A-B46F-A4D93397A5CC, OS:15.5, name:iPhone SE (3rd generation) }
    { platform:iOS Simulator, id:947FDBBB-2A8D-45B6-AEB2-BF4E0539B4D9, OS:15.5, name:iPod touch (7th generation) }
    Run pre-actions
    
    SchemeAction Run\ Script /var/folders/yg/g78xphgd4_q536qxg4zlgthr0000gn/T/SchemeScriptAction-rebr78.sh
        cd /var/folders/yg/g78xphgd4_q536qxg4zlgthr0000gn/T/
        export RBENV_SHELL=bash
        export RUBY_VERSION=ruby-2.7.2
        export SCHEME_ACTION_NAME="Run Script"
        export SCHEME_NAME=Heimdallr-iOS
        export SHELL=/bin/bash
        export SHLVL=1
        export SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.ePUSOEPFPi/Listeners
        export TERM=xterm-256color
        export TERM_PROGRAM=Apple_Terminal
        export TERM_PROGRAM_VERSION=444
        ...
        export TMPDIR=/var/folders/yg/g78xphgd4_q536qxg4zlgthr0000gn/T/
        export rvm_ruby_string=ruby-2.7.2
        export rvm_version="1.29.9 (latest)"
        /bin/sh -c /var/folders/yg/g78xphgd4_q536qxg4zlgthr0000gn/T/SchemeScriptAction-rebr78.sh
    /var/folders/yg/g78xphgd4_q536qxg4zlgthr0000gn/T/SchemeScriptAction-rebr78.sh: line 2: : command not found
    
    note: Using new build system
    note: Using codesigning identity override:
    note: Planning
    Analyze workspace
    
    
    opened by xelven 0
  • Project refactor

    Project refactor

    The long overdue PR to update the project.

    There were several places in the project that were outdated, such as using the Result dependency, outdated scripts, broken CI config, etc. Due to this it was a bit easier to just completely refactor the project setup and start from a clean slate. A big piece of this update was that I wanted to add proper SPM support, so I configured the project from the beginning as a Swift Package. Once that was setup then I added back support for Carthage and Cocoapods. I also wanted to move the CI setup from CircleCI to GitHub Actions.

    To reduce dependencies, I converted all of the tests to XCTest and removed the need for Quick and Nimble. The only dependency that remains is for OHHTTPStubs, but this is only needed for the tests.

    There were no changes to the actual code of the framework, this was strictly a cosmetic and structural change to the project. I hope that this helps in keeping the project up to date more often going forward.

    NOTE The Xcode project is only needed for Carthage support and does not include references for the tests. Open the root of the project in Xcode and it will open it as a Swift Package. You only need to open the Xcode project itself to verify that it builds for each scheme. You can also run carthage build --no-skip-current from the command line to verify the Carthage setup.

    opened by donnywdavis 1
  • FYI / congrats (?)

    FYI / congrats (?)

    Not actually an issue but thought you guys might be interested in knowing that TikTok uses this library in their iOS app 🥇

    Some reports say TikTok's accrued 2.5B downloads — of course many of those will be Android — though for all I know they use the Heimdallr.droid version there — in any case, that's a lot! 😄

    opened by chbrown 0
  • Version 3.7.0 not available through cocoa pods

    Version 3.7.0 not available through cocoa pods

    The latest version available on cocoa pods is 3.6.1:

    -> Heimdallr (3.6.1)
       Easy to use OAuth 2 library, written in Swift
       pod 'Heimdallr', '~> 3.6.1'
       - Homepage: https://github.com/trivago/Heimdallr.swift
       - Source:   https://github.com/trivago/Heimdallr.swift.git
       - Versions: 3.6.1, 3.6.0, 3.5.0, 3.4.0, 3.3.1, 3.3.0, 3.2.1, 3.2.0, 3.1.0-alpha.3, 3.1.0-alpha.1, 3.0 [master repo]
       - Subspecs:
         - Heimdallr/Core (3.6.1)
         - Heimdallr/ReactiveCocoa (3.6.1)
    

    Would it be possible to have version 3.7.0 made available?

    opened by maloneranger 0
Releases(3.7.0)
Owner
trivago N.V.
trivago N.V.
A simple OAuth library for iOS with a built-in set of providers

SwiftyOAuth is a small OAuth library with a built-in set of providers and a nice API to add your owns. let instagram: Provider = .instagram(clientID:

Damien 477 Oct 15, 2022
Easy-to-use ICMP Ping for iOS (and maybe OSX)

CDZPinger Easy-to-use ICMP ping for iOS - just create a CDZPinger and you delegate gets a callback every second with the average ping time. Installati

Chris Dzombak 48 Feb 2, 2022
Easy to use SMJobBless, along with a full Swift implementation of the Authorization Services and Service Management frameworks

Leverage SMJobBless functionality with just one function call: let message = "Example App needs your permission to do thingamajig." let icon = Bundle.

null 20 Dec 23, 2022
The easy way to use sockets on Apple platforms

SwiftSocket SwiftSocket library provides as easy to use interface for socket based connections on server or client side. Supports both TCP and UDP soc

null 1.6k Dec 21, 2022
Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone

ASIHTTPRequest is an easy to use wrapper around the CFNetwork API that makes some of the more tedious aspects of communicating with web servers easier

Ben Copsey 5.8k Dec 14, 2022
QwikHttp is a robust, yet lightweight and simple to use HTTP networking library for iOS, tvOS and watchOS

QwikHttp is a robust, yet lightweight and simple to use HTTP networking library. It allows you to customize every aspect of your http requests within a single line of code, using a Builder style syntax to keep your code super clean.

Logan Sease 2 Mar 20, 2022
A custom wrapper over AFNetworking library that we use inside RC extensively

AFNetworkingHelper A very simple wrapper over the most amazing networking library for objective C, AFNetworking. We extensively use it inside RC and i

Betacraft 16 Aug 3, 2021
WebSocket(RFC-6455) library written using Swift

DNWebSocket Object-Oriented, Swift-style WebSocket Library (RFC 6455) for Swift-compatible Platforms. Tests Installation Requirements Usage Tests Conf

Gleb Radchenko 36 Jan 29, 2022
RSNetworking is a networking library written entirly for the Swift programming language.

RSNetworking is a networking library written entirly for the Swift programming language.

null 18 Feb 25, 2018
ServiceData is an HTTP networking library written in Swift which can download different types of data.

ServiceData Package Description : ServiceData is an HTTP networking library written in Swift which can download different types of data. Features List

Mubarak Alseif 0 Nov 11, 2021
A new, clean and lean network interface reachability library written in Swift.

Reachability A new, clean and lean network interface reachability library written in Swift. Remarks Network reachability changes can be monitored usin

Alecrim 7 Aug 8, 2022
AsyncHTTP - Generic networking library written using Swift async/await

Generic networking library written using Swift async/await

Laszlo Teveli 7 Aug 3, 2022
Shawn Frank 2 Aug 31, 2022
SwiftCANLib is a library used to process Controller Area Network (CAN) frames utilizing the Linux kernel open source library SOCKETCAN.

SwiftCANLib SwiftCANLib is a library used to process Controller Area Network (CAN) frames utilizing the Linux kernel open source library SOCKETCAN. Th

Tim Wise 4 Oct 25, 2021
Easy HTTP Networking in Swift a NSURLSession wrapper with image caching support

Networking was born out of the necessity of having a simple networking library that doesn't have crazy programming abstractions or uses the latest rea

Nes 1.3k Dec 17, 2022
WebSocket implementation for use by Client and Server

WebSocket ⚠️ This module contains no networking. To create a WebSocket Server, see WebSocketServer. To create a WebSocket Client, see WebSocketClient.

Zewo Graveyard 63 Jan 29, 2022
a NSURLCache subclass for handling all web requests that use NSURLRequest

EVURLCache What is this? This is a NSURLCache subclass for handeling all web requests that use NSURLRequest. (This includes UIWebView) The EVURLCache

Edwin Vermeer 296 Dec 18, 2022
UnsplashProvider - A package that can use the Unsplash API. It was developed as a SwiftUI

UnsplashProvider It is a package that can use the Unsplash API. It was developed

jasu 12 Dec 20, 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