Conversation
SUPPORTED_PLATFORMS gains xros/xrsimulator on both targets, with XROS_DEPLOYMENT_TARGET 26.0, TARGETED_DEVICE_FAMILY "2,7" and the visionOS spellings of UISupportsDocumentBrowser. Nothing in the layout is conditional: the scene is regular width, so the same three-pane NavigationSplitView fills the window, and both packages had already declared .visionOS(.v26). What the platform actually costs is the #ifs, in both directions. A guard written `#if os(iOS)` compiles clean on visionOS and simply stops applying, which had silently dropped the launch scene (DocumentGroupLaunchScene is unavailable on macOS only), the numeric keyboard and the 44pt touch targets; those are `#if !os(macOS)` now. And some API is genuinely gone: ToolbarSpacer, the Liquid Glass grouping separator, which is why the canvas toolbar becomes a CanvasToolbar: ToolbarContent — somewhere for the #if to live that isn't the call site. CI builds visionOS for exactly this reason; nothing else catches a guard that quietly does nothing. pointerHover() stays iOS-only, and says why. hoverEffect on a palette entry segfaults inside SwiftUI's own update of PaletteEntryButton.body before a window is ever shown, with .automatic as well as .highlight, so it is the modifier rather than the effect. Buttons get the system's hover treatment there anyway. Verified by opening a real document in the visionOS 27 simulator: palette, workspace, canvas, playback row and the document title all render as they do on iPadOS, and drag & drop and the four value-slot popovers behave. The app icon is the one thing still missing. visionOS wants a circular layered icon and Icon Composer only writes squares (plus watchOS circles), so AppIcon.icon produces nothing for it and the system placeholder is what shows on the Home View. #11
`ideal` carries more weight than it looks. macOS and iPadOS 26 both let the split view's divider be dragged, so there it is only where the column opens; visionOS has no draggable divider, so there it is the width, permanently, and the detail column absorbs every extra point the window has. Measured on a 1280pt visionOS window: 360 for the workspace against ~690 for the canvas, which is 270 past the canvas's own ideal. At 360 a nested Japanese program wraps, and not only where the design had accepted it. 「くりかえす 10 かい」 broke か/い at the *top* level, no nesting involved, and 「はこにかける」 split in the middle three levels down. 440 fits every row of that program on one line at three levels — each level of nesting costs 18pt — and still leaves the canvas ~600pt. max goes to 560 because ideal == max would leave the two platforms that can drag able to drag only narrower. Checked against the same three-deep document on visionOS 27 and on a 1280×800 Mac window. Judge any change to it on a nested *Japanese* program: English fits where 「はこにかける」 does not, and the top-level wrap is invisible in a flat one. #11
Icon Composer writes squares (plus watchOS circles) and nothing else, so AppIcon.icon left visionOS with the system placeholder. The circular layered icon comes from a second source instead: an AppIcon.solidimagestack of three .solidimagestacklayers — Front, Middle, Back at 1024×1024 on the vision idiom — carrying the same artwork as the Icon Composer icon, so the tortoise reads the same in the Home View as it does in the Dock and on a Home Screen. Both are named AppIcon and neither shadows the other: ASSETCATALOG_COMPILER_APPICON_NAME is one value for every platform and actool routes by idiom. Verified in the built products, not in Xcode — the visionOS Assets.car holds a SolidImageStack and no IconImageStack, the iOS one the reverse, and the Mac still ships AppIcon.icns. Checked on the visionOS 27 Home View too, which is the only place the layers and the circular mask are actually applied. #11
visionOS で iPad アプリ相当を動かす #11
Two are `#if os(visionOS)`, so iPadOS and macOS keep the arrangements #23, #31 and #41 settled. The third — the code pane — was wrong everywhere and merely unreadable there. **A way back to the browser.** iPadOS puts a chevron beside the document title and macOS has File ▸ Open with a window per document. visionOS has neither: its window carries the drawing it was opened with, nothing offers another, and the only route to a second one was closing the window and launching the app again. A folder button in the sidebar's bar calls `dismiss`, which is what a DocumentGroup document closes itself with. Where that `dismiss` is read from decides whether it does anything. Read inside the toolbar item's own view — the obvious place, since that is where the button is — it resolves against the toolbar's context and the button is inert: it highlights on press and nothing happens. It has to come from the environment of the *content* the toolbar is attached to, hence a ViewModifier rather than a view inside the `toolbar` block. Nothing warns you: the code compiles and the button draws. **The name stays in one place.** The document's name reaches the pane late — opening from the browser leaves it blank for a moment and then fills in — and a second, self-drawn label from `\.documentConfiguration`'s fileURL fixes that, being right from the first frame. It was built, looked at, and taken back out: on a window this wide, the sidebar's title and a canvas-pane copy read as one name printed twice rather than as a title and a reminder. The sidebar's is the one that can rename, so it is the one that stays. **The code pane is paper now.** It sat on `.background.secondary`, a *semantic* surface: near-white or near-black on iPad and Mac, but light translucent glass on visionOS. The syntax colors then had nowhere to stand — system `.purple` and `.blue` are tuned for an opaque backdrop, and `.plain` was `Color.primary`, which is *white* there, so the plain text and the ground behind it were both light. It is white and opaque now, the same in both appearances, rounded the same 8 as the canvas: the two swap places inside one ZStack, so the toggle should change the content and nothing else. The token colors are fixed values measured against white — 8.6:1, 8.4:1, 5.1:1 and 16.9:1 — for the reason the block fills are fixed (#41). Two traps came with that. The copy button had to move outside the paper: on it, it needed the ink as a tint to be legible, and on visionOS the tint went to the button's *capsule* rather than its label, leaving a black lozenge with invisible text. And a program narrower than the pane sat in the middle of it, which white made obvious — in a scroll view that scrolls both ways the content is offered no width to fill, so the `.leading` frame does nothing and `defaultScrollAnchor(.topLeading)` is what places it. #11
Running on real hardware stopped with "TortoiseBlocksThumbnail has entitlements that require signing with a development certificate". The extension's Debug identity was a bare `CODE_SIGN_IDENTITY = "-"` with an `[sdk=iphoneos*]` exception naming a real certificate. That reads correctly right up until a platform arrives the exception does not name: a visionOS device build fell into the ad-hoc default, and both targets are sandboxed, so ad-hoc is never enough on a device. Simulators hid it, because they ad-hoc sign whatever they are handed — every build this repository makes on CI is a simulator or a Mac. Scoped to `[sdk=macosx*]` instead, which is what the app target already does and what the everyday Mac loop actually needs. The iphoneos exception goes with it: with ad-hoc named for the one platform that wants it, automatic signing resolves the rest. Verified with -showBuildSettings that both targets now read identically — macosx "-", iphoneos and xros "Apple Development" — and that a Mac Debug build still comes out `Signature=adhoc`, `TeamIdentifier=not set`. Name the platform that wants the exception, never the ones that don't. It is the rule `#if !os(macOS)` follows in PlatformModifiers, and it fails the same silent way when inverted. #11
A palette block was the one thing on screen that never lit up when looked at. visionOS does not give a button with a custom ButtonStyle the system hover treatment, and `pointerHover()` had been left iOS-only because it crashed there — so on the platform where gaze *is* the targeting affordance, the palette had none. The effect was never the problem. `hoverEffect` and `draggable` on the **same view** segfault: a swift_release inside SwiftUI's own update of that view's body, before a window is ever shown. It reads as "hoverEffect crashes on visionOS" because the crash blames the body, and because both `.highlight` and `.automatic` do it — but move the same `.highlight` one level down, onto the shaped body `PaletteBlockButtonStyle` draws, and it is fine. So `pointerHover()` is `#if !os(macOS)` again, the palette entry applies it inside its style rather than on the Button that carries `draggable`, and every other call site is unchanged. Checked on the visionOS 27 simulator that the palette, the block rows and the value chips all render with no crash — the chips sit inside draggable rows, which is a different view and therefore fine. It also frames better this way: the highlight follows the shape the style draws instead of the label's own bounds. #11
Everything the public sees is ready for the release that carries visionOS, and the pipeline can push a third listing. It is *not* 1.1.0 any more — this rode that version until visionOS was held back, and the text here must not go up until the platform actually ships, or the iOS and macOS listings will claim a Vision Pro app nobody can download. visionOS is a native app on the xrOS SDK, not "Designed for iPad", so App Store Connect gives it a platform version of its own — and the vocabulary for that platform is spelled three different ways across one pipeline, all three required. `visionos` names the screenshots directory, `xros` goes to deliver, `VISION_OS` goes to spaceship. The first is the one that is not a style choice: a Vision Pro capture is 3840×2160, the same size as an Apple TV one, so deliver cannot resolve the display type from the size and breaks the tie on whether the path contains "vision" — naming the directory after deliver's own platform value would file every screenshot as APP_APPLE_TV, on an app with no tvOS listing at all. So: a visionos platform block with the same two lanes, VISION_OS in CONNECT_PLATFORM, 3840×2160 in metadata_check (a platform missing from that table is not checked at all, so the size gate follows the directory), and visionos in the App Store Metadata workflow's choices, where "both" becomes "all". `SupportedPlatforms.extra` declares the namespace, which is the sanctioned way to stop fastlane warning about it on every run. The store text gains Apple Vision Pro where it listed iPad and Mac, and a What's New section for the platform; the landing page gains it in both languages, in the meta description, the two heroes, the two requirement lines and the "one app" showcase. No screenshots yet — 3840×2160, alpha off, into appstore/screenshots/visionos/<locale>/. #11
13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
visionOS 対応の退避ブランチです。v1.1.0 に間に合わないので、main を
v1.1.0タグまで戻し、visionOS 関連はすべてここに集めます。まだマージしないでください。main は
v1.1.0(0a30773) まで巻き戻し済みで、visionOS 関連はすべてこのブランチに集約してあります(#51 でマージ済みだった分も含む)。入っているもの
動く(#51 でマージ済みの分)
1459028SUPPORTED_PLATFORMSに xros/xrsimulator、XROS_DEPLOYMENT_TARGET 26.0、TARGETED_DEVICE_FAMILY "2,7"。ToolbarSpacerが unavailable なのでCanvasToolbarを分離。#if os(iOS)が visionOS で静かに無効化される問題(起動画面・数字キーボード・44ptタップ領域が丸ごと落ちていた)を#if !os(macOS)に修正。CI に visionOS ビルド追加9f49526idealを 360→440(max440→560)。visionOS はディバイダをドラッグできないので ideal がそのまま列幅になり、1280pt ウィンドウで 360 対 690 という配分だった。3段ネストの日本語プログラムで最上段の「くりかえす 10 かい」まで折り返していた670be04AppIcon.solidimagestack)。Icon Composer は squares と watchOS circles しか書き出せないため別ソース。.iconと同名で共存することをビルド生成物で確認済み退避後に足した分
60a78c7.background.secondaryは visionOS では部屋が透ける明るいガラスで、システム色もColor.primary=白も沈んでいた)。ついでにコードの中央寄りをdefaultScrollAnchor(.topLeading)で左上へ2e99c9e[sdk=macosx*]に限定e000deeButtonStyleのボタンに自動ホバーを付けないので、パレットだけ視線で光らなかったcdbe446release/visionos-1.1.0。1.1.0 から降ろしたのでこちらへ移動)判明した visionOS の癖(すべて実測)
#if os(iOS)は visionOS で黙って効かなくなる。 コンパイルは通るので気付けない。CI に visionOS ビルドを足した本当の理由hoverEffect+draggableを同じビューに置くと segfault する。 効果の種類は無関係(.highlightも.automaticも落ちる)。1段下(ButtonStyleが描くボディ)に移すと問題なし。クラッシュがボディを指すので「hoverEffect が壊れている」と誤読しやすいdismissはツールバー項目の中から読むと何もしない。 ツールバーを付けているコンテンツ側の環境から取る必要がある。押しても無反応で、コンパイルも描画も通る残課題
1. 書類の再選択が2タップ
📁 を押すとシステムの「書類」ボタンが現れ、それを押すと戻れます。1タップにする手が公開 API に見当たりません:
dismiss()の唯一の効果が「書類」を出すこと。書類ビュー自体は生きたまま残る(タイマーが回り続けることで確認)dismissWindow()は無反応window.rootViewController?.dismiss()(フォーラムの定番の回避策)も visionOS 26 では完全に無反応\.openDocument/\.newDocumentは@available(visionOS, unavailable)dismiss()が DocumentGroup の書類を閉じないのは 2020年からの既知の制約。2. 表示の切り替えで前のビューが残る(実機のみ)
条件分岐で消えるはずのビューが画面に残る。ワークスペースの
ContentUnavailableViewがブロックの背後に残るのが分かりやすい例ですが、押したボタンとは無関係に、切り替えが起きる箇所全般で発生。シミュレータでは再現しません(プログラムからの切り替えは正常)。上の「書類ビューが生きたまま残る」と同じ穴の可能性が高い。Feedback Assistant 行きだと思います。visionOS 1.x の DocumentGroup バグが 2.0 で修正された前例あり。
3. ストア/LP の文言は「出したら名乗ってしまう」
cdbe446の中身(description・release_notes・site/index.html)は visionOS が実際に出荷される版まで公開してはいけません。文言は3プラットフォーム共有なので、上げると iOS と macOS のリスティングまで Vision Pro 対応を名乗ります。site も main にマージした時点で公開されます(pages.ymlの paths にsite/**)。罠が1つ埋めてあります: Vision Pro のスクショは 3840×2160 で Apple TV と同じサイズ。deliver はサイズで display type を決められず、パスに
visionが含まれるかで判定するので、ディレクトリをxrosにすると全カットがAPP_APPLE_TVとして登録されます。4. 出荷側の未着手分
appstore/screenshots/visionos/{en-US,ja}/、3840×2160、アルファ off(xcrun simctl io <device> screenshotがそのサイズで書き出すが、アルファが付くので-alpha offが必須)buildDistributionAudienceはAPP_STORE_ELIGIBLE検証状況
3プラットフォームのビルド・Kit テスト119件・
swift format lint --strictすべて green。実機(Apple Vision Pro)で 📁 の2タップ動作とアイコン表示を確認済み。