Latest 3.0.1
Homepage https://github.com/eMdOS/AirPlay
License MIT
Platforms ios 8.0, requires ARC
Frameworks MediaPlayer, AVFoundation
Authors

CI Status
Version
License
Platform

AirPlay lets users track iOS AirPlay availability and provides extra information about AirPlay connections.

Requirements

  • Xcode 7+
  • iOS 8+
  • CocoaPods 0.39.0

XcodeVersion
Swift
CocoaPods

Support

iOSSupport

Currently, this library is a kind of workaround to be able to track AirPlay availability observing changes on MPVolumeView. So, it needs to be tested every new iOS release.

If there is an Apple TV or other AirPlay-enabled device in range, the route button allows the user to choose it. If there is only one audio output route available, the route button is not displayed.

Usage

Notifications, Properties, Methods, Closures

Notifications

Notification Description
AirPlayAvailabilityChangedNotification Notification sent everytime AirPlay availability changes.
AirPlayRouteStatusChangedNotification Notification sent everytime AirPlay connection route changes.

Properties

Property Description
isPossible Returns true or false if there are or not available devices for casting via AirPlay. (read-only)
isBeingMonitored Returns true or false if AirPlay availability is being monitored or not. (read-only)
isConnected Returns true or false if device is connected or not to a second device via AirPlay. (read-only)
connectedDevice Returns Device’s name if connected, if not, it returns nil. (read-only)

Methods

Method Description
startMonitoring() Starts monitoring AirPlay availability changes
stopMonitoring() Stops monitoring AirPlay availability changes

Closures

Closure Description
whenPossible Block of code to execute when AirPlay is possible
whenNotPossible Block of code to execute when AirPlay is not possible
whenConnectionChanged Block of code to execute when AirPlay connects/disconnects

Start Monitoring

What I use to do is to start monitoring in the AppDelegate. It can be implemented anywhere.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    AirPlay.startMonitoring()

    return true
}

Adding/Removing Observers

To add them:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "<selector>", name: AirPlayAvailabilityChangedNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "<selector>", name: AirPlayRouteStatusChangedNotification, object: nil)

To remove them:

NSNotificationCenter.defaultCenter().removeObserver(self, name: AirPlayAvailabilityChangedNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: AirPlayRouteStatusChangedNotification, object: nil)

Using closures

When possible:

AirPlay.whenPossible = { _ in
    <code>
}

When not possible:

AirPlay.whenNotPossible = { _ in
    <code>
}

When connection changed:

AirPlay.whenConnectionChanged = { _ in
    <code>
}

Displaying AirPlay availability status

AirPlay.isPossible will return true or false.

Displaying AirPlay connection status

AirPlay.isConnected will return true of false.

Displaying connected device name

AirPlay.connectedDevice ?? "Unknown Device"

Examples

Example using Protocol Extensions and Constraints

Assuming we have a class called Player which extends from UIViewController.

AirPlayCastable protocol:

protocol AirPlayCastable: class {
    func airplayDidChangeAvailability(notification: NSNotification)
    func airplayCurrentRouteDidChange(notification: NSNotification)
}

AirPlayCastable extension and constraint:

extension AirPlayCastable where Self: Player {
    func registerForAirPlayAvailabilityChanges() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "airplayDidChangeAvailability:", name: AirPlayAvailabilityChangedNotification, object: nil)
    }

    func registerForAirPlayRouteChanges() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "airplayCurrentRouteDidChange:", name: AirPlayRouteStatusChangedNotification, object: nil)
    }

    func unregisterForAirPlayAvailabilityChanges() {
        NSNotificationCenter.defaultCenter().removeObserver(self, name: AirPlayAvailabilityChangedNotification, object: nil)
    }

    func unregisterForAirPlayRouteChanges() {
        NSNotificationCenter.defaultCenter().removeObserver(self, name: AirPlayRouteStatusChangedNotification, object: nil)
    }
}

Then, in Player class…

Registering:

override func viewDidLoad() {
    super.viewDidLoad()
    registerForAirPlayAvailabilityChanges()
    registerForAirPlayRouteChanges()
}

Unregistering:

deinit {
    unregisterForAirPlayAvailabilityChanges()
    unregisterForAirPlayRouteChanges()
}

Updating UI:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    updateUI()
}

private func updateUI() {
    airplayStatus.text = AirPlay.isPossible ? "Possible" : "Not Possible"
    if AirPlay.isConnected {
        let device = AirPlay.connectedDevice ?? "Unknown Device"
        airplayConnectionStatus.text = "Connected to: (device)"
    } else {
        airplayConnectionStatus.text = "Not Connected"
    }
}

Listening:

extension Player: AirPlayCastable {
    func airplayDidChangeAvailability(notification: NSNotification) {
        updateUI()
    }

    func airplayCurrentRouteDidChange(notification: NSNotification) {
        updateUI()
    }
}

Example using closures

Setting-up closures:

override func viewDidLoad() {
    super.viewDidLoad()
    airplayStuffs()
}

private func airplayStuffs() {
    AirPlay.whenPossible = { _ in
        print("Possible = (AirPlay.isPossible)")
        self.updateUI()
    }

    AirPlay.whenNotPossible = { _ in
        print("Not Possible = (AirPlay.isPossible)")
        self.updateUI()
    }

    AirPlay.whenConnectionChanged = { _ in
        print("Connection has changed... Connected: (AirPlay.isConnected)")
        self.updateUI()
    }
}

Updating UI:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    updateUI()
}

private func updateUI() {
    airplayStatus.text = AirPlay.isPossible ? "Possible" : "Not Possible"
    if AirPlay.isConnected {
        let device = AirPlay.connectedDevice ?? "Unknown Device"
        airplayConnectionStatus.text = "Connected to: (device)"
    } else {
        airplayConnectionStatus.text = "Not Connected"
    }
}

Installation

AirPlay is available through CocoaPods. To install it, simply add pod "AirPlay" to your podfile, and run pod install.

Author

eMdOS

License

AirPlay is available under the MIT license. See the LICENSE file for more info.

Latest podspec

{
    "name": "AirPlay",
    "version": "3.0.1",
    "summary": "AirPlay lets users track iOS AirPlay availability and provides extra information about AirPlay connection status.",
    "homepage": "https://github.com/eMdOS/AirPlay",
    "license": "MIT",
    "authors": {
        "eMdOS": "[email protected]"
    },
    "source": {
        "git": "https://github.com/eMdOS/AirPlay.git",
        "tag": "v3.0.1"
    },
    "social_media_url": "https://twitter.com/_eMdOS_",
    "platforms": {
        "ios": "8.0"
    },
    "requires_arc": true,
    "source_files": "Sources/",
    "frameworks": [
        "MediaPlayer",
        "AVFoundation"
    ],
    "pushed_with_swift_version": "3.0"
}

Pin It on Pinterest

Share This