Add iOS app with CarPlay and Siri
SwiftUI port of the Android app under ios/, with CarPlay browse and Now Playing, Siri play-media intents, and a build-ipa.sh script that makes an unsigned IPA for sideloading. README gets an iOS section and the vibecoded disclaimer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
45bc0eefe0
commit
fdf9e970b2
45 files changed
+9822
No files matched your search
@@ -0,0 +1,33 @@
|
||||
import Intents
|
||||
|
||||
/// "Hey Siri, play … on Stemify". Handled in the app process, so it can start playback directly.
|
||||
final class PlayMediaHandler: NSObject, INPlayMediaIntentHandling {
|
||||
func resolveMediaItems(for intent: INPlayMediaIntent) async -> [INPlayMediaMediaItemResolutionResult] {
|
||||
let q = intent.mediaSearch?.mediaName ?? intent.mediaSearch?.artistName ?? intent.mediaSearch?.albumName ?? ""
|
||||
let item = INMediaItem(identifier: "search:\(q)", title: q.isEmpty ? "Downloads" : q, type: .music, artwork: nil)
|
||||
return INPlayMediaMediaItemResolutionResult.successes(with: [item])
|
||||
}
|
||||
|
||||
func handle(intent: INPlayMediaIntent) async -> INPlayMediaIntentResponse {
|
||||
let s = intent.mediaSearch
|
||||
let q = s?.mediaName ?? s?.artistName ?? s?.albumName ?? intent.mediaItems?.first?.title ?? ""
|
||||
let shuffle = intent.playShuffled == true
|
||||
let ok = await Self.play(q, shuffle)
|
||||
return INPlayMediaIntentResponse(code: ok ? .success : .failure, userActivity: nil)
|
||||
}
|
||||
|
||||
@MainActor static func play(_ query: String, _ shuffle: Bool) async -> Bool {
|
||||
let g = AppGraph.shared
|
||||
do {
|
||||
guard let r = try await g.car.resolveSearch(query) else {
|
||||
g.playback.report(query.isEmpty ? "Nothing downloaded yet" : "Nothing found for “\(query)”")
|
||||
return false
|
||||
}
|
||||
g.playback.playTracks(r.tracks, start: r.start, shuffle: r.shuffle || shuffle)
|
||||
return true
|
||||
} catch {
|
||||
g.playback.report(error is NotSignedIn ? "Sign in to Plex on your phone" : "Couldn't load that: \(error.localizedDescription)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user