# FoldReady — porting report: openfoodfacts-ios
**Dry run — review the patches, then re-run with `--apply`.**
## Migrate to UIScene lifecycle · REVIEW (check the diff)
- Added UIApplicationSceneManifest to Snapshots/Info.plist.
- UIScene lifecycle is REQUIRED from the iOS 27 SDK — apps without it fail to launch (TN3187).
- Set the real rootViewController in SceneDelegate (currently a placeholder).
```diff
--- a/Snapshots/Info.plist
+++ b/Snapshots/Info.plist
@@ -21,0 +21,17 @@
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+ UIWindowSceneSessionRoleApplication
+
+
+ UISceneConfigurationName
+ Default Configuration
+ UISceneDelegateClassName
+ $(PRODUCT_MODULE_NAME).SceneDelegate
+
+
+
+
--- a/SceneDelegate.swift
+++ b/SceneDelegate.swift
@@ -0,0 +1,18 @@
+import UIKit
+
+// Generated by FoldReady — migrate your AppDelegate's window setup here.
+// See Apple Technote TN3187 for the full UIScene migration.
+class SceneDelegate: UIResponder, UIWindowSceneDelegate {
+
+ var window: UIWindow?
+
+ func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
+ options connectionOptions: UIScene.ConnectionOptions) {
+ guard let windowScene = scene as? UIWindowScene else { return }
+ let window = UIWindow(windowScene: windowScene)
+ // TODO: set the app's real root view controller here (previously built in AppDelegate).
+ window.rootViewController = UIViewController()
+ window.makeKeyAndVisible()
+ self.window = window
+ }
+}
```
## Replace UIScreen.main.bounds · REVIEW (check the diff)
- Sources/AppDelegate.swift: 1 UIScreen.main.bounds read(s) remain — replace with the scene's effective geometry.
- Sources/Views/Products/Search/StateViews/EmptyView.swift: 1 UIScreen.main.bounds read(s) remain — replace with the scene's effective geometry.
- UIScreen.main is deprecated in iOS 27; reads must come from the window scene / effective geometry.
## Root NavigationStack → NavigationSplitView · REVIEW (check the diff)
- No root NavigationStack without an existing NavigationSplitView found.
## State preservation across fold transitions · MANUAL (suggested)
- Snapshots/SnapshotHelper.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Tests/Network/ProductServiceTests.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Tests/ViewControllers/Products/Detail/ProductDetailViewControllerTests.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Tests/ViewControllers/Products/Add/ProductAddViewControllerTests.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/PendingUploadItem.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/DataManager.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/PersistenceManager.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/Common/InfoRow.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/Transforms/TagTransform.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/PendingProductMergeProcessor.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Product.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Label.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/IngredientsAnalysis.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Vitamin.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Additive.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Nucleotide.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Allergen.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/OtherNutritionalSubstance.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Country.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Nutriment.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Category.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/API/Taxonomies/Mineral.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/Realm/RealmPendingUploadItem.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Models/Realm/RealmUserPreferences.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/ViewControllers/Products/Search/ScannerViewController.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/ViewControllers/Products/Detail/ProductDetailViewController.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/ViewControllers/Products/Add/ProductAddViewController.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Views/Products/Detail/Common/IngredientsAnalysisView.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Views/Products/Detail/Summary/IngredientsAnalysisTableViewCell.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Sources/Helpers/SharingManager.swift: add @SceneStorage for selection/scroll so the fold transition keeps user state.
- Pattern: @SceneStorage("selection") var selection: String? — survives the scene geometry change.
## De-hardcode fixed frames · MANUAL (suggested)
- No hardcoded frames detected.