diff --git a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm index ce1e6e55be71d..36de96d451a8d 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,32 @@ - (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]; + + [restorationPlugin setRestorationData:nil]; + + NSKeyedUnarchiver* unarchiver = + [[NSKeyedUnarchiver alloc] initForReadingWithData:archiver.encodedData]; + [flutterViewController decodeRestorableStateWithCoder:unarchiver]; + + XCTAssert([[restorationPlugin restorationData] isEqualToData:data], + "Restoration state data must be equal"); +} + - (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]; }