diff --git a/packages/quick_actions/quick_actions/CHANGELOG.md b/packages/quick_actions/quick_actions/CHANGELOG.md index 3fd0c7e28256..f849d90bd902 100644 --- a/packages/quick_actions/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/quick_actions/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.0+1 + +* Correctly handle iOS Application lifecycle events on cold start of the App. + ## 0.6.0 * Migrate to federated architecture. diff --git a/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m index 30b87969f44a..a89d86c28c6f 100644 --- a/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m +++ b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m @@ -11,7 +11,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; + [super application:application didFinishLaunchingWithOptions:launchOptions]; + return NO; } - @end diff --git a/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m b/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m index 45791864d239..9991e344fe91 100644 --- a/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m +++ b/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m @@ -18,9 +18,45 @@ - (void)setUp { self.continueAfterFailure = NO; } -- (void)testQuickAction { +- (void)testQuickActionWithFreshStart { XCUIApplication *app = [[XCUIApplication alloc] init]; [app launch]; + [app terminate]; + + XCUIApplication *springboard = + [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; + XCUIElement *quickActionsAppIcon = springboard.icons[@"quick_actions_example"]; + if (![quickActionsAppIcon waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", springboard.debugDescription); + XCTFail(@"Failed due to not able to find the example app from springboard with %@ seconds", + @(kElementWaitingTime)); + } + + [quickActionsAppIcon pressForDuration:2]; + XCUIElement *actionTwo = springboard.buttons[@"Action two"]; + if (![actionTwo waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", springboard.debugDescription); + XCTFail(@"Failed due to not able to find the actionTwo button from springboard with %@ seconds", + @(kElementWaitingTime)); + } + + [actionTwo tap]; + + XCUIElement *actionTwoConfirmation = app.otherElements[@"action_two"]; + if (![actionTwoConfirmation waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", springboard.debugDescription); + XCTFail(@"Failed due to not able to find the actionTwoConfirmation in the app with %@ seconds", + @(kElementWaitingTime)); + } + XCTAssertTrue(actionTwoConfirmation.exists); + + [app terminate]; +} + +- (void)testQuickActionWhenAppIsInBackground { + XCUIApplication *app = [[XCUIApplication alloc] init]; + [app launch]; + XCUIElement *actionsReady = app.otherElements[@"actions ready"]; if (![actionsReady waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription); @@ -56,6 +92,8 @@ - (void)testQuickAction { @(kElementWaitingTime)); } XCTAssertTrue(actionOneConfirmation.exists); + + [app terminate]; } @end diff --git a/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m index 0025795744f9..3a966f86a824 100644 --- a/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m +++ b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m @@ -8,6 +8,7 @@ @interface FLTQuickActionsPlugin () @property(nonatomic, retain) FlutterMethodChannel *channel; +@property(nonatomic, retain) NSString *shortcutType; @end @implementation FLTQuickActionsPlugin @@ -50,12 +51,44 @@ - (BOOL)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler API_AVAILABLE(ios(9.0)) { - [self.channel invokeMethod:@"launch" arguments:shortcutItem.type]; + [self handleShortcut:shortcutItem.type]; return YES; } +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + if (@available(iOS 9.0, *)) { + UIApplicationShortcutItem *shortcutItem = + launchOptions[UIApplicationLaunchOptionsShortcutItemKey]; + if (shortcutItem) { + // Keep hold of the shortcut type and handle it in the + // `applicationDidBecomeActure:` method once the Dart MethodChannel + // is initialized. + self.shortcutType = shortcutItem.type; + + // Return NO to indicate we handled the quick action to ensure + // the `application:performActionFor:` method is not called (as + // per Apple's documentation: + // https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622935-application?language=objc). + return NO; + } + } + return YES; +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + if (self.shortcutType) { + [self handleShortcut:self.shortcutType]; + self.shortcutType = nil; + } +} + #pragma mark Private functions +- (void)handleShortcut:(NSString *)shortcut { + [self.channel invokeMethod:@"launch" arguments:shortcut]; +} + NS_INLINE void _setShortcutItems(NSArray *items) API_AVAILABLE(ios(9.0)) { NSMutableArray *newShortcuts = [[NSMutableArray alloc] init]; diff --git a/packages/quick_actions/quick_actions/pubspec.yaml b/packages/quick_actions/quick_actions/pubspec.yaml index f6622525d458..2bcdcf7ea8a5 100644 --- a/packages/quick_actions/quick_actions/pubspec.yaml +++ b/packages/quick_actions/quick_actions/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions -version: 0.6.0 +version: 0.6.0+1 flutter: plugin: