State Restoration for iOS#23495
Conversation
3c945f4 to
9c9931a
Compare
shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h
Outdated
Show resolved
Hide resolved
cbracken
left a comment
There was a problem hiding this comment.
A few initial comments. Overall looks good. @gaaclarke for the OCMock test, which I'm less familiar with.
| #pragma mark - State Restoration | ||
|
|
||
| - (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder { | ||
| [coder encodeInt64:self.lastAppModificationTime forKey:@"mod-date"]; |
There was a problem hiding this comment.
Optional: not used much but consider yanking this to a const. Sadly, can't use constexpr since it's an NSString.
There was a problem hiding this comment.
Well it is duplicated across the file so I think it's a good idea.
|
|
||
| #import <UIKit/UIKit.h> | ||
|
|
||
| #include "flutter/fml/memory/weak_ptr.h" |
There was a problem hiding this comment.
Doesn't look like you're using weak_ptr here (anymore).
| restorationEnabled:(BOOL)waitForData NS_DESIGNATED_INITIALIZER; | ||
|
|
||
| - (NSData*)restorationData; | ||
| - (void)restorationData:(NSData*)data; |
There was a problem hiding this comment.
This should be - (void)setRestorationData:(NSData*)data;. The getter is named correctly.
There was a problem hiding this comment.
Use a property as previously mentioned.
|
|
||
| - (NSData*)restorationData; | ||
| - (void)restorationData:(NSData*)data; | ||
| - (void)restorationComplete; |
There was a problem hiding this comment.
This should be setRestorationComplete or similar.
|
Added @gaaclarke for additional set of eyes, particularly around the OCMock test. |
gaaclarke
left a comment
There was a problem hiding this comment.
The tests look good to me. I just had some comments mostly around non-idiomatic code and the usage of properties.
| NSDate* fileDate; | ||
| [[[NSBundle mainBundle] executableURL] getResourceValue:&fileDate | ||
| forKey:NSURLContentModificationDateKey | ||
| error:nil]; |
There was a problem hiding this comment.
We should probably not gobble up this error. Its worth having an assert at least.
There was a problem hiding this comment.
I missed this comment earlier, will fix after meeting.
| - (instancetype)initWithChannel:(FlutterMethodChannel*)channel | ||
| restorationEnabled:(BOOL)waitForData NS_DESIGNATED_INITIALIZER; | ||
|
|
||
| - (NSData*)restorationData; |
There was a problem hiding this comment.
Idiomatic objc would use a property for this.
| restorationEnabled:(BOOL)waitForData NS_DESIGNATED_INITIALIZER; | ||
|
|
||
| - (NSData*)restorationData; | ||
| - (void)restorationData:(NSData*)data; |
There was a problem hiding this comment.
Use a property as previously mentioned.
| // found in the LICENSE file. | ||
|
|
||
| #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h" | ||
|
|
There was a problem hiding this comment.
Please assert ARC or non ARC at the top. There are macros in FlutterMacros.
There was a problem hiding this comment.
You mean FLUTTER_ASSERT_NOT_ARC or FLUTTER_ASSERT_ARC? In existing code I am only seeing those used in test code. Should they also appear in this non-test code?
There was a problem hiding this comment.
Added FLUTTER_ASSERT_NOT_ARC.
| BOOL _waitForData; | ||
| BOOL _restorationEnabled; | ||
| FlutterResult _pendingRequest; | ||
| NSData* _restorationData; |
There was a problem hiding this comment.
You need to add a dealloc to this class that deletes this.
| if ([[call method] isEqualToString:@"put"]) { | ||
| FlutterStandardTypedData* data = [call arguments]; | ||
| NSData* newData = [[data data] retain]; | ||
| if (_restorationData != nil) { |
There was a problem hiding this comment.
If you use properties you don't have to do this manual reference counting work.
| } | ||
| _restorationData = newData; | ||
| result(nil); | ||
| } else if ([[call method] isEqualToString:@"get"]) { |
There was a problem hiding this comment.
There is no call to result in this method.
There was a problem hiding this comment.
The call to result is delayed until we have something to send over, see _pendingResult.
| if (_restorationData != nil) { | ||
| [_restorationData release]; | ||
| } | ||
| _restorationData = newData; |
There was a problem hiding this comment.
Another place where properties will make your life easier.
| XCTAssertNil([restorationPlugin restorationData]); | ||
|
|
||
| __block id capturedResult; | ||
| methodCall = [FlutterMethodCall methodCallWithMethodName:@"get" arguments:nil]; |
There was a problem hiding this comment.
Optional: It would be nice if these method names where placed as consts in the header so we don't have to duplicate them. No one should have to refer to them by string literal.
goderbauer
left a comment
There was a problem hiding this comment.
Thanks for the review. Addressed all comments. PTAL.
| #pragma mark - State Restoration | ||
|
|
||
| - (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder { | ||
| [coder encodeInt64:self.lastAppModificationTime forKey:@"mod-date"]; |
|
|
||
| #import <UIKit/UIKit.h> | ||
|
|
||
| #include "flutter/fml/memory/weak_ptr.h" |
| restorationEnabled:(BOOL)waitForData NS_DESIGNATED_INITIALIZER; | ||
|
|
||
| - (NSData*)restorationData; | ||
| - (void)restorationData:(NSData*)data; |
|
|
||
| - (NSData*)restorationData; | ||
| - (void)restorationData:(NSData*)data; | ||
| - (void)restorationComplete; |
| // found in the LICENSE file. | ||
|
|
||
| #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h" | ||
|
|
There was a problem hiding this comment.
You mean FLUTTER_ASSERT_NOT_ARC or FLUTTER_ASSERT_ARC? In existing code I am only seeing those used in test code. Should they also appear in this non-test code?
| if ([[call method] isEqualToString:@"put"]) { | ||
| FlutterStandardTypedData* data = [call arguments]; | ||
| NSData* newData = [[data data] retain]; | ||
| if (_restorationData != nil) { |
| } | ||
| _restorationData = newData; | ||
| result(nil); | ||
| } else if ([[call method] isEqualToString:@"get"]) { |
There was a problem hiding this comment.
The call to result is delayed until we have something to send over, see _pendingResult.
| if (_restorationData != nil) { | ||
| [_restorationData release]; | ||
| } | ||
| _restorationData = newData; |
| BOOL _waitForData; | ||
| BOOL _restorationEnabled; | ||
| FlutterResult _pendingRequest; | ||
| NSData* _restorationData; |
| // found in the LICENSE file. | ||
|
|
||
| #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h" | ||
|
|
There was a problem hiding this comment.
Added FLUTTER_ASSERT_NOT_ARC.
gaaclarke
left a comment
There was a problem hiding this comment.
Thanks looking much better, lgtm modulo changing pendingRequest to a property as well.
PS declare the property in the .mm file with a class extension.
| static NSString* kUIBackgroundMode = @"UIBackgroundModes"; | ||
| static NSString* kRemoteNotificationCapabitiliy = @"remote-notification"; | ||
| static NSString* kBackgroundFetchCapatibility = @"fetch"; | ||
| static NSString* kRestorationStateAppModificationKey = @"mod-date"; |
There was a problem hiding this comment.
These should really be static NSString* const, sorry I know you didn't set the precedent =(
| - (instancetype)initWithChannel:(FlutterMethodChannel*)channel | ||
| restorationEnabled:(BOOL)waitForData NS_DESIGNATED_INITIALIZER; | ||
|
|
||
| @property(nonatomic, retain) NSData* restorationData; |
There was a problem hiding this comment.
s/retain/strong for forward compatibility with ARC
| } | ||
|
|
||
| - (void)dealloc { | ||
| if (_restorationData != nil) { |
There was a problem hiding this comment.
there is no need to do a nil check here, calls to nil are ignored in objective-c
| result([self dataForFramework]); | ||
| return; | ||
| } | ||
| _pendingRequest = [result retain]; |
There was a problem hiding this comment.
This is a leak, you should switch pendingRequest to a property and used self.pendingRequest = result; The property should be copy for blocks. In more cases your code will clean up once you turn this to a property, too. Sorry I didn't catch it earlier.
|
This pull request is not suitable for automatic merging in its current state.
|
e6fee6c to
7c2858f
Compare
|
This pull request is not suitable for automatic merging in its current state.
|
7c2858f to
c08e07f
Compare
Description
Wires up state restoration in the iOS embedder. The same has been done for Android in #18042.
Related Issues
Fixes flutter/flutter#62915.
Tests
I added the following tests:
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.Reviewer Checklist
Breaking Change
Did any tests fail when you ran them? Please read handling breaking changes.