mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 06:00:33 +02:00
iPhone app: verified against a Frame from the Simulator
Adds debug-only test hooks (open on a tab, run page JS, leave the tunnel URL in Caches) used to drive the app in the Simulator, and records what was verified: all four tabs with live data, capture and 31 fps live video in WKWebView, upload, install jobs and the power password check through the app's tunnel. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fd3a25434d
commit
db75d1ca71
4 files changed
+36
-5
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
+18
-4
@@ -67,7 +67,21 @@ signing team in Xcode (Signing & Capabilities).
|
|||||||
|
|
||||||
## Verified
|
## Verified
|
||||||
|
|
||||||
In the iOS Simulator (iOS 26.5) and against a Frame (2026-09-27): the page and
|
<img src="img/iphone-tabs.jpg" alt="The four tabs in the iPhone app, connected to a Frame" width="900">
|
||||||
all its reads, headset capture, live video, and file upload through the
|
|
||||||
on-Frame server. Not yet exercised: pairing with the password, Android display
|
In the iOS Simulator (iOS 26.5) against a real Frame, 2026-09-27: the app connected
|
||||||
changes through podman, and power actions.
|
with its key, copied the bundle over SFTP, started the server on the Frame and
|
||||||
|
showed all four tabs with live data. In the app's web view, Capture returned a
|
||||||
|
headset still and Live played H.264 video at 31 fps (WebCodecs works in
|
||||||
|
WKWebView). Through the app's tunnel: status, games, Steam library, Android apps,
|
||||||
|
screenshots, a file upload (checked on the Frame), a background install job, and
|
||||||
|
the power password check (a wrong password is refused). The server on the Frame
|
||||||
|
exits within seconds of the app closing.
|
||||||
|
|
||||||
|
Not yet exercised: pairing with the password (only the add-the-key route),
|
||||||
|
Android display changes through podman (no Android app was running), a real
|
||||||
|
sleep/restart/shut down, and a physical iPhone.
|
||||||
|
|
||||||
|
Debug builds have Simulator test hooks (`FRAME_TEST_HOST`, `FRAME_TEST_PAGE`,
|
||||||
|
`FRAME_TEST_JS`, and the tunnel URL in the app's Caches folder); release builds
|
||||||
|
don't.
|
||||||
@@ -178,7 +178,16 @@ final class AppModel: ObservableObject {
|
|||||||
self.server = server
|
self.server = server
|
||||||
self.forwarder = f
|
self.forwarder = f
|
||||||
readySince = Date()
|
readySince = Date()
|
||||||
phase = .ready(URL(string: "http://127.0.0.1:\(f.localPort)/?key=\(key)")!)
|
var page = "http://127.0.0.1:\(f.localPort)/?key=\(key)"
|
||||||
|
#if DEBUG
|
||||||
|
// Test hooks for the Simulator: open on a given tab, and leave the URL where
|
||||||
|
// a test can drive the same tunnel (`simctl get_app_container … data`).
|
||||||
|
if let tab = ProcessInfo.processInfo.environment["FRAME_TEST_PAGE"] { page += "#\(tab)" }
|
||||||
|
if let dir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first {
|
||||||
|
try? page.write(to: dir.appendingPathComponent("frame-test-url.txt"), atomically: true, encoding: .utf8)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
phase = .ready(URL(string: page)!)
|
||||||
// Runs at once if it stopped in the moment since the check above.
|
// Runs at once if it stopped in the moment since the check above.
|
||||||
server.whenExited { [weak self] tail in
|
server.whenExited { [weak self] tail in
|
||||||
Task { @MainActor in self?.lost(mine, "Frame Control on the headset stopped. \(tail.suffix(200))") }
|
Task { @MainActor in self?.lost(mine, "Frame Control on the headset stopped. \(tail.suffix(200))") }
|
||||||
|
|||||||
@@ -144,6 +144,14 @@ struct WebShell: UIViewRepresentable {
|
|||||||
(root.presentedViewController ?? root).present(sheet, animated: true)
|
(root.presentedViewController ?? root).present(sheet, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
/// Simulator test hook: FRAME_TEST_JS runs in the page once it has loaded.
|
||||||
|
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
|
guard let js = ProcessInfo.processInfo.environment["FRAME_TEST_JS"] else { return }
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 4) { webView.evaluateJavaScript(js) }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// MARK: navigation: the app's page stays here; other sites open in Safari
|
// MARK: navigation: the app's page stays here; other sites open in Safari
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, decidePolicyFor action: WKNavigationAction,
|
func webView(_ webView: WKWebView, decidePolicyFor action: WKNavigationAction,
|
||||||
|
|||||||
Reference in new issue
Block a user