Skip to content

Commit

Permalink
Work on initial data update
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathangarelick committed May 7, 2024
1 parent a2b5dfb commit bceb58f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 27 deletions.
2 changes: 2 additions & 0 deletions SoundSeer/Application/Application.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
protocol Application {
static var shared: Application { get }

var playerState: PlayerState { get }

func copySongURL()
func nextTrack()
func revealSong()
Expand Down
7 changes: 7 additions & 0 deletions SoundSeer/Application/MusicApplication.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import AppKit

class MusicApplication: Application {
static let bundleID = "com.apple.Music"
static let notificationName = Notification.Name("com.apple.Music.playerInfo")

private static let instance = MusicApplication()

let app = AppleMusicBridge.appleMusicApplication()
Expand All @@ -13,6 +16,10 @@ class MusicApplication: Application {
instance
}

var playerState: PlayerState {
PlayerState(app?.playerState)
}

func copySongURL() {
guard let songId = songId, let albumId = albumId else { return }

Expand Down
7 changes: 7 additions & 0 deletions SoundSeer/Application/SpotifyApplication.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import AppKit

class SpotifyApplication: Application {
static let bundleID = "com.spotify.client"
static let notificationName = Notification.Name("com.spotify.client.PlaybackStateChanged")

private static let instance = SpotifyApplication()

static var shared: Application {
Expand All @@ -15,6 +18,10 @@ class SpotifyApplication: Application {

private init() {}

var playerState: PlayerState {
PlayerState(app?.playerState)
}

func copySongURL() {
guard let songId = songId else { return }

Expand Down
46 changes: 19 additions & 27 deletions SoundSeer/Models/PlayerModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,29 @@ class PlayerModel {
@Published var currentAlbum: String = ""
@Published var currentAlbumId: String = ""

private let spotifyApp: AnyObject
let musicApp: AnyObject = SBApplication(bundleIdentifier: "com.apple.Music")!

private let notificationCenter = DistributedNotificationCenter.default()
private let notificationName = Notification.Name("com.spotify.client.PlaybackStateChanged")

let musicNotificationName = Notification.Name("com.apple.Music.playerInfo")

init?() {
guard let spotifyApp = SBApplication(bundleIdentifier: "com.spotify.client") else {
Logger.model.error("Could not find Spotify application")
if !Utils.isAppInstalled(MusicApplication.bundleID),
!Utils.isAppInstalled(SpotifyApplication.bundleID) {
Logger.model.error("Could not find Apple Music or Spotify application")
return nil
}

// let myApp = SBApplication(bundleIdentifier: "com.spotify.client") as? SBSpotifyApplication

// print(myApp?.shuffling)
SpotifyBridge.spotifyApplication().play()

self.spotifyApp = spotifyApp

// Need to trigger a "fake" event when SoundSeer is first opened
// Logger.model.debug("Performing initial update")
// update()
Logger.model.debug("Performing initial update")
if Utils.isAppRunning(MusicApplication.bundleID) {
doInitialUpdate(MusicApplication.shared)
} else if Utils.isAppRunning(SpotifyApplication.bundleID) {
doInitialUpdate(SpotifyApplication.shared)
} else {
Logger.model.debug("Neither app is running, waiting quietly...")
}

Logger.model.debug("Subscribing to Spotify playback change events")
notificationCenter.addObserver(forName: notificationName, object: nil, queue: nil) { [weak self] in
DistributedNotificationCenter.default().addObserver(forName: SpotifyApplication.notificationName, object: nil, queue: nil) { [weak self] in
self?.update(PlayerStateNotification(SpotifyApplication.shared, $0))
}

Logger.model.debug("Subscribing to Apple Music playback change events")
notificationCenter.addObserver(forName: musicNotificationName, object: nil, queue: nil) { [weak self] in
DistributedNotificationCenter.default().addObserver(forName: MusicApplication.notificationName, object: nil, queue: nil) { [weak self] in
self?.update(PlayerStateNotification(MusicApplication.shared, $0))
}
}
Expand All @@ -53,11 +44,6 @@ class PlayerModel {
DistributedNotificationCenter.default().removeObserver(self)
}

func nextTrack() {
Logger.model.debug("Skipping track")
spotifyApp.nextTrack?()
}

private func resetData() {
Logger.model.debug("Resetting data")
playerState = .stopped
Expand All @@ -69,6 +55,12 @@ class PlayerModel {
currentAlbumId = ""
}

private func doInitialUpdate(_ application: Application) {
currentApplication = application
playerState = application.playerState
// do more
}

private func update(_ notification: PlayerStateNotification?) {
guard let notification = notification else {
Logger.model.error("Received bad event. Discarding")
Expand Down
5 changes: 5 additions & 0 deletions SoundSeer/Utils.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import AppKit

enum Utils {
static func isAppInstalled(_ bundleIdentifier: String) -> Bool {
let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleIdentifier)
return url != nil
}

static func isAppRunning(_ bundleIdentifier: String) -> Bool {
return NSWorkspace.shared.runningApplications
.filter { $0.bundleIdentifier == bundleIdentifier }.count > 0
Expand Down

0 comments on commit bceb58f

Please sign in to comment.