fix native playback build blockers

This commit is contained in:
dirtydishes 2026-05-24 23:23:14 -04:00
parent d28540ce98
commit b15e4d640e
5 changed files with 48 additions and 2 deletions

View file

@ -3,3 +3,4 @@
{"id":"int-d8dc4ec5","kind":"field_change","created_at":"2026-05-25T01:25:35.590554Z","actor":"dirtydishes","issue_id":"dreamio-tnv","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Added bundle metadata to Info.plist and validated processed app bundle identifier."}} {"id":"int-d8dc4ec5","kind":"field_change","created_at":"2026-05-25T01:25:35.590554Z","actor":"dirtydishes","issue_id":"dreamio-tnv","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Added bundle metadata to Info.plist and validated processed app bundle identifier."}}
{"id":"int-a86e17e0","kind":"field_change","created_at":"2026-05-25T02:34:54.605755Z","actor":"dirtydishes","issue_id":"dreamio-evt","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented debug-only WKWebView inspection, token-safe playback diagnostics, navigation logging, validation build, and turn documentation."}} {"id":"int-a86e17e0","kind":"field_change","created_at":"2026-05-25T02:34:54.605755Z","actor":"dirtydishes","issue_id":"dreamio-evt","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented debug-only WKWebView inspection, token-safe playback diagnostics, navigation logging, validation build, and turn documentation."}}
{"id":"int-4d73c126","kind":"field_change","created_at":"2026-05-25T03:20:17.439589Z","actor":"dirtydishes","issue_id":"dreamio-l68","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented native direct-stream bridge, classification, MobileVLCKit backend wiring, CocoaPods workflow docs, and turn documentation. Full iOS build is blocked locally by missing CocoaPods and iPhoneOS SDK."}} {"id":"int-4d73c126","kind":"field_change","created_at":"2026-05-25T03:20:17.439589Z","actor":"dirtydishes","issue_id":"dreamio-l68","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented native direct-stream bridge, classification, MobileVLCKit backend wiring, CocoaPods workflow docs, and turn documentation. Full iOS build is blocked locally by missing CocoaPods and iPhoneOS SDK."}}
{"id":"int-3dbe205a","kind":"field_change","created_at":"2026-05-25T03:23:00.515861Z","actor":"dirtydishes","issue_id":"dreamio-2lp","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Fixed Swift raw string escaping and guarded MobileVLCKit import for builds before pod install."}}

View file

@ -1,3 +1,4 @@
{"_type":"issue","id":"dreamio-2lp","title":"Fix native playback build blockers","description":"Correct Swift string escaping for the injected stream bridge and allow the VLC backend source to compile before MobileVLCKit is installed by guarding the import with canImport.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T03:22:52Z","created_by":"dirtydishes","updated_at":"2026-05-25T03:23:00Z","started_at":"2026-05-25T03:23:00Z","closed_at":"2026-05-25T03:23:00Z","close_reason":"Fixed Swift raw string escaping and guarded MobileVLCKit import for builds before pod install.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"dreamio-l68","title":"Add native playback for direct debrid streams","description":"Implement a WKWebView JavaScript bridge that detects direct-file debrid media URLs and routes unsupported containers to a native player backend, initially MobileVLCKit, while preserving normal Stremio Web playback for compatible streams.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T03:13:19Z","created_by":"dirtydishes","updated_at":"2026-05-25T03:20:17Z","started_at":"2026-05-25T03:13:28Z","closed_at":"2026-05-25T03:20:17Z","close_reason":"Implemented native direct-stream bridge, classification, MobileVLCKit backend wiring, CocoaPods workflow docs, and turn documentation. Full iOS build is blocked locally by missing CocoaPods and iPhoneOS SDK.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-l68","title":"Add native playback for direct debrid streams","description":"Implement a WKWebView JavaScript bridge that detects direct-file debrid media URLs and routes unsupported containers to a native player backend, initially MobileVLCKit, while preserving normal Stremio Web playback for compatible streams.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T03:13:19Z","created_by":"dirtydishes","updated_at":"2026-05-25T03:20:17Z","started_at":"2026-05-25T03:13:28Z","closed_at":"2026-05-25T03:20:17Z","close_reason":"Implemented native direct-stream bridge, classification, MobileVLCKit backend wiring, CocoaPods workflow docs, and turn documentation. Full iOS build is blocked locally by missing CocoaPods and iPhoneOS SDK.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"dreamio-tnv","title":"Fix iOS bundle identifier install failure","description":"Xcode built Dreamio.app without a valid CFBundleIdentifier, causing device install to fail with CoreDeviceError 3000/3002. Investigate project bundle settings, fix the source configuration, validate the app bundle Info.plist, and document the change.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T01:23:00Z","created_by":"dirtydishes","updated_at":"2026-05-25T01:25:36Z","started_at":"2026-05-25T01:23:07Z","closed_at":"2026-05-25T01:25:36Z","close_reason":"Added bundle metadata to Info.plist and validated processed app bundle identifier.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-tnv","title":"Fix iOS bundle identifier install failure","description":"Xcode built Dreamio.app without a valid CFBundleIdentifier, causing device install to fail with CoreDeviceError 3000/3002. Investigate project bundle settings, fix the source configuration, validate the app bundle Info.plist, and document the change.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T01:23:00Z","created_by":"dirtydishes","updated_at":"2026-05-25T01:25:36Z","started_at":"2026-05-25T01:23:07Z","closed_at":"2026-05-25T01:25:36Z","close_reason":"Added bundle metadata to Info.plist and validated processed app bundle identifier.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"dreamio-4yn","title":"Build WKWebView MVP shell","description":"Create the first Dreamio MVP implementation: a minimal iOS WKWebView wrapper around hosted Stremio Web, with configuration, launch behavior, diagnostics, and documentation for real-device viability testing.","acceptance_criteria":"App project exists; WKWebView loads hosted Stremio Web; external/new-window navigation is handled; basic diagnostics and manual test documentation exist; quality gates are run or documented.","status":"closed","priority":1,"issue_type":"feature","owner":"dishes@dpdrm.com","created_at":"2026-05-24T14:55:12Z","created_by":"dirtydishes","updated_at":"2026-05-24T14:59:44Z","closed_at":"2026-05-24T14:59:44Z","close_reason":"Implemented the MVP WKWebView iOS shell, added run and validation documentation, and recorded current validation limits.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-4yn","title":"Build WKWebView MVP shell","description":"Create the first Dreamio MVP implementation: a minimal iOS WKWebView wrapper around hosted Stremio Web, with configuration, launch behavior, diagnostics, and documentation for real-device viability testing.","acceptance_criteria":"App project exists; WKWebView loads hosted Stremio Web; external/new-window navigation is handled; basic diagnostics and manual test documentation exist; quality gates are run or documented.","status":"closed","priority":1,"issue_type":"feature","owner":"dishes@dpdrm.com","created_at":"2026-05-24T14:55:12Z","created_by":"dirtydishes","updated_at":"2026-05-24T14:59:44Z","closed_at":"2026-05-24T14:59:44Z","close_reason":"Implemented the MVP WKWebView iOS shell, added run and validation documentation, and recorded current validation limits.","dependency_count":0,"dependent_count":0,"comment_count":0}

View file

@ -54,7 +54,7 @@ final class DreamioWebViewController: UIViewController {
private var lastNativePlaybackURL: URL? private var lastNativePlaybackURL: URL?
private static let streamCandidateScript = WKUserScript( private static let streamCandidateScript = WKUserScript(
source: """ source: #"""
(() => { (() => {
if (window.__dreamioStreamBridgeInstalled) { if (window.__dreamioStreamBridgeInstalled) {
return; return;
@ -181,7 +181,7 @@ final class DreamioWebViewController: UIViewController {
inspectMedia(document); inspectMedia(document);
})(); })();
""", """#,
injectionTime: .atDocumentStart, injectionTime: .atDocumentStart,
forMainFrameOnly: false forMainFrameOnly: false
) )

View file

@ -1,24 +1,34 @@
import UIKit import UIKit
#if canImport(MobileVLCKit)
import MobileVLCKit import MobileVLCKit
#endif
final class VLCNativePlaybackBackend: NSObject, NativePlaybackBackend { final class VLCNativePlaybackBackend: NSObject, NativePlaybackBackend {
let view = UIView() let view = UIView()
var onReady: (() -> Void)? var onReady: (() -> Void)?
var onFailure: ((Error) -> Void)? var onFailure: ((Error) -> Void)?
#if canImport(MobileVLCKit)
private let mediaPlayer = VLCMediaPlayer() private let mediaPlayer = VLCMediaPlayer()
#endif
override init() { override init() {
super.init() super.init()
#if canImport(MobileVLCKit)
mediaPlayer.delegate = self mediaPlayer.delegate = self
#endif
view.backgroundColor = .black view.backgroundColor = .black
} }
func prepare(in viewController: UIViewController) { func prepare(in viewController: UIViewController) {
#if canImport(MobileVLCKit)
mediaPlayer.drawable = view mediaPlayer.drawable = view
#endif
} }
func play(request: NativePlaybackRequest) { func play(request: NativePlaybackRequest) {
#if canImport(MobileVLCKit)
let media = VLCMedia(url: request.playbackURL) let media = VLCMedia(url: request.playbackURL)
var headers = ["Referer": request.referer] var headers = ["Referer": request.referer]
if let userAgent = request.userAgent { if let userAgent = request.userAgent {
@ -36,14 +46,20 @@ final class VLCNativePlaybackBackend: NSObject, NativePlaybackBackend {
mediaPlayer.media = media mediaPlayer.media = media
mediaPlayer.play() mediaPlayer.play()
#else
onFailure?(NativePlaybackError.backendUnavailable)
#endif
} }
func stop() { func stop() {
#if canImport(MobileVLCKit)
mediaPlayer.stop() mediaPlayer.stop()
mediaPlayer.media = nil mediaPlayer.media = nil
#endif
} }
} }
#if canImport(MobileVLCKit)
extension VLCNativePlaybackBackend: VLCMediaPlayerDelegate { extension VLCNativePlaybackBackend: VLCMediaPlayerDelegate {
func mediaPlayerStateChanged(_ aNotification: Notification) { func mediaPlayerStateChanged(_ aNotification: Notification) {
switch mediaPlayer.state { switch mediaPlayer.state {
@ -56,3 +72,4 @@ extension VLCNativePlaybackBackend: VLCMediaPlayerDelegate {
} }
} }
} }
#endif

View file

@ -275,6 +275,33 @@ diff --git a/Podfile b/Podfile
<li>Consider adding a tiny XCTest target for classifier behavior once the project has a test bundle.</li> <li>Consider adding a tiny XCTest target for classifier behavior once the project has a test bundle.</li>
</ul> </ul>
</section> </section>
<section>
<h2>New Changes as of 2026-05-24 23:22 EDT</h2>
<p><strong>Summary of changes:</strong> Fixed the Swift build errors reported after the first handoff by converting the injected stream bridge into a raw multiline Swift string and guarding the MobileVLCKit import with <code>canImport(MobileVLCKit)</code>.</p>
<p><strong>Why this change was made:</strong> Swift was interpreting JavaScript regex backslashes as Swift string escapes, and the app could not compile from <code>Dreamio.xcodeproj</code> before CocoaPods had installed and linked <code>MobileVLCKit</code>. The fallback keeps the project buildable enough to show a native-player unavailable error until the workspace is set up with pods.</p>
<p><strong>Code diffs:</strong> Plain diff fallback is used for the same reason noted above: <code>@pierre/diffs</code> is present as a library but has no runnable CLI exposed in this repo.</p>
<pre class="diffs-fallback"><code>diff --git a/Dreamio/DreamioWebViewController.swift b/Dreamio/DreamioWebViewController.swift
- source: """
+ source: #"""
...
- """,
+ """#,
diff --git a/Dreamio/VLCNativePlaybackBackend.swift b/Dreamio/VLCNativePlaybackBackend.swift
+#if canImport(MobileVLCKit)
import MobileVLCKit
+#endif
...
+#if canImport(MobileVLCKit)
private let mediaPlayer = VLCMediaPlayer()
+#endif
...
+#else
+ onFailure?(NativePlaybackError.backendUnavailable)
+#endif</code></pre>
<p><strong>Related issues or PRs:</strong> Follow-up to Beads issue <code>dreamio-l68</code>.</p>
</section>
</main> </main>
</body> </body>
</html> </html>