# 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.