Skip to content

Instantly share code, notes, and snippets.

@Czajnikowski
Last active May 5, 2023 08:17
Show Gist options
  • Save Czajnikowski/5eed414975baec3dbb0b59f3316eecfa to your computer and use it in GitHub Desktop.
Save Czajnikowski/5eed414975baec3dbb0b59f3316eecfa to your computer and use it in GitHub Desktop.
A problematic implementation (FB12168694) that doesnt seem to respect changing the ApplicationMusicPlayer.state.playbackRate on iOS 16.4.1 (and possibly other iOS versions). Related discussion here: https://developer.apple.com/forums/thread/702397?answerId=752470022#752470022
import MusicKit
import Foundation
public class AppleMusicPlayer {
private let musicPlayer = ApplicationMusicPlayer.shared
public init() {}
@Sendable public func prepareToPlay(songID: String) async throws {
guard let item = await MusicCatalog.song(withID: songID) else {
throw Unity.instance
}
musicPlayer.queue = [item]
do {
try await musicPlayer.prepareToPlay()
} catch {
throw Unity.instance
}
}
@Sendable public func playPause() {
if musicPlayer.state.playbackStatus == .playing {
musicPlayer.pause()
} else {
Task {
do {
musicPlayer.state.playbackRate = 0.5
try await musicPlayer.play()
musicPlayer.state.playbackRate = 0.5
}
catch {
print(error)
}
}
}
}
}
public enum MusicCatalog {
public static func song(withID songID: String) async -> Song? {
guard MusicAuthorization.currentStatus == .authorized else {
return nil
}
let song: Song?
do {
let searchResponse = try await MusicCatalogResourceRequest<Song>(
matching: \.id,
equalTo: MusicItemID(songID)
).response()
song = searchResponse.items.first!
} catch {
print("Music Catalog request failed with error: \(error)")
song = nil
}
return song
}
}
public enum Unity: Hashable {
case instance
}
extension Unity: Error {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment