diff --git a/starter/dart_runner.js b/starter/dart_runner.js
index f940e020f..f238f281d 100644
--- a/starter/dart_runner.js
+++ b/starter/dart_runner.js
@@ -8,32 +8,32 @@ const modules = [
{
name: 'camera',
path: 'scripts/modules/enable_camera.dart',
- parameters: ['camera_description', 'platform']
+ parameters: ['camera_description']
},
{
name: 'files',
path: 'scripts/modules/enable_files.dart',
- parameters: ['photo_library_description', 'music_description', 'platform']
+ parameters: ['photo_library_description', 'music_description']
},
{
name: 'contacts',
path: 'scripts/modules/enable_contacts.dart',
- parameters: ['contacts_description', 'platform']
+ parameters: ['contacts_description']
},
{
name: 'connect',
path: 'scripts/modules/enable_connect.dart',
- parameters: [],
+ parameters: ['camera_description'],
},
{
name: 'location',
path: 'scripts/modules/enable_location.dart',
- parameters: []
+ parameters: ['in_use_location_description', 'always_use_location_description', 'google_maps', 'google_maps_api_key']
},
{
name: 'deeplink',
path: 'scripts/modules/enable_deeplink.dart',
- parameters: []
+ parameters: ['branch_live_key', 'branch_test_key', 'use_test_key']
},
{
name: 'firebaseAnalytics',
diff --git a/starter/scripts/modules/enable_connect.dart b/starter/scripts/modules/enable_connect.dart
index 1582641f5..8e4013410 100644
--- a/starter/scripts/modules/enable_connect.dart
+++ b/starter/scripts/modules/enable_connect.dart
@@ -28,6 +28,13 @@ ensemble_connect:
}
];
+ final iOSPermissions = [
+ {
+ 'key': 'camera_description',
+ 'value': 'NSCameraUsageDescription',
+ }
+ ];
+
try {
// Update the ensemble_modules.dart file
updateEnsembleModules(
@@ -39,6 +46,20 @@ ensemble_connect:
// Update the pubspec.yaml file
updatePubspec(pubspecFilePath, pubspecDependencies);
+ // Add the camera usage description to the iOS Info.plist file
+ if (platforms.contains('ios')) {
+ updateIOSPermissions(iosInfoPlistFilePath, iOSPermissions, arguments);
+ }
+
+ // Add the ',
+ );
+ }
+
print(
'Connect module enabled successfully for ${platforms.join(', ')}! 🎉');
exit(0);
diff --git a/starter/scripts/modules/enable_location.dart b/starter/scripts/modules/enable_location.dart
index 550cf1582..61cc9dca8 100644
--- a/starter/scripts/modules/enable_location.dart
+++ b/starter/scripts/modules/enable_location.dart
@@ -1,9 +1,12 @@
import 'dart:io';
-
import '../utils.dart';
void main(List arguments) {
List platforms = getPlatforms(arguments);
+ bool? hasGoogleMaps =
+ getArgumentValue(arguments, 'google_maps')?.toLowerCase() == 'true';
+ String? googleMapsApiKey = getArgumentValue(arguments, 'google_maps_api_key',
+ required: hasGoogleMaps);
final statements = {
'moduleStatements': [
@@ -28,6 +31,21 @@ ensemble_location:
}
];
+ final androidPermissions = [
+ '',
+ ];
+
+ final iOSPermissions = [
+ {
+ 'key': 'in_use_location_description',
+ 'value': 'NSLocationWhenInUseUsageDescription',
+ },
+ {
+ 'key': 'always_use_location_description',
+ 'value': 'NSLocationAlwaysUsageDescription',
+ }
+ ];
+
try {
// Update the ensemble_modules.dart file
updateEnsembleModules(
@@ -39,6 +57,30 @@ ensemble_location:
// Update the pubspec.yaml file
updatePubspec(pubspecFilePath, pubspecDependencies);
+ // Add the location permissions to AndroidManifest.xml
+ if (platforms.contains('android')) {
+ updateAndroidPermissions(androidManifestFilePath, androidPermissions);
+ }
+
+ // Add the location usage description to the iOS Info.plist file
+ if (platforms.contains('ios')) {
+ updateIOSPermissions(iosInfoPlistFilePath, iOSPermissions, arguments);
+ }
+
+ // Update Google Maps API key if available
+ if (hasGoogleMaps == true && googleMapsApiKey != null) {
+ updatePropertiesFile(
+ ensemblePropertiesFilePath, 'googleMapsAPIKey', googleMapsApiKey);
+ if (platforms.contains('ios')) {
+ updateAppDelegateForGoogleMaps(appDelegatePath, googleMapsApiKey);
+ }
+
+ if (platforms.contains('web')) {
+ updateHtmlFile(webIndexFilePath, '',
+ '');
+ }
+ }
+
print(
'Location module enabled successfully for ${platforms.join(', ')}! 🎉');
exit(0);
diff --git a/starter/scripts/utils.dart b/starter/scripts/utils.dart
index 7663a7bb3..a34e19fbb 100644
--- a/starter/scripts/utils.dart
+++ b/starter/scripts/utils.dart
@@ -5,6 +5,9 @@ const String pubspecFilePath = 'pubspec.yaml';
const String androidManifestFilePath =
'android/app/src/main/AndroidManifest.xml';
const String iosInfoPlistFilePath = 'ios/Runner/Info.plist';
+const String webIndexFilePath = 'web/index.html';
+const String ensemblePropertiesFilePath = 'ensemble/ensemble.properties';
+const String appDelegatePath = 'ios/Runner/AppDelegate.swift';
// To read file content
String readFileContent(String filePath) {
@@ -16,13 +19,19 @@ String readFileContent(String filePath) {
}
// Helper function to parse individual arguments in key=value format
-String? getArgumentValue(List arguments, String key) {
+String? getArgumentValue(List arguments, String key,
+ {bool required = false}) {
for (var arg in arguments) {
final parts = arg.split('=');
if (parts.length == 2 && parts[0] == key) {
return parts[1];
}
}
+
+ if (required) {
+ throw Exception('Missing required argument: $key');
+ }
+
return null;
}
@@ -188,11 +197,17 @@ void updatePubspec(
// Update AndroidManifest.xml with permissions and throw error if not updated
void updateAndroidPermissions(
String manifestFilePath, List permissions) {
+ String manifestContent = readFileContent(manifestFilePath);
+
for (var permission in permissions) {
- addPermissionToAndroidManifest(
- manifestFilePath,
- '',
- permission);
+ // Check if the permission already exists in the manifest
+ if (!manifestContent.contains(permission)) {
+ // Add the permission if it doesn't exist
+ addPermissionToAndroidManifest(
+ manifestFilePath,
+ '',
+ permission);
+ }
}
}
@@ -225,3 +240,65 @@ void updateIOSPermissions(String plistFilePath,
}
}
}
+
+// To update an HTML file with a new content before a specific marker (like )
+void updateHtmlFile(String filePath, String marker, String contentToAdd) {
+ // Check if the HTML file exists
+ if (!File(filePath).existsSync()) {
+ throw Exception('Error: $filePath not found');
+ }
+
+ String content = File(filePath).readAsStringSync();
+
+ if (!content.contains(contentToAdd)) {
+ // Insert the new content before the marker (e.g., )
+ content = content.replaceFirst(marker, ' $contentToAdd\n$marker');
+ File(filePath).writeAsStringSync(content);
+ }
+}
+
+void updatePropertiesFile(String filePath, String key, String value) {
+ File propertiesFile = File(filePath);
+ if (!propertiesFile.existsSync()) {
+ throw Exception('Error: $filePath not found.');
+ }
+
+ List lines = propertiesFile.readAsLinesSync();
+ bool updated = false;
+
+ for (int i = 0; i < lines.length; i++) {
+ if (lines[i].startsWith('$key=')) {
+ lines[i] = '$key=$value';
+ updated = true;
+ break;
+ }
+ }
+
+ if (!updated) {
+ lines.add('$key=$value');
+ }
+
+ propertiesFile.writeAsStringSync(lines.join('\n').trim());
+}
+
+void updateAppDelegateForGoogleMaps(String filePath, String googleMapsApiKey) {
+ File appDelegateFile = File(filePath);
+ if (!appDelegateFile.existsSync()) {
+ throw Exception('Error: $filePath not found.');
+ }
+
+ // Read the file content
+ String content = appDelegateFile.readAsStringSync();
+
+ // Uncomment the Google Maps import and API key lines if they are commented
+ content = content.replaceAllMapped(
+ RegExp(r'\/\/\s*import\s+GoogleMaps'), (match) => 'import GoogleMaps');
+
+ content = content.replaceAllMapped(
+ RegExp(r'\/\/\s*GMSServices\.provideAPIKey\("(.*?)"\)'),
+ (match) => ' GMSServices.provideAPIKey("$googleMapsApiKey")');
+
+ // Write the updated content back to the file
+ appDelegateFile.writeAsStringSync(content.trim());
+ print('AppDelegate.swift updated successfully with Google Maps API key.');
+}