Absturz beim Abspielen, und die Annahme dahinter
Der Crashlog vom Gerät:
_dispatch_assert_queue_fail
_swift_task_checkIsolatedSwift
MainActor.assumeIsolated
VLCPlayerEngine.mediaPlayerStateChanged(_:)
VLCKit input_thread_Events
Im Code stand als Begründung für assumeIsolated, VLCKit stelle seine
Rückrufe über die Hauptwarteschlange zu. Das ist falsch — es ruft den
Delegaten von seinem eigenen Input-Thread. Die App brach deshalb hart
ab, sobald VLC den ersten Zustandswechsel meldete, also unmittelbar
beim Drücken auf Play.
Alle drei Delegat-Methoden springen jetzt mit Task { @MainActor in }
sauber hinüber. Die Reihenfolge bleibt erhalten: die Aufgaben werden aus
demselben Thread nacheinander eingereiht.
Dieselbe Annahme steckte im AVPlayer-Motor in den KVO-Beobachtern —
KVO meldet auf dem Thread, der die Änderung ausgelöst hat, und AVPlayer
ändert seinen Zustand auch aus internen Threads. Ebenfalls umgestellt.
Die beiden Rückrufe mit ausdrücklichem queue: .main behalten
assumeIsolated: dort ist die Annahme belegt statt geraten, und der
Zeitbeobachter feuert viermal je Sekunde.
Dazu die Anmeldung: Plex führt den Rücksprung über forwardUrl nicht
zuverlässig aus. Auf dem iPad landet der Browser nach dem Anmelden auf
watch.plex.tv und bleibt stehen — der Token liegt bereit, aber die App
wartete auf einen Rückruf, der nie kam. Das Fenster wird jetzt geöffnet,
ohne darauf zu warten; parallel wird im Sekundentakt beim Server
nachgefragt. Der Rücksprung ist damit eine Annehmlichkeit, keine
Voraussetzung.
132 Tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,23 @@ public actor PlexAuthenticator {
|
||||
)
|
||||
}
|
||||
|
||||
/// Fragt einmal nach, ob der Code inzwischen bestätigt wurde.
|
||||
///
|
||||
/// Gibt `nil` zurück, solange er es nicht ist. Für Aufrufer, die ihre
|
||||
/// eigene Schleife führen — etwa weil sie nebenher noch auf das Schließen
|
||||
/// eines Anmeldefensters achten müssen.
|
||||
public func token(for pin: PlexPin) async throws(PlexError) -> String? {
|
||||
let current = try await client.send(
|
||||
PlexRequest(path: "/api/v2/pins/\(pin.id)"),
|
||||
as: PlexPin.self
|
||||
)
|
||||
guard let token = current.authToken, !token.isEmpty else { return nil }
|
||||
|
||||
try? tokenStore.store(token, for: Self.accountTokenAccount)
|
||||
await client.setToken(token)
|
||||
return token
|
||||
}
|
||||
|
||||
/// Wartet darauf, dass der Nutzer den Code im Browser bestätigt.
|
||||
///
|
||||
/// Plex bietet keinen Rückkanal — es bleibt nur regelmäßiges Nachfragen.
|
||||
|
||||
Reference in New Issue
Block a user