diff --git a/.gitignore b/.gitignore index 6f135de6ed3..0771d0eb5ab 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ unlinked_spec.ds **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ +**/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ diff --git a/examples/platform_view/README.md b/examples/platform_view/README.md index c677d67f8d7..e13dec4f821 100644 --- a/examples/platform_view/README.md +++ b/examples/platform_view/README.md @@ -1,3 +1,12 @@ # Example of switching between full-screen Flutter and Platform View -This project demonstrates how to bring up a full-screen iOS/Android view from a full-screen Flutter view along with passing data back and forth between the two. \ No newline at end of file +This project demonstrates how to bring up a full-screen iOS/Android view from a +full-screen Flutter view along with passing data back and forth between the two. + +On iOS we use a CocoaPods dependency to add a Material Design button, and so +`pod install` needs to be invoked in the `ios/` folder before `flutter run`: + +``` +pushd ios/ ; pod install ; popd +flutter run +``` diff --git a/examples/platform_view/ios/Podfile b/examples/platform_view/ios/Podfile index 0d9b7dd2f29..b44ccaa0dbe 100644 --- a/examples/platform_view/ios/Podfile +++ b/examples/platform_view/ios/Podfile @@ -1,33 +1,59 @@ # Uncomment this line to define a global platform for your project # platform :ios, '9.0' -if ENV['FLUTTER_FRAMEWORK_DIR'] == nil - abort('Please set FLUTTER_FRAMEWORK_DIR to the directory containing Flutter.framework') -end +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' -target 'Runner' do - use_frameworks! - - # Pods for Runner - pod 'MaterialControls' - - # Flutter Pods - pod 'Flutter', :path => ENV['FLUTTER_FRAMEWORK_DIR'] - - if File.exists? '../.flutter-plugins' - flutter_root = File.expand_path('..') - File.foreach('../.flutter-plugins') { |line| - plugin = line.split(pattern='=') +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + pods_ary = [] + 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 - name = plugin[0].strip() + podname = plugin[0].strip() path = plugin[1].strip() - resolved_path = File.expand_path("#{path}/ios", flutter_root) - pod name, :path => resolved_path + 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 +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 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])) + end + } + + # Plugin Pods + 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') + } + + pod 'MaterialControls' end post_install do |installer| diff --git a/examples/platform_view/ios/Podfile.lock b/examples/platform_view/ios/Podfile.lock index 835dcf84d48..1d0239cc659 100644 --- a/examples/platform_view/ios/Podfile.lock +++ b/examples/platform_view/ios/Podfile.lock @@ -3,13 +3,21 @@ PODS: - MaterialControls (1.2.2) DEPENDENCIES: - - Flutter (from `/Users/zarah/flutter/bin/cache/artifacts/engine/ios`) + - Flutter (from `.symlinks/flutter/ios`) - MaterialControls +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - MaterialControls + +EXTERNAL SOURCES: + Flutter: + :path: ".symlinks/flutter/ios" + SPEC CHECKSUMS: - Flutter: d674e78c937094a75ac71dd77e921e840bea3dbf + Flutter: 9d0fac939486c9aba2809b7982dfdbb47a7b0296 MaterialControls: 1c6b29e78d3a13d8dd6a67ed31b6d26eb5de8f72 -PODFILE CHECKSUM: d6aabe8e71e2432dda8b99c2a5dbd2bdd65b3c0c +PODFILE CHECKSUM: 4a320bf98e7f7e414d7d7f5079edf1b2d6679c9b -COCOAPODS: 1.2.1 +COCOAPODS: 1.5.2 diff --git a/examples/platform_view/ios/Runner.xcodeproj/project.pbxproj b/examples/platform_view/ios/Runner.xcodeproj/project.pbxproj index e40b4f10670..5bec6ef6c57 100644 --- a/examples/platform_view/ios/Runner.xcodeproj/project.pbxproj +++ b/examples/platform_view/ios/Runner.xcodeproj/project.pbxproj @@ -8,13 +8,12 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 2DAF064C1ED38C3E00716BEE /* PlatformViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DAF064B1ED38C3E00716BEE /* PlatformViewController.m */; }; 2DAF064E1ED4224F00716BEE /* ic_add.png in Resources */ = {isa = PBXBuildFile; fileRef = 2DAF064D1ED4224F00716BEE /* ic_add.png */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BA46596ABA518F51EA58D4E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D1B5578FA4D9AA771FA85C8 /* Pods_Runner.framework */; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; @@ -24,6 +23,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + ECB86F1A0B90276D0AEF4169 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E6555FD3971FC12A9802782 /* libPods-Runner.a */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -44,13 +44,13 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 2DAF064A1ED38C2300716BEE /* PlatformViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformViewController.h; sourceTree = ""; }; 2DAF064B1ED38C3E00716BEE /* PlatformViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlatformViewController.m; sourceTree = ""; }; 2DAF064D1ED4224F00716BEE /* ic_add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_add.png; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 6D1B5578FA4D9AA771FA85C8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6E6555FD3971FC12A9802782 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -72,28 +72,20 @@ files = ( 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - 8BA46596ABA518F51EA58D4E /* Pods_Runner.framework in Frameworks */, + ECB86F1A0B90276D0AEF4169 /* libPods-Runner.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 3B3C98E6C891D133450756AD /* Pods */ = { + 5A56E2F315C4CB64895375DA /* Pods */ = { isa = PBXGroup; children = ( ); name = Pods; sourceTree = ""; }; - 7CA8E998102019A63A09E65A /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6D1B5578FA4D9AA771FA85C8 /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -114,8 +106,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 3B3C98E6C891D133450756AD /* Pods */, - 7CA8E998102019A63A09E65A /* Frameworks */, + 5A56E2F315C4CB64895375DA /* Pods */, + E9007A48891C669D010E4F3D /* Frameworks */, ); sourceTree = ""; }; @@ -154,6 +146,14 @@ name = "Supporting Files"; sourceTree = ""; }; + E9007A48891C669D010E4F3D /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6E6555FD3971FC12A9802782 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -161,15 +161,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - F869B9DE0F60F9C16FF08EE0 /* [CP] Check Pods Manifest.lock */, + BE1F6A680926BCE299C7F0C1 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - A875464D32C7B41BBF6F7738 /* [CP] Embed Pods Frameworks */, - BFF083CE02D0AAF0AAF9BBA9 /* [CP] Copy Pods Resources */, + 23ADFA8256C517EB939E4349 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -231,6 +230,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 23ADFA8256C517EB939E4349 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../.symlinks/flutter/ios/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"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -259,49 +276,22 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - A875464D32C7B41BBF6F7738 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - BFF083CE02D0AAF0AAF9BBA9 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - F869B9DE0F60F9C16FF08EE0 /* [CP] Check Pods Manifest.lock */ = { + BE1F6A680926BCE299C7F0C1 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */