Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0069f47

Browse files
committed
almost compiles
1 parent bb9cac2 commit 0069f47

9 files changed

+276
-4
lines changed

shell/platform/darwin/ios/framework/Headers/FlutterEngine.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,30 @@ FLUTTER_EXPORT
135135
*/
136136
- (instancetype)initWithName:(NSString*)labelPrefix
137137
project:(nullable FlutterDartProject*)project
138-
allowHeadlessExecution:(BOOL)allowHeadlessExecution NS_DESIGNATED_INITIALIZER;
138+
allowHeadlessExecution:(BOOL)allowHeadlessExecution;
139+
140+
/**
141+
* Initialize this FlutterEngine with a `FlutterDartProject`.
142+
*
143+
* If the FlutterDartProject is not specified, the FlutterEngine will attempt to locate
144+
* the project in a default location (the flutter_assets folder in the iOS application
145+
* bundle).
146+
*
147+
* A newly initialized engine will not run the `FlutterDartProject` until either
148+
* `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI:` is called.
149+
*
150+
* @param labelPrefix The label prefix used to identify threads for this instance. Should
151+
* be unique across FlutterEngine instances, and is used in instrumentation to label
152+
* the threads used by this FlutterEngine.
153+
* @param project The `FlutterDartProject` to run.
154+
* @param allowHeadlessExecution Whether or not to allow this instance to continue
155+
* running after passing a nil `FlutterViewController` to `-setViewController:`.
156+
* @param waitForRestorationData TODO
157+
*/
158+
- (instancetype)initWithName:(NSString*)labelPrefix
159+
project:(nullable FlutterDartProject*)project
160+
allowHeadlessExecution:(BOOL)allowHeadlessExecution
161+
restorationEnabled:(BOOL)restorationEnabled NS_DESIGNATED_INITIALIZER;
139162

140163
+ (instancetype)new NS_UNAVAILABLE;
141164

@@ -273,6 +296,16 @@ FLUTTER_EXPORT
273296
*/
274297
@property(nonatomic, readonly) FlutterMethodChannel* navigationChannel;
275298

299+
/**
300+
* The `FlutterMethodChannel` used for restoration related platform messages.
301+
*
302+
* Can be nil after `destroyContext` is called.
303+
*
304+
* @see [Navigation
305+
* Channel](https://docs.flutter.io/flutter/services/SystemChannels/restoration-constant.html)
306+
*/
307+
@property(nonatomic, readonly) FlutterMethodChannel* restorationChannel;
308+
276309
/**
277310
* The `FlutterMethodChannel` used for core platform messages, such as
278311
* information about the screen orientation.

shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,27 @@ FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDart
6464
*/
6565
- (instancetype)initWithName:(NSString*)labelPrefix
6666
project:(FlutterDartProject*)projectOrNil
67-
allowHeadlessExecution:(BOOL)allowHeadlessExecution NS_DESIGNATED_INITIALIZER;
67+
allowHeadlessExecution:(BOOL)allowHeadlessExecution;
68+
69+
/**
70+
* Iniitalize this FlutterHeadlessDartRunner with a `FlutterDartProject`.
71+
*
72+
* If the FlutterDartProject is not specified, the FlutterHeadlessDartRunner will attempt to locate
73+
* the project in a default location.
74+
*
75+
* A newly initialized engine will not run the `FlutterDartProject` until either
76+
* `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is called.
77+
*
78+
* @param labelPrefix The label prefix used to identify threads for this instance. Should
79+
* be unique across FlutterEngine instances
80+
* @param projectOrNil The `FlutterDartProject` to run.
81+
* @param allowHeadlessExecution Must be set to `YES`.
82+
* @param restorationEnabled TODO
83+
*/
84+
- (instancetype)initWithName:(NSString*)labelPrefix
85+
project:(FlutterDartProject*)projectOrNil
86+
allowHeadlessExecution:(BOOL)allowHeadlessExecution
87+
restorationEnabled:(BOOL)restorationEnabled NS_DESIGNATED_INITIALIZER;
6888

6989
/**
7090
* Not recommended for use - will initialize with a default label ("io.flutter.headless")

shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h"
66

7+
#include <iostream>
8+
79
#import "flutter/fml/logging.h"
810
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
911
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
@@ -24,6 +26,7 @@ @implementation FlutterAppDelegate {
2426
}
2527

2628
- (instancetype)init {
29+
NSLog(@"MIKE: HELLOO");
2730
if (self = [super init]) {
2831
_lifeCycleDelegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
2932
}
@@ -307,5 +310,33 @@ - (void)logCapabilityConfigurationWarningIfNeeded:(SEL)selector {
307310
}
308311
}
309312
}
313+
314+
#pragma mark - State Restoration
310315

316+
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
317+
[coder encodeInt64: self.lastAppModificationTime forKey:@"mod-date"];
318+
return YES;
319+
}
320+
321+
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
322+
int64_t stateDate = [coder decodeInt64ForKey:@"mod-date"];
323+
return self.lastAppModificationTime == stateDate;
324+
}
325+
326+
- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder {
327+
[coder encodeInt64: self.lastAppModificationTime forKey:@"mod-date"];
328+
return YES;
329+
}
330+
331+
- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder {
332+
int64_t stateDate = [coder decodeInt64ForKey:@"mod-date"];
333+
return self.lastAppModificationTime == stateDate;
334+
}
335+
336+
- (int64_t)lastAppModificationTime {
337+
NSDate *fileDate;
338+
[[[NSBundle mainBundle] executableURL] getResourceValue:&fileDate forKey:NSURLContentModificationDateKey error:nil];
339+
return [fileDate timeIntervalSince1970];
340+
}
341+
311342
@end

shell/platform/darwin/ios/framework/Source/FlutterEngine.mm

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ @implementation FlutterEngine {
7171
// Channels
7272
fml::scoped_nsobject<FlutterPlatformPlugin> _platformPlugin;
7373
fml::scoped_nsobject<FlutterTextInputPlugin> _textInputPlugin;
74+
fml::scoped_nsobject<FlutterRestorationPlugin> _restorationPlugin;
7475
fml::scoped_nsobject<FlutterMethodChannel> _localizationChannel;
7576
fml::scoped_nsobject<FlutterMethodChannel> _navigationChannel;
77+
fml::scoped_nsobject<FlutterMethodChannel> _restorationChannel;
7678
fml::scoped_nsobject<FlutterMethodChannel> _platformChannel;
7779
fml::scoped_nsobject<FlutterMethodChannel> _platformViewsChannel;
7880
fml::scoped_nsobject<FlutterMethodChannel> _textInputChannel;
@@ -84,6 +86,7 @@ @implementation FlutterEngine {
8486
int64_t _nextTextureId;
8587

8688
BOOL _allowHeadlessExecution;
89+
BOOL _restorationEnabled;
8790
FlutterBinaryMessengerRelay* _binaryMessenger;
8891
std::unique_ptr<flutter::ConnectionCollection> _connections;
8992
}
@@ -103,10 +106,18 @@ - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*
103106
- (instancetype)initWithName:(NSString*)labelPrefix
104107
project:(FlutterDartProject*)project
105108
allowHeadlessExecution:(BOOL)allowHeadlessExecution {
109+
return [self initWithName:labelPrefix project:project allowHeadlessExecution:allowHeadlessExecution restorationEnabled:NO];
110+
}
111+
112+
- (instancetype)initWithName:(NSString*)labelPrefix
113+
project:(FlutterDartProject*)project
114+
allowHeadlessExecution:(BOOL)allowHeadlessExecution
115+
restorationEnabled:(BOOL)restorationEnabled {
106116
self = [super init];
107117
NSAssert(self, @"Super init cannot be nil");
108118
NSAssert(labelPrefix, @"labelPrefix is required");
109119

120+
_restorationEnabled = restorationEnabled;
110121
_allowHeadlessExecution = allowHeadlessExecution;
111122
_labelPrefix = [labelPrefix copy];
112123

@@ -331,12 +342,18 @@ - (FlutterPlatformPlugin*)platformPlugin {
331342
- (FlutterTextInputPlugin*)textInputPlugin {
332343
return _textInputPlugin.get();
333344
}
345+
- (FlutterRestorationPlugin*)restorationPlugin {
346+
return _restorationPlugin.get();
347+
}
334348
- (FlutterMethodChannel*)localizationChannel {
335349
return _localizationChannel.get();
336350
}
337351
- (FlutterMethodChannel*)navigationChannel {
338352
return _navigationChannel.get();
339353
}
354+
- (FlutterMethodChannel*)restorationChannel {
355+
return _restorationChannel.get();
356+
}
340357
- (FlutterMethodChannel*)platformChannel {
341358
return _platformChannel.get();
342359
}
@@ -363,6 +380,7 @@ - (NSURL*)observatoryUrl {
363380
- (void)resetChannels {
364381
_localizationChannel.reset();
365382
_navigationChannel.reset();
383+
_restorationChannel.reset();
366384
_platformChannel.reset();
367385
_platformViewsChannel.reset();
368386
_textInputChannel.reset();
@@ -413,6 +431,11 @@ - (void)setupChannels {
413431
_initialRoute = nil;
414432
}
415433

434+
_restorationChannel.reset([[FlutterMethodChannel alloc]
435+
initWithName:@"flutter/restoration"
436+
binaryMessenger:self.binaryMessenger
437+
codec:[FlutterStandardMethodCodec sharedInstance]]);
438+
416439
_platformChannel.reset([[FlutterMethodChannel alloc]
417440
initWithName:@"flutter/platform"
418441
binaryMessenger:self.binaryMessenger
@@ -452,6 +475,8 @@ - (void)setupChannels {
452475
_textInputPlugin.get().textInputDelegate = self;
453476

454477
_platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithEngine:[self getWeakPtr]]);
478+
479+
_restorationPlugin.reset([[FlutterRestorationPlugin alloc] initWithChannel:_restorationChannel.get() restorationEnabled:_restorationEnabled]);
455480
}
456481

457482
- (void)maybeSetupPlatformViewChannels {

shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
1919
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h"
2020
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
21+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h"
2122
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h"
2223
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h"
2324
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
@@ -42,6 +43,7 @@ extern NSString* const FlutterEngineWillDealloc;
4243
- (FlutterPlatformPlugin*)platformPlugin;
4344
- (std::shared_ptr<flutter::FlutterPlatformViewsController>&)platformViewsController;
4445
- (FlutterTextInputPlugin*)textInputPlugin;
46+
- (FlutterRestorationPlugin*)restorationPlugin;
4547
- (void)launchEngine:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil;
4648
- (BOOL)createShell:(NSString*)entrypoint
4749
libraryURI:(NSString*)libraryOrNil

shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,24 @@ - (instancetype)initWithName:(NSString*)labelPrefix
3535
allowHeadlessExecution:(BOOL)allowHeadlessExecution {
3636
NSAssert(allowHeadlessExecution == YES,
3737
@"Cannot initialize a FlutterHeadlessDartRunner without headless execution.");
38+
return [self initWithName:labelPrefix
39+
project:projectOrNil
40+
allowHeadlessExecution:allowHeadlessExecution
41+
restorationEnabled:NO];
42+
}
43+
44+
- (instancetype)initWithName:(NSString*)labelPrefix
45+
project:(FlutterDartProject*)projectOrNil
46+
allowHeadlessExecution:(BOOL)allowHeadlessExecution
47+
restorationEnabled:(BOOL)restorationEnabled{
48+
NSAssert(allowHeadlessExecution == YES,
49+
@"Cannot initialize a FlutterHeadlessDartRunner without headless execution.");
3850
return [super initWithName:labelPrefix
3951
project:projectOrNil
40-
allowHeadlessExecution:allowHeadlessExecution];
52+
allowHeadlessExecution:allowHeadlessExecution
53+
restorationEnabled:restorationEnabled];
4154
}
55+
4256
- (instancetype)init {
4357
return [self initWithName:@"io.flutter.headless" project:nil];
4458
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERRESTORATIONPLUGIN_H_
6+
#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERRESTORATIONPLUGIN_H_
7+
8+
#import <UIKit/UIKit.h>
9+
10+
#include "flutter/fml/memory/weak_ptr.h"
11+
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
12+
13+
@interface FlutterRestorationPlugin : NSObject
14+
15+
- (instancetype)init NS_UNAVAILABLE;
16+
+ (instancetype)new NS_UNAVAILABLE;
17+
- (instancetype)initWithChannel:(fml::WeakPtr<FlutterMethodChannel>)channel restorationEnabled:(BOOL)waitForData NS_DESIGNATED_INITIALIZER;
18+
19+
- (NSData*)restorationData;
20+
- (void)restorationData:(NSData *)data;
21+
- (void)restorationComplete;
22+
@end
23+
#endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERRESTORATIONPLUGIN_H_
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h"
6+
7+
#import <Foundation/Foundation.h>
8+
#import <UIKit/UIKit.h>
9+
10+
#include "flutter/fml/logging.h"
11+
12+
13+
@implementation FlutterRestorationPlugin {
14+
BOOL _waitForData;
15+
BOOL _restorationEnabled;
16+
FlutterResult _pendingRequest;
17+
NSData* _restorationData;
18+
}
19+
20+
- (instancetype)init {
21+
@throw([NSException exceptionWithName:@"FlutterRestorationPlugin must initWithEngine"
22+
reason:nil
23+
userInfo:nil]);
24+
/Users/goderbauer/dev/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h
25+
}
26+
27+
- (instancetype)initWithChannel:(fml::WeakPtr<FlutterMethodChannel>)channel restorationEnabled:(BOOL)restorationEnabled {
28+
FML_DCHECK(channel) << "channel must be set";
29+
self = [super init];
30+
if (self) {
31+
[channel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
32+
[self handleMethodCall:call result:result];
33+
}];
34+
_restorationEnabled = restorationEnabled;
35+
_waitForData = restorationEnabled;
36+
}
37+
return self;
38+
}
39+
40+
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
41+
if ([[call method] isEqualToString:@"put"]) {
42+
FlutterStandardTypedData* data = [call arguments];
43+
NSData* newData = [[data data] retain];
44+
if (_restorationData != nil) {
45+
[_restorationData release];
46+
}
47+
_restorationData = newData;
48+
result(nil);
49+
} else if ([[call method] isEqualToString:@"get"]) {
50+
if (!_restorationEnabled || !_waitForData) {
51+
result( [self dataForFramework] );
52+
return;
53+
}
54+
_pendingRequest = [result retain];
55+
} else {
56+
result(FlutterMethodNotImplemented);
57+
}
58+
}
59+
60+
_ (NSData*)restorationData {
61+
return _restorationData;
62+
}
63+
64+
- (void)restorationData:(NSData*)data {
65+
NSData* newData = [data retain];
66+
if (_restorationData != nil) {
67+
[_restorationData release];
68+
}
69+
_restorationData = newData;
70+
if (_pendingRequest != nil) {
71+
_pendingRequest( [self dataForFramework] );
72+
[_pendingRequest release];
73+
_pendingRequest = nil;
74+
_waitForData = NO;
75+
}
76+
}
77+
78+
- (void)restorationComplete {
79+
_waitForData = NO;
80+
if (_pendingRequest != nil) {
81+
NSAssert(_restorationEnabled, @"No request can be pending when restoration is disabled.");
82+
_pendingRequest( [self dataForFramework] );
83+
[_pendingRequest release];
84+
_pendingRequest = nil;
85+
}
86+
}
87+
88+
- (NSDictionary*)dataForFramework {
89+
if (!_restorationEnabled) {
90+
return @{ @"enabled": @NO };
91+
}
92+
if (_restorationData == nil) {
93+
return @{ @"enabled": @YES };
94+
}
95+
return @{@"enabled": @YES, @"data": [FlutterStandardTypedData typedDataWithBytes:_restorationData]};
96+
}
97+
98+
@end

0 commit comments

Comments
 (0)