4 // Protocol to obtain the track from
5 @objc protocol AppleMusicTrack {
6 @objc optional var name: String {get}
7 @objc optional var artist: String {get}
10 // Protocol to interact with Apple Music
11 @objc protocol AppleMusicApplication {
12 @objc optional var currentTrack: AppleMusicTrack? {get}
13 @objc optional var currentStreamTitle: String? {get}
16 extension SBApplication: AppleMusicApplication {}
18 // Source that reads track artist and name from current itunes track
19 class AppleMusicSource: Source {
21 // Calls the spotify API and returns the current track
22 var currentTrack: Track? {
24 if let appleMusic: AppleMusicApplication = SBApplication(bundleIdentifier: bundleIdentifier) {
25 if let application = appleMusic as? SBApplication {
26 if !application.isRunning {
31 // Attempt to fetch the title from a stream
32 if let currentStreamTitle = appleMusic.currentStreamTitle {
33 if let track = currentStreamTitle {
35 let trackComponents = track.split(separator: "-").map(String.init)
37 if trackComponents.count == 2 {
38 let artist = trackComponents[0].trimmingCharacters(in: .whitespaces)
39 let name = trackComponents[1].trimmingCharacters(in: .whitespaces)
41 return Track(withName: name, andArtist: artist)
47 // Attempt to fetch the title from a song
48 if let currentTrack = appleMusic.currentTrack {
49 if let track = currentTrack {
50 if let name = track.name {
51 if let artist = track.artist {
53 // track properties are empty strings if itunes is closed
54 if name == "" || artist == "" {
57 return Track(withName: name, andArtist: artist)
67 private var bundleIdentifier: String {
68 if ProcessInfo().isOperatingSystemAtLeast(
69 OperatingSystemVersion(majorVersion: 10, minorVersion: 15, patchVersion: 0)
71 return "com.apple.Music"
74 return "com.apple.iTunes"
77 func enable() -> Bool { return true }
78 func disable() -> Bool { return true }
79 func reset() -> Bool { return true }