Skip to content

Commit

Permalink
Fix issue where hot restart would cause duplicate plugin registration…
Browse files Browse the repository at this point in the history
… and crash
  • Loading branch information
bkonyi committed Nov 1, 2019
1 parent 8068462 commit 49224f5
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 67 deletions.
92 changes: 58 additions & 34 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,80 @@
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
pods_ary = []
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
File.foreach(file_abs_path) do |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
end
end
generated_key_values
end

target 'Runner' do
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
# Flutter Pod

# Flutter Pods
generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
if generated_xcode_build_settings.empty?
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
end
generated_xcode_build_settings.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join('.symlinks', 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.

generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
}
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];

unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end

# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'

# Plugin Pods

# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join('.symlinks', 'plugins', p[:name])
File.symlink(p[:path], symlink)
pod p[:name], :path => File.join(symlink, 'ios')
}
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
end

# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true

post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
Expand Down
18 changes: 6 additions & 12 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
PODS:
- Flutter (1.0.0)
- flutter_local_notifications (0.0.1):
- Flutter
- geofencing (0.0.1):
- Flutter

DEPENDENCIES:
- Flutter (from `.symlinks/flutter/ios_debug_sim`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- Flutter (from `Flutter`)
- geofencing (from `.symlinks/plugins/geofencing/ios`)

EXTERNAL SOURCES:
Flutter:
:path: ".symlinks/flutter/ios_debug_sim"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
:path: Flutter
geofencing:
:path: ".symlinks/plugins/geofencing/ios"

SPEC CHECKSUMS:
Flutter: 9d0fac939486c9aba2809b7982dfdbb47a7b0296
flutter_local_notifications: 696a74904e0a0ab754e27a5f761da4a7f9153710
geofencing: 03e5e092597a2619fb90fc277d31932752595b00
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
geofencing: f963c883322f1f6123301be3fa9af86e64afb7fb

PODFILE CHECKSUM: 1e5af4103afd21ca5ead147d7b81d06f494f51a2
PODFILE CHECKSUM: 3dbe063e9c90a5d7c9e4e76e70a821b9e2c1d271

COCOAPODS: 1.5.3
COCOAPODS: 1.8.4
14 changes: 8 additions & 6 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
7A0C70F717F0CD54C305435B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.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>"; };
Expand All @@ -52,6 +53,7 @@
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>"; };
CD903FD956E9A22BE0DFB9AB /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -71,6 +73,8 @@
6CBC30358DFF51EA0A13FCBB /* Pods */ = {
isa = PBXGroup;
children = (
7A0C70F717F0CD54C305435B /* Pods-Runner.debug.xcconfig */,
CD903FD956E9A22BE0DFB9AB /* Pods-Runner.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
Expand Down Expand Up @@ -184,6 +188,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down Expand Up @@ -232,16 +237,13 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios_debug_sim/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
Expand Down Expand Up @@ -435,7 +437,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.geofencing;
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.geofencing2;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
Expand All @@ -459,7 +461,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.geofencing;
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.geofencing2;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
Expand Down
26 changes: 13 additions & 13 deletions example/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Required for Flutter Geofencing example events.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Required for Flutter Geofencing example events.</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand All @@ -26,20 +22,24 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Required for Flutter Geofencing example events.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Required for Flutter Geofencing example events.</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>location-services</string>
<string>gps</string>
<string>armv7</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
<array>
<string>location-services</string>
<string>gps</string>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
Expand Down
7 changes: 5 additions & 2 deletions ios/Classes/GeofencingPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ @implementation GeofencingPlugin {
static GeofencingPlugin *instance = nil;
static FlutterPluginRegistrantCallback registerPlugins = nil;
static BOOL initialized = NO;

static BOOL backgroundIsolateRun = NO;
#pragma mark FlutterPlugin Methods

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
Expand Down Expand Up @@ -167,8 +167,11 @@ - (void)startGeofencingService:(int64_t)handle {
// with the runner in order for them to work on the background isolate. `registerPlugins` is
// a callback set from AppDelegate.m in the main application. This callback should register
// all relevant plugins (excluding those which require UI).
registerPlugins(_headlessRunner);
if (!backgroundIsolateRun) {
registerPlugins(_headlessRunner);
}
[_registrar addMethodCallDelegate:self channel:_callbackChannel];
backgroundIsolateRun = YES;
}

- (void)registerGeofence:(NSArray *)arguments {
Expand Down

0 comments on commit 49224f5

Please sign in to comment.