diff --git a/dev/benchmarks/macrobenchmarks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/benchmarks/macrobenchmarks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/benchmarks/macrobenchmarks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/benchmarks/macrobenchmarks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/benchmarks/test_apps/stocks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/benchmarks/test_apps/stocks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/benchmarks/test_apps/stocks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/benchmarks/test_apps/stocks/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart b/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart index 4349a18f3b..12bd058820 100644 --- a/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart +++ b/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart @@ -12,7 +12,7 @@ import 'package:path/path.dart' as path; Future main() async { await task(() async { - section('Copy test Flutter App with WatchOS Companion'); + section('Copy app with watchOS companion and Swift Package'); String watchDeviceID; String phoneDeviceID; @@ -47,7 +47,7 @@ Future main() async { if (!appReleaseBuilt) { return TaskResult.failure( - 'Failed to build flutter iOS app with WatchOS companion in release mode.'); + 'Failed to build flutter iOS app with watchOS companion and Swift Package in release mode.'); } section('Create debug build'); @@ -69,7 +69,7 @@ Future main() async { if (!appDebugBuilt) { return TaskResult.failure( - 'Failed to build flutter iOS app with WatchOS companion in debug mode.'); + 'Failed to build flutter iOS app with watchOS companion and Swift Package in debug mode.'); } section('Create build for a simulator device'); @@ -183,7 +183,7 @@ Future main() async { if (!appSimulatorBuilt) { return TaskResult.failure( - 'Failed to build flutter iOS app with WatchOS companion in debug mode for simulated device.'); + 'Failed to build flutter iOS app with watchOS companion and Swift Package in debug mode for simulated device.'); } section('Run app on simulator device'); @@ -229,7 +229,7 @@ Future main() async { if (exitCode != 0) return TaskResult.failure( - 'Failed to start flutter iOS app with WatchOS companion on simulated device.'); + 'Failed to start flutter iOS app with watchOS companion and Swift Package on simulated device.'); return TaskResult.success(null); } catch (e) { diff --git a/dev/integration_tests/channels/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/channels/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/channels/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/channels/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/external_ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/external_ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/external_ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/external_ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/flavors/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/flavors/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/flavors/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/flavors/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.pbxproj index 26c9e79df5..c5525fd986 100644 --- a/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.pbxproj +++ b/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.pbxproj @@ -262,9 +262,14 @@ files = ( ); inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../Flutter/Flutter.framework", + "${BUILT_PRODUCTS_DIR}/device_info/device_info.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/flutter_driver_screenshot_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/flutter_gallery/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/flutter_gallery/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/flutter_gallery/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/flutter_gallery/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/ios_app_with_extensions/README.md b/dev/integration_tests/ios_app_with_extensions/README.md index b7eb35445e..7c45d782d2 100644 --- a/dev/integration_tests/ios_app_with_extensions/README.md +++ b/dev/integration_tests/ios_app_with_extensions/README.md @@ -3,3 +3,4 @@ Integration test to test building an iOS app with non-Flutter features: - watchOS app and extension +- Swift Package diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj index 2e18f9e802..ed4b7d1252 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -22,6 +22,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + F735C5C42485E50A002BE868 /* PlayingCard in Frameworks */ = {isa = PBXBuildFile; productRef = F735C5C32485E50A002BE868 /* PlayingCard */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -115,6 +116,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F735C5C42485E50A002BE868 /* PlayingCard in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -262,6 +264,9 @@ 49C15B68243E340F0025F804 /* PBXTargetDependency */, ); name = Runner; + packageProductDependencies = ( + F735C5C32485E50A002BE868 /* PlayingCard */, + ); productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; @@ -297,6 +302,9 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + F735C5C22485E50A002BE868 /* XCRemoteSwiftPackageReference "example-package-playingcard" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -907,6 +915,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + F735C5C22485E50A002BE868 /* XCRemoteSwiftPackageReference "example-package-playingcard" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/example-package-playingcard.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 3.0.5; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + F735C5C32485E50A002BE868 /* PlayingCard */ = { + isa = XCSwiftPackageProductDependency; + package = F735C5C22485E50A002BE868 /* XCRemoteSwiftPackageReference "example-package-playingcard" */; + productName = PlayingCard; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..b74fdf63a3 --- /dev/null +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "PlayingCard", + "repositoryURL": "https://github.com/apple/example-package-playingcard.git", + "state": { + "branch": null, + "revision": "39ddabb01e8102ab548a8c6bb3eb20b15f3b4fbc", + "version": "3.0.5" + } + } + ] + }, + "version": 1 +} diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..b74fdf63a3 --- /dev/null +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "PlayingCard", + "repositoryURL": "https://github.com/apple/example-package-playingcard.git", + "state": { + "branch": null, + "revision": "39ddabb01e8102ab548a8c6bb3eb20b15f3b4fbc", + "version": "3.0.5" + } + } + ] + }, + "version": 1 +} diff --git a/dev/integration_tests/ios_platform_view_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ios_platform_view_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/ios_platform_view_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/ios_platform_view_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/non_nullable/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/non_nullable/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/non_nullable/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/non_nullable/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/platform_interaction/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/platform_interaction/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/platform_interaction/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/platform_interaction/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/release_smoke_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/release_smoke_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/integration_tests/release_smoke_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/release_smoke_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/dev/integration_tests/ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 21a3cc14c7..919434a625 100644 --- a/dev/integration_tests/ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,9 +2,6 @@ - - + location = "self:"> diff --git a/dev/manual_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/manual_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/dev/manual_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/dev/manual_tests/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/examples/catalog/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/catalog/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 21a3cc14c7..919434a625 100644 --- a/examples/catalog/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/catalog/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,9 +2,6 @@ - - + location = "self:"> diff --git a/examples/flutter_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/flutter_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 21a3cc14c7..919434a625 100644 --- a/examples/flutter_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/flutter_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,9 +2,6 @@ - - + location = "self:"> diff --git a/examples/hello_world/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/hello_world/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/examples/hello_world/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/hello_world/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/examples/image_list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/image_list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/examples/image_list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/image_list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/examples/layers/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/layers/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/examples/layers/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/layers/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/examples/platform_channel/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/platform_channel/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/examples/platform_channel/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/platform_channel/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/examples/platform_channel_swift/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/platform_channel_swift/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/examples/platform_channel_swift/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/platform_channel_swift/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/examples/platform_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/platform_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/examples/platform_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/platform_view/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index f2f088d188..4d4a838c56 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -26,6 +26,7 @@ import '../reporting/reporting.dart'; import 'code_signing.dart'; import 'migrations/ios_migrator.dart'; import 'migrations/project_base_configuration_migration.dart'; +import 'migrations/project_build_location_migration.dart'; import 'migrations/remove_framework_link_and_embedding_migration.dart'; import 'migrations/xcode_build_system_migration.dart'; import 'xcodeproj.dart'; @@ -97,6 +98,7 @@ Future buildXcodeProject({ RemoveFrameworkLinkAndEmbeddingMigration(app.project, globals.logger, globals.xcode, globals.flutterUsage), XcodeBuildSystemMigration(app.project, globals.logger), ProjectBaseConfigurationMigration(app.project, globals.logger), + ProjectBuildLocationMigration(app.project, globals.logger), ]; final IOSMigration migration = IOSMigration(migrators); diff --git a/packages/flutter_tools/lib/src/ios/migrations/ios_migrator.dart b/packages/flutter_tools/lib/src/ios/migrations/ios_migrator.dart index 7965e6699c..e7d7cd7654 100644 --- a/packages/flutter_tools/lib/src/ios/migrations/ios_migrator.dart +++ b/packages/flutter_tools/lib/src/ios/migrations/ios_migrator.dart @@ -26,6 +26,13 @@ abstract class IOSMigrator { } @protected + String migrateFileContents(String fileContents) { + return fileContents; + } + + @protected + /// Calls [migrateLine] per line, then [migrateFileContents] + /// including the line migrations. void processFileLines(File file) { final List lines = file.readAsLinesSync(); @@ -51,9 +58,16 @@ abstract class IOSMigrator { newProjectContents.writeln(newProjectLine); } + final String projectContentsWithMigratedLines = newProjectContents.toString(); + final String projectContentsWithMigratedContents = migrateFileContents(projectContentsWithMigratedLines); + if (projectContentsWithMigratedLines != projectContentsWithMigratedContents) { + logger.printTrace('Migrating $basename contents'); + migrationRequired = true; + } + if (migrationRequired) { logger.printStatus('Upgrading $basename'); - file.writeAsStringSync(newProjectContents.toString()); + file.writeAsStringSync(projectContentsWithMigratedContents); } } } diff --git a/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart new file mode 100644 index 0000000000..effd0eb311 --- /dev/null +++ b/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart @@ -0,0 +1,49 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../../base/file_system.dart'; +import '../../base/logger.dart'; +import '../../project.dart'; +import 'ios_migrator.dart'; + +// Update the xcodeproj build location. Legacy build location does not work with Swift Packages. +class ProjectBuildLocationMigration extends IOSMigrator { + ProjectBuildLocationMigration( + IosProject project, + Logger logger, + ) : _xcodeProjectWorkspaceData = project.xcodeProjectWorkspaceData, + super(logger); + + final File _xcodeProjectWorkspaceData; + + @override + bool migrate() { + if (!_xcodeProjectWorkspaceData.existsSync()) { + logger.printTrace('Xcode project workspace data not found, skipping build location migration.'); + return true; + } + + processFileLines(_xcodeProjectWorkspaceData); + return true; + } + + @override + String migrateLine(String line) { + const String legacyBuildLocation = 'location = "group:Runner.xcodeproj"'; + const String defaultBuildLocation = 'location = "self:"'; + + return line.replaceAll(legacyBuildLocation, defaultBuildLocation); + } + + @override + String migrateFileContents(String fileContents) { + const String podLocation = ''' + + +'''; + + return fileContents.replaceAll(podLocation, ''); + } +} diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 722ea7b7dc..0b95dc40ee 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -398,6 +398,11 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { @override File get xcodeProjectInfoFile => xcodeProject.childFile('project.pbxproj'); + File get xcodeProjectWorkspaceData => + xcodeProject + .childDirectory('project.xcworkspace') + .childFile('contents.xcworkspacedata'); + @override Directory get xcodeWorkspace => hostAppRoot.childDirectory('$_hostAppProjectName.xcworkspace'); diff --git a/packages/flutter_tools/templates/app/ios.tmpl/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/flutter_tools/templates/app/ios.tmpl/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/packages/flutter_tools/templates/app/ios.tmpl/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/flutter_tools/templates/app/ios.tmpl/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.xcworkspace/contents.xcworkspacedata b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed..919434a625 100644 --- a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.xcworkspace/contents.xcworkspacedata +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart index 8fb672e10b..beea0a8b62 100644 --- a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart @@ -5,10 +5,9 @@ import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/platform.dart'; -import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/ios/migrations/ios_migrator.dart'; import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.dart'; +import 'package:flutter_tools/src/ios/migrations/project_build_location_migration.dart'; import 'package:flutter_tools/src/ios/migrations/remove_framework_link_and_embedding_migration.dart'; import 'package:flutter_tools/src/ios/migrations/xcode_build_system_migration.dart'; import 'package:flutter_tools/src/macos/xcode.dart'; @@ -49,15 +48,7 @@ void main () { memoryFileSystem = MemoryFileSystem(); mockXcode = MockXcode(); xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); - - testLogger = BufferLogger( - terminal: AnsiTerminal( - stdio: null, - platform: const LocalPlatform(), - ), - outputPreferences: OutputPreferences.test(), - ); - + testLogger = BufferLogger.test(); mockIosProject = MockIosProject(); when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile); }); @@ -268,15 +259,7 @@ keep this 2 setUp(() { memoryFileSystem = MemoryFileSystem(); xcodeWorkspaceSharedSettings = memoryFileSystem.file('WorkspaceSettings.xcsettings'); - - testLogger = BufferLogger( - terminal: AnsiTerminal( - stdio: null, - platform: const LocalPlatform(), - ), - outputPreferences: OutputPreferences.test(), - ); - + testLogger = BufferLogger.test(); mockIosProject = MockIosProject(); when(mockIosProject.xcodeWorkspaceSharedSettings).thenReturn(xcodeWorkspaceSharedSettings); }); @@ -339,6 +322,86 @@ keep this 2 }); }); + group('Xcode default build location', () { + MemoryFileSystem memoryFileSystem; + BufferLogger testLogger; + MockIosProject mockIosProject; + File xcodeProjectWorkspaceData; + + setUp(() { + memoryFileSystem = MemoryFileSystem(); + xcodeProjectWorkspaceData = memoryFileSystem.file('contents.xcworkspacedata'); + testLogger = BufferLogger.test(); + mockIosProject = MockIosProject(); + when(mockIosProject.xcodeProjectWorkspaceData).thenReturn(xcodeProjectWorkspaceData); + }); + + testWithoutContext('skipped if files are missing', () { + final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration( + mockIosProject, + testLogger, + ); + expect(iosProjectMigration.migrate(), isTrue); + expect(xcodeProjectWorkspaceData.existsSync(), isFalse); + + expect(testLogger.traceText, contains('Xcode project workspace data not found, skipping build location migration.')); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('skipped if nothing to upgrade', () { + const String contents = ''' + + + + + '''; + xcodeProjectWorkspaceData.writeAsStringSync(contents); + + final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration( + mockIosProject, + testLogger, + ); + expect(iosProjectMigration.migrate(), isTrue); + expect(xcodeProjectWorkspaceData.existsSync(), isTrue); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('Xcode project is migrated', () { + const String contents = ''' + + + + + + + +'''; + xcodeProjectWorkspaceData.writeAsStringSync(contents); + + final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration( + mockIosProject, + testLogger, + ); + expect(iosProjectMigration.migrate(), isTrue); + expect(xcodeProjectWorkspaceData.readAsStringSync(), ''' + + + + + + +'''); + expect(testLogger.statusText, contains('Upgrading contents.xcworkspacedata')); + }); + }); + group('remove Runner project base configuration', () { MemoryFileSystem memoryFileSystem; BufferLogger testLogger; @@ -348,15 +411,7 @@ keep this 2 setUp(() { memoryFileSystem = MemoryFileSystem(); xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); - - testLogger = BufferLogger( - terminal: AnsiTerminal( - stdio: null, - platform: const LocalPlatform(), - ), - outputPreferences: OutputPreferences.test(), - ); - + testLogger = BufferLogger.test(); mockIosProject = MockIosProject(); when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile); });