Support for flutter run/build module on iOS (#21216)
diff --git a/packages/flutter_tools/lib/src/android/apk.dart b/packages/flutter_tools/lib/src/android/apk.dart index 57e7f29..43b73c1 100644 --- a/packages/flutter_tools/lib/src/android/apk.dart +++ b/packages/flutter_tools/lib/src/android/apk.dart
@@ -19,7 +19,7 @@ @required String target, BuildInfo buildInfo = BuildInfo.debug }) async { - if (!project.android.isUsingGradle()) { + if (!project.android.isUsingGradle) { throwToolExit( 'The build process for Android has changed, and the current project configuration\n' 'is no longer valid. Please consult\n\n'
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart index cbe569b..58829a2 100644 --- a/packages/flutter_tools/lib/src/application_package.dart +++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -17,7 +17,6 @@ import 'globals.dart'; import 'ios/ios_workflow.dart'; import 'ios/plist_utils.dart' as plist; -import 'ios/xcodeproj.dart'; import 'project.dart'; import 'tester/flutter_tester.dart'; @@ -93,7 +92,7 @@ static Future<AndroidApk> fromAndroidProject(AndroidProject androidProject) async { File apkFile; - if (androidProject.isUsingGradle()) { + if (androidProject.isUsingGradle) { apkFile = await getGradleAppOut(androidProject); if (apkFile.existsSync()) { // Grab information from the .apk. The gradle build script might alter @@ -217,26 +216,10 @@ ); } - factory IOSApp.fromCurrentDirectory() { + factory IOSApp.fromIosProject(IosProject project) { if (getCurrentHostPlatform() != HostPlatform.darwin_x64) return null; - - final String plistPath = fs.path.join('ios', 'Runner', 'Info.plist'); - String id = iosWorkflow.getPlistValueFromFile( - plistPath, - plist.kCFBundleIdentifierKey, - ); - if (id == null || !xcodeProjectInterpreter.isInstalled) - return null; - final String projectPath = fs.path.join('ios', 'Runner.xcodeproj'); - final Map<String, String> buildSettings = xcodeProjectInterpreter.getBuildSettings(projectPath, 'Runner'); - id = substituteXcodeVariables(id, buildSettings); - - return new BuildableIOSApp( - appDirectory: 'ios', - projectBundleId: id, - buildSettings: buildSettings, - ); + return new BuildableIOSApp(project); } @override @@ -248,25 +231,12 @@ } class BuildableIOSApp extends IOSApp { - static const String kBundleName = 'Runner.app'; + BuildableIOSApp(this.project) : super(projectBundleId: project.productBundleIdentifier); - BuildableIOSApp({ - this.appDirectory, - String projectBundleId, - this.buildSettings, - }) : super(projectBundleId: projectBundleId); - - final String appDirectory; - - /// Build settings of the app's Xcode project. - /// - /// These are the build settings as specified in the Xcode project files. - /// - /// Build settings may change depending on the parameters passed while building. - final Map<String, String> buildSettings; + final IosProject project; @override - String get name => kBundleName; + String get name => project.hostAppBundleName; @override String get simulatorBundlePath => _buildAppPath('iphonesimulator'); @@ -274,11 +244,8 @@ @override String get deviceBundlePath => _buildAppPath('iphoneos'); - /// True if the app is built from a Swift project. Null if unknown. - bool get isSwift => buildSettings?.containsKey('SWIFT_VERSION'); - String _buildAppPath(String type) { - return fs.path.join(getIosBuildDirectory(), type, kBundleName); + return fs.path.join(getIosBuildDirectory(), type, name); } } @@ -317,7 +284,7 @@ : new AndroidApk.fromApk(applicationBinary); case TargetPlatform.ios: return applicationBinary == null - ? new IOSApp.fromCurrentDirectory() + ? new IOSApp.fromIosProject((await FlutterProject.current()).ios) : new IOSApp.fromPrebuiltApp(applicationBinary); case TargetPlatform.tester: return new FlutterTesterApp.fromCurrentDirectory(); @@ -346,7 +313,7 @@ android ??= await AndroidApk.fromAndroidProject((await FlutterProject.current()).android); return android; case TargetPlatform.ios: - iOS ??= new IOSApp.fromCurrentDirectory(); + iOS ??= IOSApp.fromIosProject((await FlutterProject.current()).ios); return iOS; case TargetPlatform.darwin_x64: case TargetPlatform.linux_x64:
diff --git a/packages/flutter_tools/lib/src/base/file_system.dart b/packages/flutter_tools/lib/src/base/file_system.dart index 225dcb6..b15e041 100644 --- a/packages/flutter_tools/lib/src/base/file_system.dart +++ b/packages/flutter_tools/lib/src/base/file_system.dart
@@ -6,6 +6,7 @@ import 'package:file/local.dart'; import 'package:file/memory.dart'; import 'package:file/record_replay.dart'; +import 'package:meta/meta.dart'; import 'common.dart' show throwToolExit; import 'context.dart'; @@ -145,3 +146,16 @@ /// On Windows it replaces all '\' with '\\'. On other platforms, it returns the /// path unchanged. String escapePath(String path) => platform.isWindows ? path.replaceAll('\\', '\\\\') : path; + +/// Returns true if the file system [entity] has not been modified since the +/// latest modification to [referenceFile]. +/// +/// Returns true, if [entity] does not exist. +/// +/// Returns false, if [entity] exists, but [referenceFile] does not. +bool isOlderThanReference({@required FileSystemEntity entity, @required File referenceFile}) { + if (!entity.existsSync()) + return true; + return referenceFile.existsSync() + && referenceFile.lastModifiedSync().isAfter(entity.statSync().modified); +}
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart index 5b2ddbb..ffc4af5 100644 --- a/packages/flutter_tools/lib/src/cache.dart +++ b/packages/flutter_tools/lib/src/cache.dart
@@ -169,17 +169,11 @@ return fs.file(fs.path.join(getRoot().path, '$artifactName.stamp')); } - /// Returns `true` if either [file] is older than the tools stamp or if - /// [file] doesn't exist. - bool fileOlderThanToolsStamp(File file) { - if (!file.existsSync()) { - return true; - } + /// Returns `true` if either [entity] is older than the tools stamp or if + /// [entity] doesn't exist. + bool isOlderThanToolsStamp(FileSystemEntity entity) { final File flutterToolsStamp = getStampFileFor('flutter_tools'); - return flutterToolsStamp.existsSync() && - flutterToolsStamp - .lastModifiedSync() - .isAfter(file.lastModifiedSync()); + return isOlderThanReference(entity: entity, referenceFile: flutterToolsStamp); } bool isUpToDate() => _artifacts.every((CachedArtifact artifact) => artifact.isUpToDate());
diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index 8c25be6..4f9f440 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -133,7 +133,7 @@ String organization = argResults['org']; if (!argResults.wasParsed('org')) { final FlutterProject project = await FlutterProject.fromDirectory(projectDir); - final Set<String> existingOrganizations = await project.organizationNames(); + final Set<String> existingOrganizations = project.organizationNames; if (existingOrganizations.length == 1) { organization = existingOrganizations.first; } else if (1 < existingOrganizations.length) {
diff --git a/packages/flutter_tools/lib/src/commands/inject_plugins.dart b/packages/flutter_tools/lib/src/commands/inject_plugins.dart index 21aa60a..8c2ba4d 100644 --- a/packages/flutter_tools/lib/src/commands/inject_plugins.dart +++ b/packages/flutter_tools/lib/src/commands/inject_plugins.dart
@@ -26,6 +26,7 @@ @override Future<Null> runCommand() async { final FlutterProject project = await FlutterProject.current(); + refreshPluginsList(project); await injectPlugins(project); final bool result = hasPlugins(project); if (result) {
diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart index 81a1e64..60b3fb3 100644 --- a/packages/flutter_tools/lib/src/flutter_manifest.dart +++ b/packages/flutter_tools/lib/src/flutter_manifest.dart
@@ -140,6 +140,14 @@ return null; } + /// Returns the iOS bundle identifier declared by this manifest in its + /// module descriptor. Returns null, if there is no such declaration. + String get iosBundleIdentifier { + if (isModule) + return _flutterDescriptor['module']['iosBundleIdentifier']; + return null; + } + List<Map<String, dynamic>> get fontsDescriptor { final List<dynamic> fontList = _flutterDescriptor['fonts']; return fontList == null
diff --git a/packages/flutter_tools/lib/src/ios/code_signing.dart b/packages/flutter_tools/lib/src/ios/code_signing.dart index 6797a6e..a337a75 100644 --- a/packages/flutter_tools/lib/src/ios/code_signing.dart +++ b/packages/flutter_tools/lib/src/ios/code_signing.dart
@@ -96,20 +96,21 @@ BuildableIOSApp iosApp, bool usesTerminalUi = true }) async{ - if (iosApp.buildSettings == null) + final Map<String, String> buildSettings = iosApp.project.buildSettings; + if (buildSettings == null) return null; // If the user already has it set in the project build settings itself, // continue with that. - if (isNotEmpty(iosApp.buildSettings['DEVELOPMENT_TEAM'])) { + if (isNotEmpty(buildSettings['DEVELOPMENT_TEAM'])) { printStatus( 'Automatically signing iOS for device deployment using specified development ' - 'team in Xcode project: ${iosApp.buildSettings['DEVELOPMENT_TEAM']}' + 'team in Xcode project: ${buildSettings['DEVELOPMENT_TEAM']}' ); return null; } - if (isNotEmpty(iosApp.buildSettings['PROVISIONING_PROFILE'])) + if (isNotEmpty(buildSettings['PROVISIONING_PROFILE'])) return null; // If the user's environment is missing the tools needed to find and read
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index f9a1e7a..0454949 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -189,13 +189,13 @@ bool codesign = true, bool usesTerminalUi = true, }) async { - if (!await upgradePbxProjWithFlutterAssets(app.name, app.appDirectory)) + if (!await upgradePbxProjWithFlutterAssets(app.project)) return new XcodeBuildResult(success: false); if (!_checkXcodeVersion()) return new XcodeBuildResult(success: false); - final XcodeProjectInfo projectInfo = xcodeProjectInterpreter.getInfo(app.appDirectory); + final XcodeProjectInfo projectInfo = xcodeProjectInterpreter.getInfo(app.project.directory.path); if (!projectInfo.targets.contains('Runner')) { printError('The Xcode project does not define target "Runner" which is needed by Flutter tooling.'); printError('Open Xcode to fix the problem:'); @@ -230,8 +230,7 @@ // Before the build, all service definitions must be updated and the dylibs // copied over to a location that is suitable for Xcodebuild to find them. - final Directory appDirectory = fs.directory(app.appDirectory); - await _addServicesToBundle(appDirectory); + await _addServicesToBundle(app.project.directory); final FlutterProject project = await FlutterProject.current(); await updateGeneratedXcodeProperties( @@ -242,22 +241,21 @@ ); if (hasPlugins(project)) { - final String iosPath = fs.path.join(fs.currentDirectory.path, app.appDirectory); // If the Xcode project, Podfile, or Generated.xcconfig have changed since // last run, pods should be updated. final Fingerprinter fingerprinter = new Fingerprinter( fingerprintPath: fs.path.join(getIosBuildDirectory(), 'pod_inputs.fingerprint'), paths: <String>[ - _getPbxProjPath(app.appDirectory), - fs.path.join(iosPath, 'Podfile'), - fs.path.join(iosPath, 'Flutter', 'Generated.xcconfig'), + app.project.xcodeProjectInfoFile.path, + app.project.podfile.path, + app.project.generatedXcodePropertiesFile.path, ], properties: <String, String>{}, ); final bool didPodInstall = await cocoaPods.processPods( iosProject: project.ios, iosEngineDir: flutterFrameworkDir(buildInfo.mode), - isSwift: app.isSwift, + isSwift: project.ios.isSwift, dependenciesChanged: !await fingerprinter.doesFingerprintMatch() ); if (didPodInstall) @@ -288,7 +286,7 @@ buildCommands.add('-allowProvisioningDeviceRegistration'); } - final List<FileSystemEntity> contents = fs.directory(app.appDirectory).listSync(); + final List<FileSystemEntity> contents = app.project.directory.listSync(); for (FileSystemEntity entity in contents) { if (fs.path.extension(entity.path) == '.xcworkspace') { buildCommands.addAll(<String>[ @@ -353,7 +351,7 @@ initialBuildStatus = logger.startProgress('Starting Xcode build...'); final RunResult buildResult = await runAsync( buildCommands, - workingDirectory: app.appDirectory, + workingDirectory: app.project.directory.path, allowReentrantFlutter: true ); buildSubStatus?.stop(); @@ -381,7 +379,7 @@ '-allowProvisioningDeviceRegistration', ].contains(buildCommand); }).toList(), - workingDirectory: app.appDirectory, + workingDirectory: app.project.directory.path, )); if (buildResult.exitCode != 0) { @@ -400,7 +398,7 @@ stderr: buildResult.stderr, xcodeBuildExecution: new XcodeBuildExecution( buildCommands: buildCommands, - appDirectory: app.appDirectory, + appDirectory: app.project.directory.path, buildForPhysicalDevice: buildForDevice, buildSettings: buildSettings, ), @@ -568,9 +566,6 @@ } } -/// The path of the Xcode project file. -String _getPbxProjPath(String appPath) => fs.path.join(fs.currentDirectory.path, appPath, 'Runner.xcodeproj', 'project.pbxproj'); - void _copyServiceDefinitionsManifest(List<Map<String, String>> services, File manifest) { printTrace("Creating service definitions manifest at '${manifest.path}'"); final List<Map<String, String>> jsonServices = services.map((Map<String, String> service) => <String, String>{ @@ -583,8 +578,8 @@ manifest.writeAsStringSync(json.encode(jsonObject), mode: FileMode.write, flush: true); } -Future<bool> upgradePbxProjWithFlutterAssets(String app, String appPath) async { - final File xcodeProjectFile = fs.file(_getPbxProjPath(appPath)); +Future<bool> upgradePbxProjWithFlutterAssets(IosProject project) async { + final File xcodeProjectFile = project.xcodeProjectInfoFile; assert(await xcodeProjectFile.exists()); final List<String> lines = await xcodeProjectFile.readAsLines(); @@ -601,7 +596,7 @@ const String l8 = ' 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,'; - printStatus("Upgrading project.pbxproj of $app' to include the " + printStatus("Upgrading project.pbxproj of ${project.hostAppBundleName}' to include the " "'flutter_assets' directory"); if (!lines.contains(l1) || !lines.contains(l3) ||
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart index 9a6afe8..288d87a 100644 --- a/packages/flutter_tools/lib/src/plugins.dart +++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -241,8 +241,7 @@ 'name': p.name, 'prefix': p.iosPrefix, 'class': p.pluginClass, - }). - toList(); + }).toList(); final Map<String, dynamic> context = <String, dynamic>{ 'plugins': iosPlugins, }; @@ -279,23 +278,34 @@ } } -/// Injects plugins found in `pubspec.yaml` into the platform-specific projects. -Future<void> injectPlugins(FlutterProject project) async { +/// Rewrites the `.flutter-plugins` file of [project] based on the plugin +/// dependencies declared in `pubspec.yaml`. +/// +/// Assumes `pub get` has been executed since last change to `pubspec.yaml`. +void refreshPluginsList(FlutterProject project) { final List<Plugin> plugins = findPlugins(project); final bool changed = _writeFlutterPluginsList(project, plugins); + if (changed) + cocoaPods.invalidatePodInstallOutput(project.ios); +} + +/// Injects plugins found in `pubspec.yaml` into the platform-specific projects. +/// +/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`. +Future<void> injectPlugins(FlutterProject project) async { + final List<Plugin> plugins = findPlugins(project); await _writeAndroidPluginRegistrant(project, plugins); await _writeIOSPluginRegistrant(project, plugins); - - if (project.ios.directory.existsSync()) { + if (!project.isModule && project.ios.directory.existsSync()) { final CocoaPods cocoaPods = new CocoaPods(); if (plugins.isNotEmpty) cocoaPods.setupPodfile(project.ios); - if (changed) - cocoaPods.invalidatePodInstallOutput(project.ios); } } /// Returns whether the specified Flutter [project] has any plugin dependencies. +/// +/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`. bool hasPlugins(FlutterProject project) { return _readFlutterPluginsList(project) != null; }
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index d54d8e9..b1fc04d 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart
@@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; import 'package:meta/meta.dart'; @@ -64,17 +63,17 @@ /// The manifest of the example sub-project of this project. final FlutterManifest _exampleManifest; - /// Asynchronously returns the organization names found in this project as + /// The set of organization names found in this project as /// part of iOS product bundle identifier, Android application ID, or /// Gradle group ID. - Future<Set<String>> organizationNames() async { - final List<String> candidates = await Future.wait(<Future<String>>[ - ios.productBundleIdentifier(), - android.applicationId(), - android.group(), - example.android.applicationId(), - example.ios.productBundleIdentifier(), - ]); + Set<String> get organizationNames { + final List<String> candidates = <String>[ + ios.productBundleIdentifier, + android.applicationId, + android.group, + example.android.applicationId, + example.ios.productBundleIdentifier, + ]; return new Set<String>.from(candidates .map(_organizationNameFromPackageName) .where((String name) => name != null)); @@ -93,6 +92,13 @@ /// The Android sub project of this project. AndroidProject get android => new AndroidProject._(this); + /// The `pubspec.yaml` file of this project. + File get pubspecFile => directory.childFile('pubspec.yaml'); + + /// The `.packages` file of this project. + File get packagesFile => directory.childFile('.packages'); + + /// The `.flutter-plugins` file of this project. File get flutterPluginsFile => directory.childFile('.flutter-plugins'); /// The example sub-project of this project. @@ -128,6 +134,7 @@ Future<void> ensureReadyForPlatformSpecificTooling() async { if (!directory.existsSync() || hasExampleApp) return; + refreshPluginsList(this); await android.ensureReadyForPlatformSpecificTooling(); await ios.ensureReadyForPlatformSpecificTooling(); await injectPlugins(this); @@ -140,6 +147,7 @@ /// Flutter applications and the `.ios/` sub-folder of Flutter modules. class IosProject { static final RegExp _productBundleIdPattern = new RegExp(r'^\s*PRODUCT_BUNDLE_IDENTIFIER\s*=\s*(.*);\s*$'); + static const String _hostAppBundleName = 'Runner'; IosProject._(this.parent); @@ -149,6 +157,8 @@ /// The directory of this project. Directory get directory => parent.directory.childDirectory(isModule ? '.ios' : 'ios'); + String get hostAppBundleName => '$_hostAppBundleName.app'; + /// True, if the parent Flutter project is a module. bool get isModule => parent.isModule; @@ -164,19 +174,30 @@ /// The 'Manifest.lock'. File get podManifestLock => directory.childDirectory('Pods').childFile('Manifest.lock'); - Future<String> productBundleIdentifier() { - final File projectFile = directory.childDirectory('Runner.xcodeproj').childFile('project.pbxproj'); - return _firstMatchInFile(projectFile, _productBundleIdPattern).then((Match match) => match?.group(1)); + /// '.xcodeproj' folder of the host app. + Directory get xcodeProject => directory.childDirectory('$_hostAppBundleName.xcodeproj'); + + /// The '.pbxproj' file of the host app. + File get xcodeProjectInfoFile => xcodeProject.childFile('project.pbxproj'); + + /// The product bundle identifier of the host app. + String get productBundleIdentifier { + return _firstMatchInFile(xcodeProjectInfoFile, _productBundleIdPattern)?.group(1); + } + + /// True, if the host app project is using Swift. + bool get isSwift => buildSettings?.containsKey('SWIFT_VERSION'); + + /// The build settings for the host app of this project, as a detached map. + Map<String, String> get buildSettings { + return xcode.xcodeProjectInterpreter.getBuildSettings(xcodeProject.path, _hostAppBundleName); } Future<void> ensureReadyForPlatformSpecificTooling() async { - if (isModule && _shouldRegenerateFromTemplate()) { - final Template template = new Template.fromName(fs.path.join('module', 'ios')); - template.render(directory, <String, dynamic>{}, printStatusWhenWriting: false); - } + _regenerateFromTemplateIfNeeded(); if (!directory.existsSync()) return; - if (Cache.instance.fileOlderThanToolsStamp(generatedXcodePropertiesFile)) { + if (Cache.instance.isOlderThanToolsStamp(generatedXcodePropertiesFile)) { await xcode.updateGeneratedXcodeProperties( project: parent, buildInfo: BuildInfo.debug, @@ -186,12 +207,23 @@ } } - Future<void> materialize() async { - throwToolExit('flutter materialize has not yet been implemented for iOS'); + void _regenerateFromTemplateIfNeeded() { + if (!isModule) + return; + final bool pubspecChanged = isOlderThanReference(entity: directory, referenceFile: parent.pubspecFile); + final bool toolingChanged = Cache.instance.isOlderThanToolsStamp(directory); + if (!pubspecChanged && !toolingChanged) + return; + _deleteIfExistsSync(directory); + _overwriteFromTemplate(fs.path.join('module', 'ios', 'library'), directory); + _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral'), directory); + if (hasPlugins(parent)) { + _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral_cocoapods'), directory); + } } - bool _shouldRegenerateFromTemplate() { - return Cache.instance.fileOlderThanToolsStamp(directory.childFile('podhelper.rb')); + Future<void> materialize() async { + throwToolExit('flutter materialize has not yet been implemented for iOS'); } File get generatedXcodePropertiesFile => directory.childDirectory('Flutter').childFile('Generated.xcconfig'); @@ -199,7 +231,20 @@ Directory get pluginRegistrantHost { return isModule ? directory.childDirectory('Flutter').childDirectory('FlutterPluginRegistrant') - : directory.childDirectory('Runner'); + : directory.childDirectory(_hostAppBundleName); + } + + void _overwriteFromTemplate(String path, Directory target) { + final Template template = new Template.fromName(path); + template.render( + target, + <String, dynamic>{ + 'projectName': parent.manifest.appName, + 'iosIdentifier': parent.manifest.iosBundleIdentifier + }, + printStatusWhenWriting: false, + overwriteExisting: true, + ); } } @@ -237,7 +282,7 @@ bool get isModule => parent.isModule; File get appManifestFile { - return isUsingGradle() + return isUsingGradle ? fs.file(fs.path.join(hostAppGradleRoot.path, 'app', 'src', 'main', 'AndroidManifest.xml')) : hostAppGradleRoot.childFile('AndroidManifest.xml'); } @@ -248,18 +293,18 @@ return fs.directory(fs.path.join(hostAppGradleRoot.path, 'app', 'build', 'outputs', 'apk')); } - bool isUsingGradle() { + bool get isUsingGradle { return hostAppGradleRoot.childFile('build.gradle').existsSync(); } - Future<String> applicationId() { + String get applicationId { final File gradleFile = hostAppGradleRoot.childDirectory('app').childFile('build.gradle'); - return _firstMatchInFile(gradleFile, _applicationIdPattern).then((Match match) => match?.group(1)); + return _firstMatchInFile(gradleFile, _applicationIdPattern)?.group(1); } - Future<String> group() { + String get group { final File gradleFile = hostAppGradleRoot.childFile('build.gradle'); - return _firstMatchInFile(gradleFile, _groupPattern).then((Match match) => match?.group(1)); + return _firstMatchInFile(gradleFile, _groupPattern)?.group(1); } Future<void> ensureReadyForPlatformSpecificTooling() async { @@ -278,7 +323,8 @@ } bool _shouldRegenerateFromTemplate() { - return Cache.instance.fileOlderThanToolsStamp(_ephemeralDirectory.childFile('build.gradle')); + return isOlderThanReference(entity: _ephemeralDirectory, referenceFile: parent.pubspecFile) + || Cache.instance.isOlderThanToolsStamp(_ephemeralDirectory); } Future<void> materialize() async { @@ -305,11 +351,6 @@ gradle.injectGradleWrapper(_ephemeralDirectory); } - void _deleteIfExistsSync(Directory directory) { - if (directory.existsSync()) - directory.deleteSync(recursive: true); - } - void _overwriteFromTemplate(String path, Directory target) { final Template template = new Template.fromName(path); template.render( @@ -324,17 +365,25 @@ } } -/// Asynchronously returns the first line-based match for [regExp] in [file]. +/// Deletes [directory] with all content. +void _deleteIfExistsSync(Directory directory) { + if (directory.existsSync()) + directory.deleteSync(recursive: true); +} + + +/// Returns the first line-based match for [regExp] in [file]. /// /// Assumes UTF8 encoding. -Future<Match> _firstMatchInFile(File file, RegExp regExp) async { - if (!await file.exists()) { +Match _firstMatchInFile(File file, RegExp regExp) { + if (!file.existsSync()) { return null; } - return file - .openRead() - .transform(utf8.decoder) - .transform(const LineSplitter()) - .map(regExp.firstMatch) - .firstWhere((Match match) => match != null, orElse: () => null); + for (String line in file.readAsLinesSync()) { + final Match match = regExp.firstMatch(line); + if (match != null) { + return match; + } + } + return null; }
diff --git a/packages/flutter_tools/schema/pubspec_yaml.json b/packages/flutter_tools/schema/pubspec_yaml.json index deafe91..0a4b56e 100644 --- a/packages/flutter_tools/schema/pubspec_yaml.json +++ b/packages/flutter_tools/schema/pubspec_yaml.json
@@ -47,7 +47,8 @@ "type": "object", "additionalProperties": false, "properties": { - "androidPackage": { "type": "string" } + "androidPackage": { "type": "string" }, + "iosBundleIdentifier": { "type": "string" } } }, "plugin": {
diff --git a/packages/flutter_tools/templates/module/README.md b/packages/flutter_tools/templates/module/README.md index f5dc3b0..8e976a0 100644 --- a/packages/flutter_tools/templates/module/README.md +++ b/packages/flutter_tools/templates/module/README.md
@@ -25,9 +25,7 @@ Written to `.android/` or `android/`. -Mixin for adding Gradle boilerplate to Android projects. The `build.gradle` -file is a template file so that it is created, not copied, on instantiation. -That way, its timestamp reflects template instantiation time. +Mixin for adding Gradle boilerplate to Android projects. #### host_app_common @@ -59,9 +57,31 @@ ## ios -Written to the `.ios/` hidden folder. +#### library -Contents wraps Flutter/Dart code as a CocoaPods pod. +Written to the `.ios/Flutter` hidden folder. -iOS host apps can set up a dependency to this project to consume +Contents wraps Flutter/Dart code for consumption by an Xcode project. + +iOS host apps can set up a dependency to this contents to consume Flutter views. + +#### host_app_ephemeral + +Written to `.ios/` outside the `Flutter/` sub-folder. + +Combined contents define an *ephemeral* (hidden, auto-generated, +under Flutter tooling control) iOS host app with a dependency on the +`.ios/Flutter` folder contents. + +The host app does not make use of CocoaPods, and is therefore +suitable only when the Flutter part declares no plugin dependencies. + +#### host_app_ephemeral_cocoapods + +Written to `.ios/` on top of `host_app_ephemeral`. + +Adds CocoaPods support. + +Combined contents define an ephemeral host app suitable for when the +Flutter part declares plugin dependencies.
diff --git a/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl b/packages/flutter_tools/templates/module/android/gradle/build.gradle.copy.tmpl similarity index 100% rename from packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl rename to packages/flutter_tools/templates/module/android/gradle/build.gradle.copy.tmpl
diff --git a/packages/flutter_tools/templates/module/common/pubspec.yaml.tmpl b/packages/flutter_tools/templates/module/common/pubspec.yaml.tmpl index c2576b5..f1db0cf 100644 --- a/packages/flutter_tools/templates/module/common/pubspec.yaml.tmpl +++ b/packages/flutter_tools/templates/module/common/pubspec.yaml.tmpl
@@ -17,3 +17,4 @@ uses-material-design: true module: androidPackage: {{androidIdentifier}} + iosBundleIdentifier: {{iosIdentifier}}
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Debug.xcconfig b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Debug.xcconfig new file mode 100644 index 0000000..49ebc75 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Debug.xcconfig
@@ -0,0 +1 @@ +#include "Flutter.xcconfig"
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Flutter.xcconfig b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Flutter.xcconfig new file mode 100644 index 0000000..7d67901 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Flutter.xcconfig
@@ -0,0 +1,2 @@ +#include "../Flutter/Generated.xcconfig" +ENABLE_BITCODE=NO
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Release.xcconfig b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Release.xcconfig new file mode 100644 index 0000000..0a56c0c --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Config.tmpl/Release.xcconfig
@@ -0,0 +1,2 @@ +#include "Flutter.xcconfig" +FLUTTER_BUILD_MODE=release
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.h b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.h new file mode 100644 index 0000000..36e21bb --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.h
@@ -0,0 +1,6 @@ +#import <Flutter/Flutter.h> +#import <UIKit/UIKit.h> + +@interface AppDelegate : FlutterAppDelegate + +@end
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.m b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.m new file mode 100644 index 0000000..9b9ce33 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.m
@@ -0,0 +1,10 @@ +#include "AppDelegate.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..3d43d11 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png Binary files differ
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/README.md b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Base.lproj/LaunchScreen.storyboard b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="EHf-IW-A2E"> + <objects> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> + <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> + </imageView> + </subviews> + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <constraints> + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> + </constraints> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="53" y="375"/> + </scene> + </scenes> + <resources> + <image name="LaunchImage" width="168" height="185"/> + </resources> +</document>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Base.lproj/Main.storyboard b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> + </dependencies> + <scenes> + <!--Flutter View Controller--> + <scene sceneID="tne-QT-ifu"> + <objects> + <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> + </objects> + </scene> + </scenes> +</document>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl new file mode 100644 index 0000000..3a4012f --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl
@@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>{{projectName}}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>$(FLUTTER_BUILD_NAME)</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>$(FLUTTER_BUILD_NUMBER)</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UIMainStoryboardFile</key> + <string>Main</string> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> + <key>UISupportedInterfaceOrientations~ipad</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> + <key>UIViewControllerBasedStatusBarAppearance</key> + <false/> +</dict> +</plist>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/main.m b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/main.m new file mode 100644 index 0000000..dff6597 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/main.m
@@ -0,0 +1,9 @@ +#import <Flutter/Flutter.h> +#import <UIKit/UIKit.h> +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +}
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.pbxproj.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.pbxproj.tmpl new file mode 100644 index 0000000..7b0eeb1 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.pbxproj.tmpl
@@ -0,0 +1,435 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; + 741F496221355F47001E2961 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 741F495E21355F27001E2961 /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 741F496821356857001E2961 /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 741F496521356807001E2961 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 74974048213559DB008C567A /* Release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 74974046213559DB008C567A /* Release.xcconfig */; }; + 74974049213559DB008C567A /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 74974047213559DB008C567A /* Debug.xcconfig */; }; + 7497404B213559E7008C567A /* Flutter.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 7497404A213559E7008C567A /* Flutter.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 741F496321355F47001E2961 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 741F496821356857001E2961 /* App.framework in Embed Frameworks */, + 741F496221355F47001E2961 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; + 741F495E21355F27001E2961 /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/engine/Flutter.framework; sourceTree = "<group>"; }; + 741F496521356807001E2961 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; }; + 74974046213559DB008C567A /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; + 74974047213559DB008C567A /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; + 7497404A213559E7008C567A /* Flutter.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Flutter.xcconfig; sourceTree = "<group>"; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 741F49642135620F001E2961 /* Config */ = { + isa = PBXGroup; + children = ( + 74974047213559DB008C567A /* Debug.xcconfig */, + 74974046213559DB008C567A /* Release.xcconfig */, + 7497404A213559E7008C567A /* Flutter.xcconfig */, + ); + path = Config; + sourceTree = "<group>"; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 741F496521356807001E2961 /* App.framework */, + 741F495E21355F27001E2961 /* Flutter.framework */, + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = "<group>"; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 741F49642135620F001E2961 /* Config */, + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = "<group>"; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + ); + path = Runner; + sourceTree = "<group>"; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 741F496321355F47001E2961 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 74974049213559DB008C567A /* Debug.xcconfig in Resources */, + 74974048213559DB008C567A /* Release.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 7497404B213559E7008C567A /* Flutter.xcconfig in Resources */, + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = "<group>"; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 74974047213559DB008C567A /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + "$(PROJECT_DIR)/Flutter/engine", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = {{iosIdentifier}}; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 74974046213559DB008C567A /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + "$(PROJECT_DIR)/Flutter/engine", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = {{iosIdentifier}}; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +}
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 new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "group:Runner.xcodeproj"> + </FileRef> +</Workspace>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/xcshareddata/xcschemes/Runner.xcscheme b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..1263ac8 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcodeproj.tmpl/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0910" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "97C146ED1CF9000F007C117D" + BuildableName = "Runner.app" + BlueprintName = "Runner" + ReferencedContainer = "container:Runner.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "97C146ED1CF9000F007C117D" + BuildableName = "Runner.app" + BlueprintName = "Runner" + ReferencedContainer = "container:Runner.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "97C146ED1CF9000F007C117D" + BuildableName = "Runner.app" + BlueprintName = "Runner" + ReferencedContainer = "container:Runner.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "97C146ED1CF9000F007C117D" + BuildableName = "Runner.app" + BlueprintName = "Runner" + ReferencedContainer = "container:Runner.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcworkspace.tmpl/contents.xcworkspacedata b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcworkspace.tmpl/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.xcworkspace.tmpl/contents.xcworkspacedata
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "group:Runner.xcodeproj"> + </FileRef> +</Workspace>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Config.tmpl/Debug.xcconfig b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Config.tmpl/Debug.xcconfig new file mode 100644 index 0000000..da820d1 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Config.tmpl/Debug.xcconfig
@@ -0,0 +1,2 @@ +#include "Flutter.xcconfig" +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Config.tmpl/Release.xcconfig b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Config.tmpl/Release.xcconfig new file mode 100644 index 0000000..4fc6f7f --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Config.tmpl/Release.xcconfig
@@ -0,0 +1,3 @@ +#include "Flutter.xcconfig" +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +FLUTTER_BUILD_MODE=release
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl new file mode 100644 index 0000000..f11c13a --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl
@@ -0,0 +1,6 @@ +platform :ios, '8.0' + +target 'Runner' do + flutter_application_path = '../' + eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb'))) +end
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Runner.tmpl/AppDelegate.m b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Runner.tmpl/AppDelegate.m new file mode 100644 index 0000000..cb3bdff --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Runner.tmpl/AppDelegate.m
@@ -0,0 +1,12 @@ +#include "AppDelegate.h" +#import "FlutterPluginRegistrant/GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end
diff --git a/packages/flutter_tools/templates/module/ios/Flutter.tmpl/AppFrameworkInfo.plist.copy.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/AppFrameworkInfo.plist similarity index 100% rename from packages/flutter_tools/templates/module/ios/Flutter.tmpl/AppFrameworkInfo.plist.copy.tmpl rename to packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/AppFrameworkInfo.plist
diff --git a/packages/flutter_tools/templates/module/ios/Flutter.tmpl/README.md.copy.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/README.md similarity index 100% rename from packages/flutter_tools/templates/module/ios/Flutter.tmpl/README.md.copy.tmpl rename to packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/README.md
diff --git a/packages/flutter_tools/templates/module/ios/Flutter.tmpl/podhelper.rb.copy.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb similarity index 87% rename from packages/flutter_tools/templates/module/ios/Flutter.tmpl/podhelper.rb.copy.tmpl rename to packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb index e9a3eb6..eec077a 100644 --- a/packages/flutter_tools/templates/module/ios/Flutter.tmpl/podhelper.rb.copy.tmpl +++ b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb
@@ -1,11 +1,3 @@ -# This file should be used from the target section of the host-app's Podfile like this: -# ``` -# target 'host' do -# flutter_application_path = /"(.*)\/.ios\/Flutter\/Generated.xcconfig"/.match(File.read("./Flutter/FlutterConfig.xcconfig"))[1] -# eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb'))) -# end -# ``` - def parse_KV_file(file, separator='=') file_abs_path = File.expand_path(file) if !File.exists? file_abs_path
diff --git a/packages/flutter_tools/test/application_package_test.dart b/packages/flutter_tools/test/application_package_test.dart index bba01f3..bdd6792 100644 --- a/packages/flutter_tools/test/application_package_test.dart +++ b/packages/flutter_tools/test/application_package_test.dart
@@ -41,17 +41,6 @@ }); }); - group('BuildableIOSApp', () { - testUsingContext('check isSwift', () { - final BuildableIOSApp buildableIOSApp = new BuildableIOSApp( - projectBundleId: 'blah', - appDirectory: 'not/important', - buildSettings: _swiftBuildSettings, - ); - expect(buildableIOSApp.isSwift, true); - }); - }); - group('PrebuiltIOSApp', () { final Map<Type, Generator> overrides = <Type, Generator>{ FileSystem: () => new MemoryFileSystem(), @@ -165,19 +154,6 @@ }); } -final Map<String, String> _swiftBuildSettings = <String, String>{ - 'ARCHS': 'arm64', - 'ASSETCATALOG_COMPILER_APPICON_NAME': 'AppIcon', - 'CLANG_ENABLE_MODULES': 'YES', - 'ENABLE_BITCODE': 'NO', - 'INFOPLIST_FILE': 'Runner/Info.plist', - 'PRODUCT_BUNDLE_IDENTIFIER': 'com.example.test', - 'PRODUCT_NAME': 'blah', - 'SWIFT_OBJC_BRIDGING_HEADER': 'Runner/Runner-Bridging-Header.h', - 'SWIFT_OPTIMIZATION_LEVEL': '-Onone', - 'SWIFT_VERSION': '3.0', -}; - const String _aaptDataWithExplicitEnabledActivity = '''N: android=http://schemas.android.com/apk/res/android E: manifest (line=7)
diff --git a/packages/flutter_tools/test/commands/create_test.dart b/packages/flutter_tools/test/commands/create_test.dart index 18edcce..33530b6 100644 --- a/packages/flutter_tools/test/commands/create_test.dart +++ b/packages/flutter_tools/test/commands/create_test.dart
@@ -340,7 +340,7 @@ await _createProject(projectDir, <String>['--no-pub'], <String>[]); final FlutterProject project = await FlutterProject.fromDirectory(projectDir); expect( - await project.ios.productBundleIdentifier(), + project.ios.productBundleIdentifier, 'com.bar.foo.flutterProject', ); }, timeout: allowForCreateFlutterProject); @@ -367,7 +367,7 @@ ); final FlutterProject project = await FlutterProject.fromDirectory(projectDir); expect( - await project.example.ios.productBundleIdentifier(), + project.example.ios.productBundleIdentifier, 'com.bar.foo.flutterProjectExample', ); }, timeout: allowForCreateFlutterProject);
diff --git a/packages/flutter_tools/test/ios/code_signing_test.dart b/packages/flutter_tools/test/ios/code_signing_test.dart index dcf4600..38b6b09 100644 --- a/packages/flutter_tools/test/ios/code_signing_test.dart +++ b/packages/flutter_tools/test/ios/code_signing_test.dart
@@ -4,6 +4,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:flutter_tools/src/project.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/base/common.dart'; @@ -16,39 +17,37 @@ import '../src/common.dart'; import '../src/context.dart'; +import '../src/mocks.dart'; void main() { group('Auto signing', () { ProcessManager mockProcessManager; Config mockConfig; + IosProject mockIosProject; BuildableIOSApp app; AnsiTerminal testTerminal; setUp(() { mockProcessManager = new MockProcessManager(); mockConfig = new MockConfig(); + mockIosProject = new MockIosProject(); + when(mockIosProject.buildSettings).thenReturn(<String, String>{ + 'For our purposes': 'a non-empty build settings map is valid', + }); testTerminal = new TestTerminal(); - app = new BuildableIOSApp( - projectBundleId: 'test.app', - buildSettings: <String, String>{ - 'For our purposes': 'a non-empty build settings map is valid', - }, - ); + app = new BuildableIOSApp(mockIosProject); }); testUsingContext('No auto-sign if Xcode project settings are not available', () async { - app = new BuildableIOSApp(projectBundleId: 'test.app'); + when(mockIosProject.buildSettings).thenReturn(null); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); expect(signingConfigs, isNull); }); testUsingContext('No discovery if development team specified in Xcode project', () async { - app = new BuildableIOSApp( - projectBundleId: 'test.app', - buildSettings: <String, String>{ - 'DEVELOPMENT_TEAM': 'abc', - }, - ); + when(mockIosProject.buildSettings).thenReturn(<String, String>{ + 'DEVELOPMENT_TEAM': 'abc', + }); final Map<String, String> signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); expect(signingConfigs, isNull); expect(testLogger.statusText, equals(
diff --git a/packages/flutter_tools/test/ios/devices_test.dart b/packages/flutter_tools/test/ios/devices_test.dart index 0751177..b2a1291 100644 --- a/packages/flutter_tools/test/ios/devices_test.dart +++ b/packages/flutter_tools/test/ios/devices_test.dart
@@ -17,6 +17,7 @@ import '../src/common.dart'; import '../src/context.dart'; +import '../src/mocks.dart'; class MockIMobileDevice extends Mock implements IMobileDevice {} class MockProcessManager extends Mock implements ProcessManager {} @@ -91,9 +92,11 @@ }); group('logging', () { MockIMobileDevice mockIMobileDevice; + MockIosProject mockIosProject; setUp(() { mockIMobileDevice = new MockIMobileDevice(); + mockIosProject = new MockIosProject(); }); testUsingContext('suppresses non-Flutter lines from output', () async { @@ -117,7 +120,7 @@ final IOSDevice device = new IOSDevice('123456'); final DeviceLogReader logReader = device.getLogReader( - app: new BuildableIOSApp(projectBundleId: 'bundleId'), + app: new BuildableIOSApp(mockIosProject), ); final List<String> lines = await logReader.logLines.toList(); @@ -147,7 +150,7 @@ final IOSDevice device = new IOSDevice('123456'); final DeviceLogReader logReader = device.getLogReader( - app: new BuildableIOSApp(projectBundleId: 'bundleId'), + app: new BuildableIOSApp(mockIosProject), ); final List<String> lines = await logReader.logLines.toList();
diff --git a/packages/flutter_tools/test/ios/simulators_test.dart b/packages/flutter_tools/test/ios/simulators_test.dart index e4edf4e..5517e35 100644 --- a/packages/flutter_tools/test/ios/simulators_test.dart +++ b/packages/flutter_tools/test/ios/simulators_test.dart
@@ -13,6 +13,7 @@ import '../src/common.dart'; import '../src/context.dart'; +import '../src/mocks.dart'; class MockFile extends Mock implements File {} class MockIMobileDevice extends Mock implements IMobileDevice {} @@ -291,9 +292,11 @@ group('log reader', () { MockProcessManager mockProcessManager; + MockIosProject mockIosProject; setUp(() { mockProcessManager = new MockProcessManager(); + mockIosProject = new MockIosProject(); }); testUsingContext('simulator can output `)`', () async { @@ -316,7 +319,7 @@ final IOSSimulator device = new IOSSimulator('123456', category: 'iOS 11.0'); final DeviceLogReader logReader = device.getLogReader( - app: new BuildableIOSApp(projectBundleId: 'bundleId'), + app: new BuildableIOSApp(mockIosProject), ); final List<String> lines = await logReader.logLines.toList();
diff --git a/packages/flutter_tools/test/project_test.dart b/packages/flutter_tools/test/project_test.dart index bdde5d2..3e3ce86 100644 --- a/packages/flutter_tools/test/project_test.dart +++ b/packages/flutter_tools/test/project_test.dart
@@ -224,50 +224,50 @@ group('organization names set', () { testInMemory('is empty, if project not created', () async { final FlutterProject project = await someProject(); - expect(await project.organizationNames(), isEmpty); + expect(project.organizationNames, isEmpty); }); testInMemory('is empty, if no platform folders exist', () async { final FlutterProject project = await someProject(); project.directory.createSync(); - expect(await project.organizationNames(), isEmpty); + expect(project.organizationNames, isEmpty); }); testInMemory('is populated from iOS bundle identifier', () async { final FlutterProject project = await someProject(); addIosWithBundleId(project.directory, 'io.flutter.someProject'); - expect(await project.organizationNames(), <String>['io.flutter']); + expect(project.organizationNames, <String>['io.flutter']); }); testInMemory('is populated from Android application ID', () async { final FlutterProject project = await someProject(); addAndroidWithApplicationId(project.directory, 'io.flutter.someproject'); - expect(await project.organizationNames(), <String>['io.flutter']); + expect(project.organizationNames, <String>['io.flutter']); }); testInMemory('is populated from iOS bundle identifier in plugin example', () async { final FlutterProject project = await someProject(); addIosWithBundleId(project.example.directory, 'io.flutter.someProject'); - expect(await project.organizationNames(), <String>['io.flutter']); + expect(project.organizationNames, <String>['io.flutter']); }); testInMemory('is populated from Android application ID in plugin example', () async { final FlutterProject project = await someProject(); addAndroidWithApplicationId(project.example.directory, 'io.flutter.someproject'); - expect(await project.organizationNames(), <String>['io.flutter']); + expect(project.organizationNames, <String>['io.flutter']); }); testInMemory('is populated from Android group in plugin', () async { final FlutterProject project = await someProject(); addAndroidWithGroup(project.directory, 'io.flutter.someproject'); - expect(await project.organizationNames(), <String>['io.flutter']); + expect(project.organizationNames, <String>['io.flutter']); }); testInMemory('is singleton, if sources agree', () async { final FlutterProject project = await someProject(); addIosWithBundleId(project.directory, 'io.flutter.someProject'); addAndroidWithApplicationId(project.directory, 'io.flutter.someproject'); - expect(await project.organizationNames(), <String>['io.flutter']); + expect(project.organizationNames, <String>['io.flutter']); }); testInMemory('is non-singleton, if sources disagree', () async { final FlutterProject project = await someProject(); addIosWithBundleId(project.directory, 'io.flutter.someProject'); addAndroidWithApplicationId(project.directory, 'io.clutter.someproject'); expect( - await project.organizationNames(), + project.organizationNames, <String>['io.flutter', 'io.clutter'], ); });
diff --git a/packages/flutter_tools/test/src/mocks.dart b/packages/flutter_tools/test/src/mocks.dart index a4326e0..2ed3e0a 100644 --- a/packages/flutter_tools/test/src/mocks.dart +++ b/packages/flutter_tools/test/src/mocks.dart
@@ -16,6 +16,7 @@ import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/ios/simulators.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:mockito/mockito.dart'; import 'package:process/process.dart'; @@ -29,10 +30,7 @@ file: fs.file('/mock/path/to/android/SkyShell.apk'), launchActivity: 'io.flutter.android.mock.MockActivity' ), - iOS: new BuildableIOSApp( - appDirectory: '/mock/path/to/iOS/SkyShell.app', - projectBundleId: 'io.flutter.ios.mock' - ) + iOS: new BuildableIOSApp(new MockIosProject()) ); } @@ -335,6 +333,14 @@ Stream<Device> get onRemoved => _onRemovedController.stream; } +class MockIosProject extends Mock implements IosProject { + @override + String get productBundleIdentifier => 'com.example.test'; + + @override + String get hostAppBundleName => 'Runner.app'; +} + class MockAndroidDevice extends Mock implements AndroidDevice { @override Future<TargetPlatform> get targetPlatform async => TargetPlatform.android_arm;