From 8bb7468d461e2c0bd14577ece5e305c0636ef2ee Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Wed, 16 Feb 2022 21:12:53 +0800 Subject: [PATCH 1/2] [iOS] Fixes state restoration not work --- .../Source/FlutterRestorationPluginTest.mm | 29 +++++++++++++++++++ .../framework/Source/FlutterViewController.mm | 11 +++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm index ce1e6e55be71d..ec9901385b747 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm @@ -9,6 +9,8 @@ #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" FLUTTER_ASSERT_ARC @@ -36,6 +38,33 @@ - (void)tearDown { #pragma mark - Tests +- (void)testRestoratonViewControllerEncodeAndDecode { + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" + project:nil + allowHeadlessExecution:YES + restorationEnabled:YES]; + [engine run]; + FlutterViewController* flutterViewController = + [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; + FlutterRestorationPlugin* restorationPlugin = flutterViewController.restorationPlugin; + + NSData* data = [@"testrestortiondata" dataUsingEncoding:NSUTF8StringEncoding]; + [restorationPlugin setRestorationData:data]; + + NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [flutterViewController encodeRestorableStateWithCoder:archiver]; + + XCTAssertEqual([restorationPlugin restorationData], archiver.encodedData); + + [restorationPlugin setRestorationData:nil]; + + NSKeyedUnarchiver* unarchiver = + [[NSKeyedUnarchiver alloc] initForReadingWithData:archiver.encodedData]; + [flutterViewController decodeRestorableStateWithCoder:unarchiver]; + + XCTAssertEqual([restorationPlugin restorationData], archiver.encodedData); +} + - (void)testRestorationEnabledWaitsForData { FlutterRestorationPlugin* restorationPlugin = [[FlutterRestorationPlugin alloc] initWithChannel:restorationChannel restorationEnabled:YES]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index b497d0917580a..304de7a21a54e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -32,6 +32,8 @@ static constexpr int kMicrosecondsPerSecond = 1000 * 1000; static constexpr CGFloat kScrollViewContentSize = 2.0; +static NSString* const kFlutterRestorationStateAppData = @"FlutterRestorationStateAppData"; + NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemanticsUpdate"; NSNotificationName const FlutterViewControllerWillDealloc = @"FlutterViewControllerWillDealloc"; NSNotificationName const FlutterViewControllerHideHomeIndicator = @@ -1811,12 +1813,17 @@ - (void)scrollEvent:(UIPanGestureRecognizer*)recognizer API_AVAILABLE(ios(13.4)) - (void)encodeRestorableStateWithCoder:(NSCoder*)coder { NSData* restorationData = [[_engine.get() restorationPlugin] restorationData]; - [coder encodeDataObject:restorationData]; + [coder encodeBytes:(const unsigned char*)restorationData.bytes + length:restorationData.length + forKey:kFlutterRestorationStateAppData]; [super encodeRestorableStateWithCoder:coder]; } - (void)decodeRestorableStateWithCoder:(NSCoder*)coder { - NSData* restorationData = [coder decodeDataObject]; + NSUInteger restorationDataLength; + const unsigned char* restorationBytes = [coder decodeBytesForKey:kFlutterRestorationStateAppData + returnedLength:&restorationDataLength]; + NSData* restorationData = [NSData dataWithBytes:restorationBytes length:restorationDataLength]; [[_engine.get() restorationPlugin] setRestorationData:restorationData]; } From b9e29d57ada72978b1725b7b1b6732454fe7be24 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Thu, 17 Feb 2022 12:52:29 +0800 Subject: [PATCH 2/2] Fix test failure --- .../ios/framework/Source/FlutterRestorationPluginTest.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm index ec9901385b747..36de96d451a8d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm @@ -54,15 +54,14 @@ - (void)testRestoratonViewControllerEncodeAndDecode { NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [flutterViewController encodeRestorableStateWithCoder:archiver]; - XCTAssertEqual([restorationPlugin restorationData], archiver.encodedData); - [restorationPlugin setRestorationData:nil]; NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:archiver.encodedData]; [flutterViewController decodeRestorableStateWithCoder:unarchiver]; - XCTAssertEqual([restorationPlugin restorationData], archiver.encodedData); + XCTAssert([[restorationPlugin restorationData] isEqualToData:data], + "Restoration state data must be equal"); } - (void)testRestorationEnabledWaitsForData {