mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Build iOS apps using Swift Packages (#72761)
This commit is contained in:
parent
3082a2806e
commit
28db5a0fae
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -39,7 +39,7 @@ target 'watch Extension' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
pod 'EFQRCode/watchOS', '5.1.6'
|
||||
pod 'EFQRCode', '6.0'
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,9 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,9 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -26,6 +26,13 @@ abstract class ProjectMigrator {
|
||||
}
|
||||
|
||||
@protected
|
||||
String migrateFileContents(String fileContents) {
|
||||
return fileContents;
|
||||
}
|
||||
|
||||
@protected
|
||||
/// Calls [migrateLine] per line, then [migrateFileContents]
|
||||
/// including the line migrations.
|
||||
void processFileLines(File file) {
|
||||
final List<String> lines = file.readAsLinesSync();
|
||||
|
||||
@ -51,9 +58,16 @@ abstract class ProjectMigrator {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import '../reporting/reporting.dart';
|
||||
import 'code_signing.dart';
|
||||
import 'devices.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';
|
||||
@ -106,6 +107,7 @@ Future<XcodeBuildResult> 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 ProjectMigration migration = ProjectMigration(migrators);
|
||||
|
@ -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 '../../base/project_migrator.dart';
|
||||
import '../../project.dart';
|
||||
|
||||
// Update the xcodeproj build location. Legacy build location does not work with Swift Packages.
|
||||
class ProjectBuildLocationMigration extends ProjectMigrator {
|
||||
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 = '''
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
''';
|
||||
|
||||
return fileContents.replaceAll(podLocation, '');
|
||||
}
|
||||
}
|
@ -446,6 +446,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');
|
||||
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -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/base/project_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.test();
|
||||
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);
|
||||
});
|
||||
@ -267,15 +258,7 @@ keep this 2
|
||||
setUp(() {
|
||||
memoryFileSystem = MemoryFileSystem.test();
|
||||
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);
|
||||
});
|
||||
@ -338,6 +321,85 @@ 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 = '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>''';
|
||||
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 = '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
''';
|
||||
xcodeProjectWorkspaceData.writeAsStringSync(contents);
|
||||
|
||||
final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration(
|
||||
mockIosProject,
|
||||
testLogger,
|
||||
);
|
||||
expect(iosProjectMigration.migrate(), isTrue);
|
||||
expect(xcodeProjectWorkspaceData.readAsStringSync(), '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
''');
|
||||
expect(testLogger.statusText, contains('Upgrading contents.xcworkspacedata'));
|
||||
});
|
||||
});
|
||||
|
||||
group('remove Runner project base configuration', () {
|
||||
MemoryFileSystem memoryFileSystem;
|
||||
BufferLogger testLogger;
|
||||
@ -345,17 +407,9 @@ keep this 2
|
||||
File xcodeProjectInfoFile;
|
||||
|
||||
setUp(() {
|
||||
memoryFileSystem = MemoryFileSystem.test();
|
||||
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);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user