A simple library to make authenticating tvOS apps easy via their iOS counterparts.

Overview

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, you can use Voucher to let them easily sign into the TV app using your iOS app.

How Does It Work?

Voucher uses Bonjour, which is a technology to discover other devices on your network, and what they can do. When active, Voucher on tvOS starts looking in your local network and over AWDL (Apple Wireless Direct Link) for any Voucher Server, on iOS.

Once it finds a Voucher Server, it asks it for authentication. Here's the demo app:

Sample tvOS App

The demo iOS app can then show a notification to the user (you can show whatever UI you want, or even no UI):

iOS app shows a dialog

If the user accepts, then the iOS app can send some authentication data back to the tvOS app (in this case, an auth token string)

Sample tvOS App

Installation

Voucher is available through Carthage and CocoaPods. You can also manually install it, if that's your jam.

Carthage

github "rsattar/Voucher"

CocoaPods

pod 'Voucher'

Manual

  • Clone the repo to your computer
  • Copy only the source files in Voucher subfolder over to your project

Using Voucher

In your tvOS app, when the user wants to authenticate, you should create a VoucherClient instance and start it:

tvOS (Requesting Auth)

When the user triggers a "Login" button, your app should display some UI instructing them to open their iOS App to finish logging in, and then start the voucher client, like below:

import Voucher

func startVoucherClient() {
    let uniqueId = "SomethingUnique";
    self.voucher = VoucherClient(uniqueSharedId: uniqueId)
    
    self.voucher.startSearchingWithCompletion { [unowned self] authData, displayName, error in

        // (authData is of type NSData)
        if authData != nil {
            // User granted permission on iOS app!
            self.authenticationSucceeded(authData!, from: displayName)
        } else {
            self.authenticationFailed()
        }
    }
}

iOS (Providing Auth)

If your iOS app has auth credentials, it should start a Voucher Server, so it can answer any requests for a login. I'd recommend starting the server when (and if) the user is logged in.

import Voucher

func startVoucherServer() {
    let uniqueId = "SomethingUnique"
    self.server = VoucherServer(uniqueSharedId: uniqueId)

    self.server.startAdvertisingWithRequestHandler { (displayName, responseHandler) -> Void in

        let alertController = UIAlertController(title: "Allow Auth?", message: "Allow \"\(displayName)\" access to your login?", preferredStyle: .Alert)
        alertController.addAction(UIAlertAction(title: "Not Now", style: .Cancel, handler: { action in
            responseHandler(nil, nil)
        }))

        alertController.addAction(UIAlertAction(title: "Allow", style: .Default, handler: { action in
            let authData = "THIS IS AN AUTH TOKEN".dataUsingEncoding(NSUTF8StringEncoding)!
            responseHandler(authData, nil)
        }))

        self.presentViewController(alertController, animated: true, completion: nil)
        
    }
}

Recommendations

Use tokens, not passwords

While you can send whatever data you like back to tvOS, you should you pass back an OAuth token, or better yet, generate some kind of a single-use token on your server and send that. Cluster, for example, uses single-use tokens to do auto-login from web to iOS app. Check out this Medium post that shows how I do it! The same model can apply for iOS to tvOS logins.

Voucher can't be the only login option

In your login screen, you must still show the manual entry UI according to the App Store Submission Guidelines (Section 2.27). Add messaging that, in addition to the on screen form, the user can simply open the iOS app to login.

Todo / Things I'd Love Your Help With!

  • Encryption? Currently Voucher does not encrypt any data between the server and the client, so I suppose if someone wanted your credentials (See Recommendations section above), they could have a packet sniffer on your local network and access your credentials.

  • Make Voucher Server work on OS X, and even tvOS! Would probably just need new framework targets, and additional test apps.

Further Reading

Check out Benny Wong's post on why Apple TV sign in sucks. He also has a demo tvOS Authing project, which you should check out!

Requirements

  • iOS 7.0 and above
  • tvOS 9.0
  • Xcode 8

License

Voucher is available using an MIT license. See the LICENSE file for more info.

I'd Love to Know If You're Using Voucher!

Post to this Github "issue" I made to help us track who's using Voucher šŸ‘

Comments
  • Not working in real device.

    Not working in real device.

    Hi, probably this isn't a library issue. I'm implementing this library and works like a charm with any iOS device as a server and Apple TV Simulator, but when I run it on a real Apple TV, the client doesn't find the server. Am I missing something? Like a said, it works perfectly with TV Simulator but not on a real device.

    Thanks!

    opened by FernandoReynoso 1
  • Correct the spelling of CocoaPods in README

    Correct the spelling of CocoaPods in README

    This pull requests corrects the spelling of CocoaPods šŸ¤“ https://github.com/CocoaPods/shared_resources/tree/master/media

    Created with cocoapods-readme.

    opened by ReadmeCritic 0
  • Not getting authorization request in IOS device immediately

    Not getting authorization request in IOS device immediately

    I'm running this code of both the tvos and ios app in the simulator. In logs of the tvos app its showing this error NSStreamErrorOccurred (fallthrough)

    And after one minute i'm getting Authrization request in IOS device.

    am i missing something ?

    2020-01-25 12:28:18.180661+0530 Voucher tvOS App[68664:767659] Browser will search 2020-01-25 12:28:25.085173+0530 Voucher tvOS App[68664:767659] Browser found service: iPhone 11 Pro Max, more coming: NO 2020-01-25 12:29:40.464556+0530 Voucher tvOS App[68664:778604] [] nw_socket_handle_socket_event [C5.1.1:1] Socket SO_ERROR [60: Operation timed out] 2020-01-25 12:29:40.466096+0530 Voucher tvOS App[68664:779648] [] nw_connection_get_connected_socket [C5] Client called nw_connection_get_connected_socket on unconnected nw_connection 2020-01-25 12:29:40.466587+0530 Voucher tvOS App[68664:779648] TCP Conn 0x6000010eda40 Failed : error 0:60 [60] 2020-01-25 12:29:40.466913+0530 Voucher tvOS App[68664:767659] NSStreamErrorOccurred (fallthrough) 2020-01-25 12:29:40.467225+0530 Voucher tvOS App[68664:767659] NSStreamEventEndEncountered 2020-01-25 12:29:40.467374+0530 Voucher tvOS App[68664:767659] => Input Stream 2020-01-25 12:30:56.072708+0530 Voucher tvOS App[68664:779650] [] nw_socket_handle_socket_event [C6.1.1:1] Socket SO_ERROR [60: Operation timed out] 2020-01-25 12:30:56.073919+0530 Voucher tvOS App[68664:780808] [] nw_connection_get_connected_socket [C6] Client called nw_connection_get_connected_socket on unconnected nw_connection 2020-01-25 12:30:56.074235+0530 Voucher tvOS App[68664:780808] TCP Conn 0x6000010e1080 Failed : error 0:60 [60] 2020-01-25 12:30:56.074448+0530 Voucher tvOS App[68664:767659] NSStreamErrorOccurred (fallthrough) 2020-01-25 12:30:56.074604+0530 Voucher tvOS App[68664:767659] NSStreamEventEndEncountered 2020-01-25 12:30:56.074772+0530 Voucher tvOS App[68664:767659] => Input Stream 2020-01-25 12:30:56.310391+0530 Voucher tvOS App[68664:767659] Input stream open 2020-01-25 12:30:56.310522+0530 Voucher tvOS App[68664:767659] Output stream open 2020-01-25 12:30:56.310635+0530 Voucher tvOS App[68664:767659] Output stream has space available 2020-01-25 12:30:56.310846+0530 Voucher tvOS App[68664:767659] Sent 295 bytes 2020-01-25 12:30:56.310947+0530 Voucher tvOS App[68664:767659] Finished sending whole data buffer 2020-01-25 12:30:56.311054+0530 Voucher tvOS App[68664:767659] Output stream has space available

    opened by bc1213 0
  • Voucher Server stopped publishing, due to error: -72004

    Voucher Server stopped publishing, due to error: -72004

    Voucher Server stopped publishing, due to error: -72004

    This seems related to the uniqueSharedId that is provided to either the client or server. I tested this with different IDs and had these results:

    weoripuwieur;uqwer: Error. weoripuwieuruqwer: Works.

    This error seems to be caused by provided 'special' characters in the unique ID field. The server will not launch and will produce this error code, plus the client will also not launch and will produce this error code in a different way. Could this be confirmed?

    opened by SirArkimedes 0
  • Feature request: Using Symmetric-key algorithm AES? to protect data transfer?

    Feature request: Using Symmetric-key algorithm AES? to protect data transfer?

    Using Symmetric-key algorithm AES (or something like that) to protect data transfer if the TV & iPhone communicated via open wifi ?

    the key can show (via text/QR?) on TV Screen (random generated, or encrypt the key again in code) or just embed the key in code...

    opened by ryh 4
  • Post here if you use Voucher for your app!

    Post here if you use Voucher for your app!

    It would be really cool to know if you're using Voucher, so post in here what your project or app is, with a link!

    Screenshots would be awesome too, to see how you've built the auth process! :+1:

    help wanted 
    opened by rsattar 5
Owner
Riz
Riz
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
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
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
An poc to make a login using Auth0 in Swift

Swift-Auth0-poc This app is an poc to make a login using Auth0. If you want to try it yourself here is a small tutorial on how to do it. 1. Configure

Sem de Wilde 1 Jan 21, 2022
Easy to use OAuth 2 library for iOS, written in Swift.

Heimdallr Heimdallr is an OAuth 2.0 client specifically designed for easy usage. It currently supports the resource owner password credentials grant f

trivago N.V. 628 Oct 17, 2022
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
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
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
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
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
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
LinkedInSignIn - Simple view controller to log in and retrieve an access token from LinkedIn.

LinkedInSignIn Example To run the example project, clone the repo, and run pod install from the Example directory first. Also you need to setup app on

Serhii Londar 34 Sep 1, 2022
A quick and simple way to authenticate an Instagram user in your iPhone or iPad app.

InstagramSimpleOAuth A quick and simple way to authenticate an Instagram user in your iPhone or iPad app. Adding InstagramSimpleOAuth to your project

Ryan Baumbach 90 Aug 20, 2022
A quick and simple way to authenticate a Dropbox user in your iPhone or iPad app.

DropboxSimpleOAuth A quick and simple way to authenticate a Dropbox user in your iPhone or iPad app. Adding DropboxSimpleOAuth to your project CocoaPo

Ryan Baumbach 42 Dec 29, 2021
A quick and simple way to authenticate a Box user in your iPhone or iPad app.

BoxSimpleOAuth A quick and simple way to authenticate a Box user in your iPhone or iPad app. Adding BoxSimpleOAuth to your project CocoaPods CocoaPods

Ryan Baumbach 15 Mar 10, 2021
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
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