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.
Swift based OAuth library for iOS

OAuthSwift Swift based OAuth library for iOS and macOS. Support OAuth1.0, OAuth2.0 Twitter, Flickr, Github, Instagram, Foursquare, Fitbit, Withings, L

OAuthSwift 3.1k Jan 3, 2023
Swift based OAuth library for iOS and macOS

OAuthSwift Swift based OAuth library for iOS and macOS. Support OAuth1.0, OAuth2.0 Twitter, Flickr, Github, Instagram, Foursquare, Fitbit, Withings, L

OAuthSwift 3.1k Jan 3, 2023
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
Swift async/await OAuth 2.0 HTTP request library.

SwAuth SwAuth is an OAuth 2.0 HTTP request library written in Swift iOS 15.0+, macOS 12.0+, watchOS 8.0+, and tvOS 15.0+. Features Requirements Instal

Colaski 17 Nov 5, 2022
A simple library to make authenticating tvOS apps easy via their iOS counterparts.

Voucher The new Apple TV is amazing but the keyboard input leaves a lot to be desired. Instead of making your users type credentials into their TV, yo

Riz 516 Nov 24, 2022
FCLAuthSwift is a Swift library for the Flow Client Library (FCL) that enables Flow wallet authentication on iOS devices.

FCLAuthSwift is a Swift library for the Flow Client Library (FCL) that enables Flow wallet authentication on iOS devices. Demo The demo a

Zed 3 May 2, 2022
LoginKit is a quick and easy way to add Facebook and email Login/Signup UI to your app.

LoginKit About LoginKit is a quick and easy way to add Facebook and email Login/Signup UI to your app. If you need to quickly prototype an app, create

Icalia Labs 653 Dec 17, 2022
OAuth2 framework for macOS and iOS, written in Swift.

OAuth2 OAuth2 frameworks for macOS, iOS and tvOS written in Swift 5.0. ⤵️ Installation ?? Usage ?? Sample macOS app (with data loader examples) ?? Tec

Pascal Pfiffner 1.1k Jan 2, 2023
Simple OAuth2 library with a support of multiple services.

Simple OAuth2 library with a support of multiple services.

HyperRedink 68 May 13, 2022
Example of simple OAuth2 authentication using Alamofire 5 and RxSwift library

REST Client based on Alamofire 5 and RxSwift library. Supports OAuth2 and Basic authentication interceptor.

Tomáš Smolík 3 Dec 8, 2022
InstagramLogin allows iOS developers to authenticate users by their Instagram accounts.

InstagramLogin handles all the Instagram authentication process by showing a custom UIViewController with the login page and returning an access token that can be used to request data from Instagram.

Ander Goig 67 Aug 20, 2022
SimpleAuth is designed to do the hard work of social account login on iOS

SimpleAuth is designed to do the hard work of social account login on iOS. It has a small set of public APIs backed by a set of "providers"

Caleb Davenport 1.2k Nov 17, 2022
A simple way to implement Facebook and Google login in your iOS apps.

Simplicity Simplicity is a simple way to implement Facebook and Google login in your iOS apps. Simplicity can be easily extended to support other exte

Simplicity Mobile 681 Dec 18, 2022
A simple project for Face ID Authentication for iOS device using LocalAuthentication Framework

BiometricAuthentication This respository is a simple project for Face ID Authentication for iOS device using LocalAuthentication Framework and infoPli

Lee McCormick 0 Oct 23, 2021
Krypton turns your iOS device into a WebAuthn/U2F Authenticator: strong, unphishable 2FA.

Krypton turns your iOS device into a WebAuthn/U2F Authenticator: strong, unphishable 2FA. Krypton implements the standardized FIDO Universal 2nd Facto

krypt.co 332 Nov 5, 2022
SpotifyLogin is a Swift 5 Framework for authenticating with the Spotify API.

SpotifyLogin SpotifyLogin is a Swift 5 Framework for authenticating with the Spotify API. Usage of this framework is bound under the Developer Terms o

Spotify 343 Dec 8, 2022
A swift implementation of OAuth2

#AlamofireOauth2 A Swift implementation of OAuth2 for iOS using Alamofire. #Intro This library is heavilly inspired by the SwiftOAuth2 repository from

Edwin Vermeer 83 Dec 5, 2022
Declarative Swift framework for Attributed Role-based Access Control management

Koosa Declarative Swift framework for Attributed Role-based Access Control management Check out this blog post for full explanation and more details:

Mostafa Abdellateef 37 Oct 24, 2022
SFA: Swift Firebase Auth Project✨

SFAssets SFA: Swift Firebase Auth Project✨ 파이어베이스로 로그인/회원가입 뿌수기 Login View (로그인 뷰) 담당 기능 배정 Facebook Login 후릐 Google Login 태끼 Apple Login 이준초이 Github

null 6 Nov 7, 2021