From ee31bf1782836a95093fbfc07593e5e7f553e105 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 27 Sep 2023 11:18:19 -0700 Subject: [PATCH 1/3] Revert "Reverts "[ios] Fix app extension not able to find assets from unloaded bundle" (#46328)" This reverts commit a42f83496efea31c230ebaa06ab1fca1fb658d67. --- .../framework/Source/FlutterNSBundleUtils.mm | 21 +- .../Source/FlutterDartProjectTest.mm | 6 +- .../project.pbxproj | 372 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../FlutterAppExtensionTestHost/AppDelegate.h | 9 + .../FlutterAppExtensionTestHost/AppDelegate.m | 38 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 13 + .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 ++ .../Base.lproj/Main.storyboard | 24 ++ .../FlutterAppExtensionTestHost/Info.plist | 25 ++ .../SceneDelegate.h | 11 + .../SceneDelegate.m | 52 +++ .../ViewController.h | 9 + .../ViewController.m | 33 ++ .../FlutterAppExtensionTestHost/main.m | 15 + .../Scenarios/Info_Impeller.plist | 29 ++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../Scenarios.xcodeproj/project.pbxproj | 253 +++++++++++- .../Base.lproj/MainInterface.storyboard | 24 ++ .../ios/Scenarios/ScenariosShare/Info.plist | 18 + .../ScenariosShare/ShareViewController.h | 10 + .../ScenariosShare/ShareViewController.m | 31 ++ .../ScenariosUITests/AppExtensionTests.m | 58 +++ .../ScenariosUITests/GoldenTestManager.m | 1 + .../src/darwin_app_extension_scenario.dart | 44 +++ testing/scenario_app/lib/src/scenarios.dart | 2 + testing/scenario_app/run_ios_tests.sh | 4 +- 32 files changed, 1163 insertions(+), 16 deletions(-) create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.pbxproj create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.h create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.m create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/Contents.json create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/LaunchScreen.storyboard create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/Main.storyboard create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Info.plist create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.h create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.m create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.h create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.m create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/main.m create mode 100644 testing/scenario_app/ios/FlutterAppExtensionTestHost/Scenarios/Info_Impeller.plist create mode 100644 testing/scenario_app/ios/Scenarios.xcworkspace/contents.xcworkspacedata create mode 100644 testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosShare/Base.lproj/MainInterface.storyboard create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosShare/Info.plist create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.h create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.m create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosUITests/AppExtensionTests.m create mode 100644 testing/scenario_app/lib/src/darwin_app_extension_scenario.dart diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm index 9582f94e266e1..54cf8feeb7d8b 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm @@ -9,6 +9,7 @@ FLUTTER_ASSERT_ARC const NSString* kDefaultAssetPath = @"Frameworks/App.framework/flutter_assets"; +static NSString* GetFlutterAssetPathFromBundle(NSBundle* bundle); NSBundle* FLTFrameworkBundleInternal(NSString* flutterFrameworkBundleID, NSURL* searchURL) { NSDirectoryEnumerator* frameworkEnumerator = [NSFileManager.defaultManager @@ -29,7 +30,7 @@ } NSBundle* FLTGetApplicationBundle() { - NSBundle* mainBundle = [NSBundle mainBundle]; + NSBundle* mainBundle = NSBundle.mainBundle; // App extension bundle is in .app/PlugIns/Extension.appex. if ([mainBundle.bundleURL.pathExtension isEqualToString:@"appex"]) { // Up two levels. @@ -48,7 +49,7 @@ flutterFrameworkBundle = [NSBundle bundleWithIdentifier:flutterFrameworkBundleID]; } if (flutterFrameworkBundle == nil) { - flutterFrameworkBundle = [NSBundle mainBundle]; + flutterFrameworkBundle = NSBundle.mainBundle; } return flutterFrameworkBundle; } @@ -58,13 +59,23 @@ } NSString* FLTAssetsPathFromBundle(NSBundle* bundle) { + NSString* flutterAssetsPath = GetFlutterAssetPathFromBundle(bundle); + if (flutterAssetsPath.length == 0) { + flutterAssetsPath = GetFlutterAssetPathFromBundle(NSBundle.mainBundle); + } + return flutterAssetsPath; +} + +static NSString* GetFlutterAssetPathFromBundle(NSBundle* bundle) { NSString* flutterAssetsPath = FLTAssetPath(bundle); // Use the raw path solution so that asset path can be returned from unloaded bundles. // See https://github.com/flutter/engine/pull/46073 - NSString* assetsPath = [bundle pathForResource:flutterAssetsPath ofType:@""]; - + NSString* assetsPath = [bundle pathForResource:flutterAssetsPath ofType:nil]; if (assetsPath.length == 0) { - assetsPath = [[NSBundle mainBundle] pathForResource:flutterAssetsPath ofType:@""]; + // In app extension, using full relative path (kDefaultAssetPath) + // returns nil when the app bundle is not loaded. Try to use + // the sub folder name, which can successfully return a valid path. + assetsPath = [bundle pathForResource:@"flutter_assets" ofType:nil]; } return assetsPath; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm index aecab91f0051c..025bde32aeb2c 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm @@ -93,7 +93,7 @@ - (void)testFLTAssetsURLFromBundle { id mockBundle = OCMClassMock([NSBundle class]); OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets"); NSString* resultAssetsPath = @"path/to/foo/assets"; - OCMStub([mockBundle pathForResource:@"foo/assets" ofType:@""]).andReturn(resultAssetsPath); + OCMStub([mockBundle pathForResource:@"foo/assets" ofType:nil]).andReturn(resultAssetsPath); NSString* path = FLTAssetsPathFromBundle(mockBundle); XCTAssertEqualObjects(path, @"path/to/foo/assets"); } @@ -102,9 +102,9 @@ - (void)testFLTAssetsURLFromBundle { id mockBundle = OCMClassMock([NSBundle class]); id mockMainBundle = OCMPartialMock([NSBundle mainBundle]); NSString* resultAssetsPath = @"path/to/foo/assets"; - OCMStub([mockBundle pathForResource:@"Frameworks/App.framework/flutter_assets" ofType:@""]) + OCMStub([mockBundle pathForResource:@"Frameworks/App.framework/flutter_assets" ofType:nil]) .andReturn(nil); - OCMStub([mockMainBundle pathForResource:@"Frameworks/App.framework/flutter_assets" ofType:@""]) + OCMStub([mockMainBundle pathForResource:@"Frameworks/App.framework/flutter_assets" ofType:nil]) .andReturn(resultAssetsPath); NSString* path = FLTAssetsPathFromBundle(mockBundle); XCTAssertEqualObjects(path, @"path/to/foo/assets"); diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.pbxproj b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000..b67c72aabae64 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.pbxproj @@ -0,0 +1,372 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 686382C62ABE173000E27AAD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 686382C52ABE173000E27AAD /* AppDelegate.m */; }; + 686382C92ABE173000E27AAD /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 686382C82ABE173000E27AAD /* SceneDelegate.m */; }; + 686382CC2ABE173000E27AAD /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 686382CB2ABE173000E27AAD /* ViewController.m */; }; + 686382CF2ABE173000E27AAD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 686382CD2ABE173000E27AAD /* Main.storyboard */; }; + 686382D12ABE173000E27AAD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 686382D02ABE173000E27AAD /* Assets.xcassets */; }; + 686382D42ABE173000E27AAD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 686382D22ABE173000E27AAD /* LaunchScreen.storyboard */; }; + 686382D72ABE173000E27AAD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 686382D62ABE173000E27AAD /* main.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 686382C12ABE172F00E27AAD /* FlutterAppExtensionTestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FlutterAppExtensionTestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 686382C42ABE173000E27AAD /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 686382C52ABE173000E27AAD /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 686382C72ABE173000E27AAD /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = ""; }; + 686382C82ABE173000E27AAD /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = ""; }; + 686382CA2ABE173000E27AAD /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 686382CB2ABE173000E27AAD /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 686382CE2ABE173000E27AAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 686382D02ABE173000E27AAD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 686382D32ABE173000E27AAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 686382D52ABE173000E27AAD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 686382D62ABE173000E27AAD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 686382BE2ABE172F00E27AAD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 686382B82ABE172F00E27AAD = { + isa = PBXGroup; + children = ( + 686382C32ABE173000E27AAD /* FlutterAppExtensionTestHost */, + 686382C22ABE172F00E27AAD /* Products */, + ); + sourceTree = ""; + }; + 686382C22ABE172F00E27AAD /* Products */ = { + isa = PBXGroup; + children = ( + 686382C12ABE172F00E27AAD /* FlutterAppExtensionTestHost.app */, + ); + name = Products; + sourceTree = ""; + }; + 686382C32ABE173000E27AAD /* FlutterAppExtensionTestHost */ = { + isa = PBXGroup; + children = ( + 686382C42ABE173000E27AAD /* AppDelegate.h */, + 686382C52ABE173000E27AAD /* AppDelegate.m */, + 686382C72ABE173000E27AAD /* SceneDelegate.h */, + 686382C82ABE173000E27AAD /* SceneDelegate.m */, + 686382CA2ABE173000E27AAD /* ViewController.h */, + 686382CB2ABE173000E27AAD /* ViewController.m */, + 686382CD2ABE173000E27AAD /* Main.storyboard */, + 686382D02ABE173000E27AAD /* Assets.xcassets */, + 686382D22ABE173000E27AAD /* LaunchScreen.storyboard */, + 686382D52ABE173000E27AAD /* Info.plist */, + 686382D62ABE173000E27AAD /* main.m */, + ); + path = FlutterAppExtensionTestHost; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 686382C02ABE172F00E27AAD /* FlutterAppExtensionTestHost */ = { + isa = PBXNativeTarget; + buildConfigurationList = 686382DA2ABE173000E27AAD /* Build configuration list for PBXNativeTarget "FlutterAppExtensionTestHost" */; + buildPhases = ( + 686382BD2ABE172F00E27AAD /* Sources */, + 686382BE2ABE172F00E27AAD /* Frameworks */, + 686382BF2ABE172F00E27AAD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FlutterAppExtensionTestHost; + productName = FlutterAppExtensionTestHost; + productReference = 686382C12ABE172F00E27AAD /* FlutterAppExtensionTestHost.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 686382B92ABE172F00E27AAD /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1500; + TargetAttributes = { + 686382C02ABE172F00E27AAD = { + CreatedOnToolsVersion = 15.0; + }; + }; + }; + buildConfigurationList = 686382BC2ABE172F00E27AAD /* Build configuration list for PBXProject "FlutterAppExtensionTestHost" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 686382B82ABE172F00E27AAD; + productRefGroup = 686382C22ABE172F00E27AAD /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 686382C02ABE172F00E27AAD /* FlutterAppExtensionTestHost */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 686382BF2ABE172F00E27AAD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 686382D42ABE173000E27AAD /* LaunchScreen.storyboard in Resources */, + 686382D12ABE173000E27AAD /* Assets.xcassets in Resources */, + 686382CF2ABE173000E27AAD /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 686382BD2ABE172F00E27AAD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 686382CC2ABE173000E27AAD /* ViewController.m in Sources */, + 686382C62ABE173000E27AAD /* AppDelegate.m in Sources */, + 686382D72ABE173000E27AAD /* main.m in Sources */, + 686382C92ABE173000E27AAD /* SceneDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 686382CD2ABE173000E27AAD /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 686382CE2ABE173000E27AAD /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 686382D22ABE173000E27AAD /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 686382D32ABE173000E27AAD /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 686382D82ABE173000E27AAD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 686382D92ABE173000E27AAD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 686382DB2ABE173000E27AAD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = FlutterAppExtensionTestHost/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.FlutterAppExtensionTestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 686382DC2ABE173000E27AAD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = FlutterAppExtensionTestHost/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.FlutterAppExtensionTestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 686382BC2ABE172F00E27AAD /* Build configuration list for PBXProject "FlutterAppExtensionTestHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 686382D82ABE173000E27AAD /* Debug */, + 686382D92ABE173000E27AAD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 686382DA2ABE173000E27AAD /* Build configuration list for PBXNativeTarget "FlutterAppExtensionTestHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 686382DB2ABE173000E27AAD /* Debug */, + 686382DC2ABE173000E27AAD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 686382B92ABE172F00E27AAD /* Project object */; +} diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000..919434a6254f0 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000..18d981003d68d --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.h b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.h new file mode 100644 index 0000000000000..99c576ec95059 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.h @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +@interface AppDelegate : UIResponder + +@end diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.m b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.m new file mode 100644 index 0000000000000..1beee74b03e03 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/AppDelegate.m @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication*)application + didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { + // Override point for customization after application launch. + return YES; +} + +#pragma mark - UISceneSession lifecycle + +- (UISceneConfiguration*)application:(UIApplication*)application + configurationForConnectingSceneSession:(UISceneSession*)connectingSceneSession + options:(UISceneConnectionOptions*)options { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" + sessionRole:connectingSceneSession.role]; +} + +- (void)application:(UIApplication*)application + didDiscardSceneSessions:(NSSet*)sceneSessions { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called + // shortly after application:didFinishLaunchingWithOptions. Use this method to release any + // resources that were specific to the discarded scenes, as they will not return. +} + +@end diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AccentColor.colorset/Contents.json b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000000000..eb87897008164 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000000..13613e3ee1a93 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/Contents.json b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/Contents.json new file mode 100644 index 0000000000000..73c00596a7fca --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/LaunchScreen.storyboard b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000000..865e9329f3767 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/Main.storyboard b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/Main.storyboard new file mode 100644 index 0000000000000..808a21ce779ba --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Info.plist b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Info.plist new file mode 100644 index 0000000000000..81ed29b76cfbe --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.h b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.h new file mode 100644 index 0000000000000..6adc5d3a2cd7f --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.h @@ -0,0 +1,11 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +@interface SceneDelegate : UIResponder + +@property(strong, nonatomic) UIWindow* window; + +@end diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.m b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.m new file mode 100644 index 0000000000000..1271efb7faa5f --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/SceneDelegate.m @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "SceneDelegate.h" + +@interface SceneDelegate () + +@end + +@implementation SceneDelegate + +- (void)scene:(UIScene*)scene + willConnectToSession:(UISceneSession*)session + options:(UISceneConnectionOptions*)connectionOptions { + // Use this method to optionally configure and attach the UIWindow `window` to the provided + // UIWindowScene `scene`. If using a storyboard, the `window` property will automatically be + // initialized and attached to the scene. This delegate does not imply the connecting scene or + // session are new (see `application:configurationForConnectingSceneSession` instead). +} + +- (void)sceneDidDisconnect:(UIScene*)scene { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene + // connects. The scene may re-connect later, as its session was not necessarily discarded (see + // `application:didDiscardSceneSessions` instead). +} + +- (void)sceneDidBecomeActive:(UIScene*)scene { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was + // inactive. +} + +- (void)sceneWillResignActive:(UIScene*)scene { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). +} + +- (void)sceneWillEnterForeground:(UIScene*)scene { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. +} + +- (void)sceneDidEnterBackground:(UIScene*)scene { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state + // information to restore the scene back to its current state. +} + +@end diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.h b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.h new file mode 100644 index 0000000000000..4f235259bfecc --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.h @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +@interface ViewController : UIViewController + +@end diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.m b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.m new file mode 100644 index 0000000000000..b725cc412618f --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/ViewController.m @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + UIButton* openShare = + [UIButton systemButtonWithPrimaryAction:[UIAction actionWithHandler:^( + __kindof UIAction* _Nonnull action) { + UIActivityViewController* activityVC = + [[UIActivityViewController alloc] initWithActivityItems:@[ @"text to share" ] + applicationActivities:nil]; + activityVC.excludedActivityTypes = @[ + UIActivityTypePrint, UIActivityTypeCopyToPasteboard, + UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll + ]; // Exclude whichever aren't relevant + [self presentViewController:activityVC animated:YES completion:nil]; + }]]; + openShare.backgroundColor = [UIColor systemPinkColor]; + [openShare setTitle:@"Open Share" forState:UIControlStateNormal]; + [self.view addSubview:openShare]; + openShare.frame = CGRectMake(0, 0, 200, 200); +} + +@end diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/main.m b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/main.m new file mode 100644 index 0000000000000..f98f92491e8a0 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/FlutterAppExtensionTestHost/main.m @@ -0,0 +1,15 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + NSString* appDelegateClassName; + @autoreleasepool { + // Setup code that might create autoreleased objects goes here. + appDelegateClassName = NSStringFromClass([AppDelegate class]); + } + return UIApplicationMain(argc, argv, nil, appDelegateClassName); +} diff --git a/testing/scenario_app/ios/FlutterAppExtensionTestHost/Scenarios/Info_Impeller.plist b/testing/scenario_app/ios/FlutterAppExtensionTestHost/Scenarios/Info_Impeller.plist new file mode 100644 index 0000000000000..2ad0401d1c878 --- /dev/null +++ b/testing/scenario_app/ios/FlutterAppExtensionTestHost/Scenarios/Info_Impeller.plist @@ -0,0 +1,29 @@ + + + + + + + FLTEnableImpeller + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/testing/scenario_app/ios/Scenarios.xcworkspace/contents.xcworkspacedata b/testing/scenario_app/ios/Scenarios.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000..00ca3de9d76c0 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000..18d981003d68d --- /dev/null +++ b/testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000000..0c67376ebacb4 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index ec69054a447da..7402e6958cd9a 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -62,6 +62,12 @@ 6860CE252A01B2FF00B68EC5 /* golden_two_platform_view_clip_rrect_iPhone SE (3rd generation)_16.2_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6860CE222A01B2FF00B68EC5 /* golden_two_platform_view_clip_rrect_iPhone SE (3rd generation)_16.2_simulator.png */; }; 6860CE262A01B2FF00B68EC5 /* golden_two_platform_view_clip_rect_iPhone SE (3rd generation)_16.2_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6860CE232A01B2FF00B68EC5 /* golden_two_platform_view_clip_rect_iPhone SE (3rd generation)_16.2_simulator.png */; }; 6860CE272A01B2FF00B68EC5 /* golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6860CE242A01B2FF00B68EC5 /* golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png */; }; + 686382EC2AC1F9F300E27AAD /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 686382EB2AC1F9F300E27AAD /* ShareViewController.m */; }; + 686382EF2AC1F9F300E27AAD /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 686382ED2AC1F9F300E27AAD /* MainInterface.storyboard */; }; + 686382F32AC1F9F300E27AAD /* ScenariosShare.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 686382E82AC1F9F300E27AAD /* ScenariosShare.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 686383132AC202B700E27AAD /* AppExtensionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 686383122AC202B700E27AAD /* AppExtensionTests.m */; }; + 686383152AC2175100E27AAD /* ../../Flutter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* ../../Flutter.xcframework */; }; + 686383162AC2175100E27AAD /* ../../Flutter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* ../../Flutter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 68A5B63423EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */; }; 68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68D4017C2564859300ECD91A /* ContinuousTexture.m */; }; 68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png */; }; @@ -83,6 +89,27 @@ remoteGlobalIDString = 248D76C622E388370012F0C1; remoteInfo = Scenarios; }; + 686382F12AC1F9F300E27AAD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 248D76BF22E388370012F0C1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 686382E72AC1F9F300E27AAD; + remoteInfo = ScenariosShare; + }; + 6863830A2AC2024200E27AAD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 686383052AC2024200E27AAD /* FlutterAppExtensionTestHost.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 686382C12ABE172F00E27AAD; + remoteInfo = FlutterAppExtensionTestHost; + }; + 686383102AC2027100E27AAD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 686383052AC2024200E27AAD /* FlutterAppExtensionTestHost.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 686382C02ABE172F00E27AAD; + remoteInfo = FlutterAppExtensionTestHost; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -120,6 +147,28 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + 686382F42AC1F9F300E27AAD /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 686382F32AC1F9F300E27AAD /* ScenariosShare.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + 686383172AC2175100E27AAD /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 686383162AC2175100E27AAD /* ../../Flutter.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -185,6 +234,13 @@ 6860CE222A01B2FF00B68EC5 /* golden_two_platform_view_clip_rrect_iPhone SE (3rd generation)_16.2_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rrect_iPhone SE (3rd generation)_16.2_simulator.png"; sourceTree = ""; }; 6860CE232A01B2FF00B68EC5 /* golden_two_platform_view_clip_rect_iPhone SE (3rd generation)_16.2_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rect_iPhone SE (3rd generation)_16.2_simulator.png"; sourceTree = ""; }; 6860CE242A01B2FF00B68EC5 /* golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png"; sourceTree = ""; }; + 686382E82AC1F9F300E27AAD /* ScenariosShare.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ScenariosShare.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 686382EA2AC1F9F300E27AAD /* ShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareViewController.h; sourceTree = ""; }; + 686382EB2AC1F9F300E27AAD /* ShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareViewController.m; sourceTree = ""; }; + 686382EE2AC1F9F300E27AAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; + 686382F02AC1F9F300E27AAD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 686383052AC2024200E27AAD /* FlutterAppExtensionTestHost.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FlutterAppExtensionTestHost.xcodeproj; path = ../FlutterAppExtensionTestHost/FlutterAppExtensionTestHost.xcodeproj; sourceTree = ""; }; + 686383122AC202B700E27AAD /* AppExtensionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppExtensionTests.m; sourceTree = ""; }; 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformViewGestureRecognizerTests.m; sourceTree = ""; }; 68D4017B2564859300ECD91A /* ContinuousTexture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContinuousTexture.h; sourceTree = ""; }; 68D4017C2564859300ECD91A /* ContinuousTexture.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContinuousTexture.m; sourceTree = ""; }; @@ -219,15 +275,25 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 686382E52AC1F9F300E27AAD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 686383152AC2175100E27AAD /* ../../Flutter.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 248D76BE22E388370012F0C1 = { isa = PBXGroup; children = ( + 686383052AC2024200E27AAD /* FlutterAppExtensionTestHost.xcodeproj */, 248D76C922E388370012F0C1 /* Scenarios */, 248D76E222E388380012F0C1 /* ScenariosTests */, 248D76ED22E388380012F0C1 /* ScenariosUITests */, + 686382E92AC1F9F300E27AAD /* ScenariosShare */, 248D76C822E388370012F0C1 /* Products */, 248D76FC22E388900012F0C1 /* Frameworks */, ); @@ -239,6 +305,7 @@ 248D76C722E388370012F0C1 /* Scenarios.app */, 248D76DF22E388380012F0C1 /* ScenariosTests.xctest */, 248D76EA22E388380012F0C1 /* ScenariosUITests.xctest */, + 686382E82AC1F9F300E27AAD /* ScenariosShare.appex */, ); name = Products; sourceTree = ""; @@ -298,6 +365,7 @@ 246A6610252E693A00EAB0F3 /* RenderingSelectionTest.m */, 0DDEBC88258830B40065D0E8 /* SpawnEngineTest.m */, F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */, + 686383122AC202B700E27AAD /* AppExtensionTests.m */, ); path = ScenariosUITests; sourceTree = ""; @@ -311,6 +379,25 @@ name = Frameworks; sourceTree = ""; }; + 686382E92AC1F9F300E27AAD /* ScenariosShare */ = { + isa = PBXGroup; + children = ( + 686382EA2AC1F9F300E27AAD /* ShareViewController.h */, + 686382EB2AC1F9F300E27AAD /* ShareViewController.m */, + 686382ED2AC1F9F300E27AAD /* MainInterface.storyboard */, + 686382F02AC1F9F300E27AAD /* Info.plist */, + ); + path = ScenariosShare; + sourceTree = ""; + }; + 686383062AC2024200E27AAD /* Products */ = { + isa = PBXGroup; + children = ( + 6863830B2AC2024200E27AAD /* FlutterAppExtensionTestHost.app */, + ); + name = Products; + sourceTree = ""; + }; F7B464DC2759D02B00079189 /* Goldens */ = { isa = PBXGroup; children = ( @@ -355,10 +442,12 @@ 248D76C422E388370012F0C1 /* Frameworks */, 248D76C522E388370012F0C1 /* Resources */, 246B4E4422E3B5F700073EBF /* Embed Frameworks */, + 686382F42AC1F9F300E27AAD /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( + 686382F22AC1F9F300E27AAD /* PBXTargetDependency */, ); name = Scenarios; productName = Scenarios; @@ -396,6 +485,7 @@ buildRules = ( ); dependencies = ( + 686383112AC2027100E27AAD /* PBXTargetDependency */, 248D76EC22E388380012F0C1 /* PBXTargetDependency */, ); name = ScenariosUITests; @@ -403,6 +493,24 @@ productReference = 248D76EA22E388380012F0C1 /* ScenariosUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; + 686382E72AC1F9F300E27AAD /* ScenariosShare */ = { + isa = PBXNativeTarget; + buildConfigurationList = 686382F72AC1F9F300E27AAD /* Build configuration list for PBXNativeTarget "ScenariosShare" */; + buildPhases = ( + 686382E42AC1F9F300E27AAD /* Sources */, + 686382E52AC1F9F300E27AAD /* Frameworks */, + 686382E62AC1F9F300E27AAD /* Resources */, + 686383172AC2175100E27AAD /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ScenariosShare; + productName = ScenariosShare; + productReference = 686382E82AC1F9F300E27AAD /* ScenariosShare.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -426,6 +534,9 @@ LastSwiftMigration = 1030; TestTargetID = 248D76C622E388370012F0C1; }; + 686382E72AC1F9F300E27AAD = { + CreatedOnToolsVersion = 15.0; + }; }; }; buildConfigurationList = 248D76C222E388370012F0C1 /* Build configuration list for PBXProject "Scenarios" */; @@ -439,15 +550,32 @@ mainGroup = 248D76BE22E388370012F0C1; productRefGroup = 248D76C822E388370012F0C1 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 686383062AC2024200E27AAD /* Products */; + ProjectRef = 686383052AC2024200E27AAD /* FlutterAppExtensionTestHost.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 248D76C622E388370012F0C1 /* Scenarios */, 248D76DE22E388380012F0C1 /* ScenariosTests */, 248D76E922E388380012F0C1 /* ScenariosUITests */, + 686382E72AC1F9F300E27AAD /* ScenariosShare */, ); }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 6863830B2AC2024200E27AAD /* FlutterAppExtensionTestHost.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = FlutterAppExtensionTestHost.app; + remoteRef = 6863830A2AC2024200E27AAD /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 248D76C522E388370012F0C1 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -497,6 +625,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 686382E62AC1F9F300E27AAD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 686382EF2AC1F9F300E27AAD /* MainInterface.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -539,10 +675,19 @@ F26F15B8268B6B5600EC54D3 /* iPadGestureTests.m in Sources */, 246A6611252E693A00EAB0F3 /* RenderingSelectionTest.m in Sources */, 4F06F1B32473296E000AF246 /* LocalizationInitializationTest.m in Sources */, + 686383132AC202B700E27AAD /* AppExtensionTests.m in Sources */, 0DDEBC89258830B40065D0E8 /* SpawnEngineTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 686382E42AC1F9F300E27AAD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 686382EC2AC1F9F300E27AAD /* ShareViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -556,8 +701,29 @@ target = 248D76C622E388370012F0C1 /* Scenarios */; targetProxy = 248D76EB22E388380012F0C1 /* PBXContainerItemProxy */; }; + 686382F22AC1F9F300E27AAD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 686382E72AC1F9F300E27AAD /* ScenariosShare */; + targetProxy = 686382F12AC1F9F300E27AAD /* PBXContainerItemProxy */; + }; + 686383112AC2027100E27AAD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FlutterAppExtensionTestHost; + targetProxy = 686383102AC2027100E27AAD /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + 686382ED2AC1F9F300E27AAD /* MainInterface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 686382EE2AC1F9F300E27AAD /* Base */, + ); + name = MainInterface.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 248D76F122E388380012F0C1 /* Debug */ = { isa = XCBuildConfiguration; @@ -678,7 +844,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = S8QB4VV633; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -701,7 +867,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = S8QB4VV633; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -723,7 +889,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = S8QB4VV633; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -750,7 +916,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = S8QB4VV633; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -776,7 +942,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = S8QB4VV633; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -802,7 +968,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = S8QB4VV633; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -824,6 +990,70 @@ }; name = Release; }; + 686382F52AC1F9F300E27AAD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ScenariosShare/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = ScenariosShare; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 flutter. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.Scenarios.ScenariosShare; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 686382F62AC1F9F300E27AAD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ScenariosShare/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = ScenariosShare; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 flutter. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.Scenarios.ScenariosShare; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -863,6 +1093,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 686382F72AC1F9F300E27AAD /* Build configuration list for PBXNativeTarget "ScenariosShare" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 686382F52AC1F9F300E27AAD /* Debug */, + 686382F62AC1F9F300E27AAD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 248D76BF22E388370012F0C1 /* Project object */; diff --git a/testing/scenario_app/ios/Scenarios/ScenariosShare/Base.lproj/MainInterface.storyboard b/testing/scenario_app/ios/Scenarios/ScenariosShare/Base.lproj/MainInterface.storyboard new file mode 100644 index 0000000000000..589bdd9e70de9 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosShare/Base.lproj/MainInterface.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/scenario_app/ios/Scenarios/ScenariosShare/Info.plist b/testing/scenario_app/ios/Scenarios/ScenariosShare/Info.plist new file mode 100644 index 0000000000000..ad33037771e88 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosShare/Info.plist @@ -0,0 +1,18 @@ + + + + + NSExtension + + NSExtensionAttributes + + NSExtensionActivationRule + TRUEPREDICATE + + NSExtensionPrincipalClass + ShareViewController + NSExtensionPointIdentifier + com.apple.share-services + + + diff --git a/testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.h b/testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.h new file mode 100644 index 0000000000000..004a75bd6ad35 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.h @@ -0,0 +1,10 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import + +@interface ShareViewController : FlutterViewController + +@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.m b/testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.m new file mode 100644 index 0000000000000..cea875a76271a --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosShare/ShareViewController.m @@ -0,0 +1,31 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ShareViewController.h" + +@interface ShareViewController () + +@end + +@implementation ShareViewController + +- (instancetype)init { + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"FlutterControllerTest" project:nil]; + [engine run]; + self = [self initWithEngine:engine nibName:nil bundle:nil]; + self.view.accessibilityIdentifier = @"flutter_view"; + + [engine.binaryMessenger + setMessageHandlerOnChannel:@"waiting_for_status" + binaryMessageHandler:^(NSData* _Nullable message, FlutterBinaryReply _Nonnull reply) { + FlutterMethodChannel* channel = [FlutterMethodChannel + methodChannelWithName:@"driver" + binaryMessenger:engine.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; + [channel invokeMethod:@"set_scenario" arguments:@{@"name" : @"app_extension"}]; + }]; + return self; +} + +@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/AppExtensionTests.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/AppExtensionTests.m new file mode 100644 index 0000000000000..70d4e0a190a3b --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/AppExtensionTests.m @@ -0,0 +1,58 @@ +// Copyright 2020 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import "GoldenTestManager.h" + +@interface AppExtensionTests : XCTestCase +@property(nonatomic, strong) XCUIApplication* hostApplication; +@end + +@implementation AppExtensionTests + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + self.hostApplication = + [[XCUIApplication alloc] initWithBundleIdentifier:@"dev.flutter.FlutterAppExtensionTestHost"]; +} + +- (void)testAppExtensionLaunching { + [self.hostApplication launch]; + XCUIElement* button = self.hostApplication.buttons[@"Open Share"]; + if (![button waitForExistenceWithTimeout:10]) { + NSLog(@"%@", self.hostApplication.debugDescription); + XCTFail(@"Failed due to not able to find any button with %@ seconds", @(10)); + } + [button tap]; + BOOL launchedExtensionInFlutter = NO; + // Custom share extension button (like the one in this test) does not have a unique + // identity. They are all identified as `XCElementSnapshotPrivilegedValuePlaceholder`. + // Loop through all the `XCElementSnapshotPrivilegedValuePlaceholder` and find the Flutter one. + for (int i = 0; i < self.hostApplication.collectionViews.cells.count; i++) { + XCUIElement* shareSheetCell = + [self.hostApplication.collectionViews.cells elementBoundByIndex:i]; + if (![shareSheetCell.label isEqualToString:@"XCElementSnapshotPrivilegedValuePlaceholder"]) { + continue; + } + [shareSheetCell tap]; + + XCUIElement* flutterView = self.hostApplication.otherElements[@"flutter_view"]; + if ([flutterView waitForExistenceWithTimeout:10]) { + launchedExtensionInFlutter = YES; + break; + } + + // All the built-in share extensions have a Cancel button. + // Tap the Cancel button to close the built-in extension. + XCUIElement* cancel = self.hostApplication.buttons[@"Cancel"]; + if ([cancel waitForExistenceWithTimeout:10]) { + [cancel tap]; + } + } + // App extension successfully launched flutter view. + XCTAssertTrue(launchedExtensionInFlutter); +} + +@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m index a8d966379a5aa..29915a4cf57b2 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m @@ -53,6 +53,7 @@ - (instancetype)initWithLaunchArg:(NSString*)launchArg { @"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect", @"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect", @"--two-platform-view-clip-path" : @"two_platform_view_clip_path", + @"--app-extension" : @"app_extension", }; }); _identifier = launchArgsMap[launchArg]; diff --git a/testing/scenario_app/lib/src/darwin_app_extension_scenario.dart b/testing/scenario_app/lib/src/darwin_app_extension_scenario.dart new file mode 100644 index 0000000000000..354810a5d8d23 --- /dev/null +++ b/testing/scenario_app/lib/src/darwin_app_extension_scenario.dart @@ -0,0 +1,44 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ui'; + +import 'scenario.dart'; + +/// Shows a text that is shown in app extension. +class DarwinAppExtensionScenario extends Scenario { + /// Creates the DarwinAppExtensionScenario scenario. + DarwinAppExtensionScenario(super.view); + + // Semi-arbitrary. + final double _screenWidth = 700; + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder(); + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + + final ParagraphBuilder paragraphBuilder = + ParagraphBuilder(ParagraphStyle()) + ..pushStyle(TextStyle(fontSize: 80)) + ..addText('flutter Scenarios app extension.') + ..pop(); + final Paragraph paragraph = paragraphBuilder.build(); + + paragraph.layout(ParagraphConstraints(width: _screenWidth)); + + canvas.drawParagraph(paragraph, const Offset(50, 80)); + final Picture picture = recorder.endRecording(); + + builder.addPicture( + Offset.zero, + picture, + willChangeHint: true, + ); + final Scene scene = builder.build(); + view.render(scene); + scene.dispose(); + } +} diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index d9c586023bed2..8e3b15a985fa1 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -6,6 +6,7 @@ import 'dart:ui'; import 'animated_color_square.dart'; import 'bogus_font_text.dart'; +import 'darwin_app_extension_scenario.dart'; import 'get_bitmap_scenario.dart'; import 'initial_route_reply.dart'; import 'locale_initialization.dart'; @@ -66,6 +67,7 @@ Map _scenarios = { 'pointer_events': (FlutterView view) => TouchesScenario(view), 'display_texture': (FlutterView view) => DisplayTexture(view), 'get_bitmap': (FlutterView view) => GetBitmapScenario(view), + 'app_extension': (FlutterView view) => DarwinAppExtensionScenario(view), }; Map _currentScenarioParams = {}; diff --git a/testing/scenario_app/run_ios_tests.sh b/testing/scenario_app/run_ios_tests.sh index 3f730deaf3bba..772ea3b96294d 100755 --- a/testing/scenario_app/run_ios_tests.sh +++ b/testing/scenario_app/run_ios_tests.sh @@ -109,7 +109,9 @@ if set -o pipefail && xcodebuild -sdk iphonesimulator \ -skip-testing ScenariosUITests/TwoPlatformViewClipRRectTests/testPlatformView \ -skip-testing ScenariosUITests/TwoPlatformViewsWithOtherBackDropFilterTests/testPlatformView \ -skip-testing ScenariosUITests/UnobstructedPlatformViewTests/testMultiplePlatformViewsWithOverlays \ - INFOPLIST_FILE="Scenarios/Info_Impeller.plist"; then # Plist with FLTEnableImpeller=YES + # Plist with FLTEnableImpeller=YES, all projects in the workspace requires this file. + # For example, FlutterAppExtensionTestHost has a dummy file under the below directory. + INFOPLIST_FILE="Scenarios/Info_Impeller.plist"; then echo "test success." else echo "test failed." From df074be30e4d2c418baa52ba1b3946cf2ea5eef4 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 27 Sep 2023 16:13:36 -0700 Subject: [PATCH 2/3] fix --- .../framework/Source/FlutterNSBundleUtils.mm | 14 +++++++------- .../ios/framework/Source/FlutterDartProjectTest.mm | 13 +++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm index 54cf8feeb7d8b..ad7d266d5139b 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm @@ -8,8 +8,8 @@ FLUTTER_ASSERT_ARC -const NSString* kDefaultAssetPath = @"Frameworks/App.framework/flutter_assets"; -static NSString* GetFlutterAssetPathFromBundle(NSBundle* bundle); +NSString* kDefaultAssetPath = @"Frameworks/App.framework/flutter_assets"; +static NSString* GetFlutterAssetsPathFromBundle(NSBundle* bundle, NSString* relativeAssetsPath); NSBundle* FLTFrameworkBundleInternal(NSString* flutterFrameworkBundleID, NSURL* searchURL) { NSDirectoryEnumerator* frameworkEnumerator = [NSFileManager.defaultManager @@ -59,18 +59,18 @@ } NSString* FLTAssetsPathFromBundle(NSBundle* bundle) { - NSString* flutterAssetsPath = GetFlutterAssetPathFromBundle(bundle); + NSString* relativeAssetsPath = FLTAssetPath(bundle); + NSString* flutterAssetsPath = GetFlutterAssetsPathFromBundle(bundle, relativeAssetsPath); if (flutterAssetsPath.length == 0) { - flutterAssetsPath = GetFlutterAssetPathFromBundle(NSBundle.mainBundle); + flutterAssetsPath = GetFlutterAssetsPathFromBundle(NSBundle.mainBundle, relativeAssetsPath); } return flutterAssetsPath; } -static NSString* GetFlutterAssetPathFromBundle(NSBundle* bundle) { - NSString* flutterAssetsPath = FLTAssetPath(bundle); +static NSString* GetFlutterAssetsPathFromBundle(NSBundle* bundle, NSString* relativeAssetsPath) { // Use the raw path solution so that asset path can be returned from unloaded bundles. // See https://github.com/flutter/engine/pull/46073 - NSString* assetsPath = [bundle pathForResource:flutterAssetsPath ofType:nil]; + NSString* assetsPath = [bundle pathForResource:relativeAssetsPath ofType:nil]; if (assetsPath.length == 0) { // In app extension, using full relative path (kDefaultAssetPath) // returns nil when the app bundle is not loaded. Try to use diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm index 025bde32aeb2c..7de95d4771ae8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm @@ -97,6 +97,18 @@ - (void)testFLTAssetsURLFromBundle { NSString* path = FLTAssetsPathFromBundle(mockBundle); XCTAssertEqualObjects(path, @"path/to/foo/assets"); } + { + // Found asset path in info.plist, is not overriden by main bundle + id mockBundle = OCMClassMock([NSBundle class]); + id mockMainBundle = OCMPartialMock(NSBundle.mainBundle); + OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets"); + OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil); + NSString* resultAssetsPath = @"path/to/foo/assets"; + OCMStub([mockBundle pathForResource:@"foo/assets" ofType:nil]).andReturn(resultAssetsPath); + NSString* path = FLTAssetsPathFromBundle(mockBundle); + XCTAssertEqualObjects(path, @"path/to/foo/assets"); + [mockMainBundle stopMocking]; + } { // No asset path in info.plist, defaults to main bundle id mockBundle = OCMClassMock([NSBundle class]); @@ -108,6 +120,7 @@ - (void)testFLTAssetsURLFromBundle { .andReturn(resultAssetsPath); NSString* path = FLTAssetsPathFromBundle(mockBundle); XCTAssertEqualObjects(path, @"path/to/foo/assets"); + [mockMainBundle stopMocking]; } } From f10ba199e95e925b924e5e614a33619666607ec7 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 27 Sep 2023 16:28:14 -0700 Subject: [PATCH 3/3] revert the accidental const change --- .../darwin/common/framework/Source/FlutterNSBundleUtils.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm index ad7d266d5139b..c96b1a9af181e 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm @@ -8,7 +8,7 @@ FLUTTER_ASSERT_ARC -NSString* kDefaultAssetPath = @"Frameworks/App.framework/flutter_assets"; +const NSString* kDefaultAssetPath = @"Frameworks/App.framework/flutter_assets"; static NSString* GetFlutterAssetsPathFromBundle(NSBundle* bundle, NSString* relativeAssetsPath); NSBundle* FLTFrameworkBundleInternal(NSString* flutterFrameworkBundleID, NSURL* searchURL) {