提交 8ec0463d 编写于 作者: C Chinmay Garde

iOS: Cleanup and move guts of the embedder into FlutterViewController.

* Remove engine code from SkySurface into the controller.
* The public API exposed by Flutter.framework for third-party embedders is present ios/public.
* Public view controller API uses idiomatic Objective-C and is subclassable by consumers.
* Paves way for moving the embedder into a framework.
上级 0d311fd3
......@@ -235,15 +235,17 @@ if (is_android) {
source_set("ios_scaffolding") {
sources = [
"platform/ios/flutter_app_delegate.h",
"platform/ios/flutter_app_delegate.mm",
"platform/ios/flutter_dynamic_service_loader.h",
"platform/ios/flutter_dynamic_service_loader.mm",
"platform/ios/flutter_touch_mapper.h",
"platform/ios/flutter_touch_mapper.mm",
"platform/ios/flutter_view.h",
"platform/ios/flutter_view.mm",
"platform/ios/flutter_view_controller.mm",
"platform/ios/main_ios.mm",
"platform/ios/sky_app_delegate.h",
"platform/ios/sky_app_delegate.mm",
"platform/ios/sky_dynamic_service_loader.h",
"platform/ios/sky_dynamic_service_loader.mm",
"platform/ios/sky_surface.h",
"platform/ios/sky_surface.mm",
"platform/ios/sky_view_controller.h",
"platform/ios/sky_view_controller.mm",
"platform/ios/public/FlutterViewController.h",
]
set_sources_assignment_filter([])
......@@ -272,6 +274,22 @@ if (is_android) {
]
}
shared_library("flutter_framework") {
output_name = "libFlutter"
deps = [
":ios_scaffolding"
]
libs = [
"UIKit.framework",
"OpenGLES.framework",
"AVFoundation.framework",
"AudioToolbox.framework",
"QuartzCore.framework",
]
}
sky_precompilation_sdk("shell") {
sdk_name = "Flutter"
}
......
......@@ -4,7 +4,7 @@
#import <UIKit/UIKit.h>
@interface SkyAppDelegate : UIResponder<UIApplicationDelegate>
@interface FlutterAppDelegate : UIResponder<UIApplicationDelegate>
@property(strong, nonatomic) UIWindow* window;
......
......@@ -2,19 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "sky_app_delegate.h"
#import "sky_view_controller.h"
#import "base/trace_event/trace_event.h"
#include "sky/shell/platform/ios/flutter_app_delegate.h"
#include "sky/shell/platform/ios/public/FlutterViewController.h"
#include "base/trace_event/trace_event.h"
@implementation SkyAppDelegate
@implementation FlutterAppDelegate
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
TRACE_EVENT0("flutter", "applicationDidFinishLaunchingWithOptions");
NSBundle* dartBundle = [NSBundle
bundleWithIdentifier:@"io.flutter.application.FlutterApplication"];
CGRect frame = [UIScreen mainScreen].bounds;
UIWindow* window = [[UIWindow alloc] initWithFrame:frame];
SkyViewController* viewController = [[SkyViewController alloc] init];
FlutterViewController* viewController =
[[FlutterViewController alloc] initWithDartBundle:dartBundle];
window.rootViewController = viewController;
[viewController release];
self.window = window;
......
......@@ -8,7 +8,7 @@
#import <Foundation/Foundation.h>
#include "sky/shell/platform/mac/platform_service_provider.h"
@interface SkyDynamicServiceLoader : NSObject
@interface FlutterDynamicServiceLoader : NSObject
- (void)resolveService:(NSString*)name
handle:(mojo::ScopedMessagePipeHandle)handle;
......
......@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/shell/platform/ios/sky_dynamic_service_loader.h"
#include "sky/shell/platform/ios/flutter_dynamic_service_loader.h"
#include "sky/services/dynamic/dynamic_service_embedder.h"
#include "sky/services/dynamic/dynamic_service_definition.h"
#include <Foundation/Foundation.h>
#include <dlfcn.h>
@interface SkyServiceDefinition : NSObject
@interface FlutterServiceDefinition : NSObject
@property(nonatomic, readonly) NSString* serviceName;
......@@ -22,7 +22,7 @@
@end
@implementation SkyServiceDefinition {
@implementation FlutterServiceDefinition {
std::unique_ptr<sky::services::DynamicServiceDefinition> _definition;
BOOL _initializationAttempted;
}
......@@ -49,7 +49,7 @@
}
mojo::String dylib_path(
[[NSBundle bundleForClass:[SkyDynamicServiceLoader class]]
[[NSBundle bundleForClass:[FlutterDynamicServiceLoader class]]
pathForResource:_containerFramework
ofType:@"dylib"
inDirectory:@"Frameworks"]
......@@ -91,7 +91,7 @@
@end
@implementation SkyDynamicServiceLoader {
@implementation FlutterDynamicServiceLoader {
NSMutableDictionary* _services;
}
......@@ -161,9 +161,9 @@
NSString* serviceName = service[@"name"];
SkyServiceDefinition* definition =
[[SkyServiceDefinition alloc] initWithName:serviceName
framework:service[@"framework"]];
FlutterServiceDefinition* definition =
[[FlutterServiceDefinition alloc] initWithName:serviceName
framework:service[@"framework"]];
if (definition != nil) {
_services[serviceName] = definition;
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_SHELL_PLATFORM_IOS_TOUCH_MAPPER_H_
#define SKY_SHELL_PLATFORM_IOS_TOUCH_MAPPER_H_
#include <UIKit/UIKit.h>
#include "base/macros.h"
#include <map>
namespace sky {
namespace shell {
/// UITouch pointers cannot be used as touch ids (even though they remain
/// constant throughout the multitouch sequence) because internal components
/// assume that ids are < 16. This class maps touch pointers to ids
class TouchMapper {
public:
TouchMapper();
~TouchMapper();
int registerTouch(UITouch* touch);
int unregisterTouch(UITouch* touch);
int identifierOf(UITouch* touch) const;
private:
using BitSet = long long int;
BitSet free_spots_;
std::map<UITouch*, int> touch_map_;
DISALLOW_COPY_AND_ASSIGN(TouchMapper);
};
} // namespace shell
} // namespace sky
#endif // SKY_SHELL_PLATFORM_IOS_TOUCH_MAPPER_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/shell/platform/ios/flutter_touch_mapper.h"
namespace sky {
namespace shell {
TouchMapper::TouchMapper() : free_spots_(~0) {}
TouchMapper::~TouchMapper() = default;
int TouchMapper::registerTouch(UITouch* touch) {
int freeSpot = ffsll(free_spots_);
touch_map_[touch] = freeSpot;
free_spots_ &= ~(1 << (freeSpot - 1));
return freeSpot;
}
int TouchMapper::unregisterTouch(UITouch* touch) {
auto index = touch_map_[touch];
free_spots_ |= 1 << (index - 1);
touch_map_.erase(touch);
return index;
}
int TouchMapper::identifierOf(UITouch* touch) const {
return touch_map_.at(touch);
}
} // namespace shell
} // namespace sky
// Copyright 2015 The Chromium Authors. All rights reserved.
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <UIKit/UIKit.h>
#ifndef FLUTTER_FLUTTERVIEW_H_
#define FLUTTER_FLUTTERVIEW_H_
@interface SkyViewController : UIViewController
#include <UIKit/UIKit.h>
@interface FlutterView : UIView
@end
#endif // FLUTTER_FLUTTERVIEW_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/shell/platform/ios/flutter_view.h"
@interface FlutterView ()<UIInputViewAudioFeedback>
@end
@implementation FlutterView
- (void)layoutSubviews {
CGFloat screenScale = [UIScreen mainScreen].scale;
CAEAGLLayer* layer = reinterpret_cast<CAEAGLLayer*>(self.layer);
layer.allowsGroupOpacity = YES;
layer.opaque = YES;
layer.contentsScale = screenScale;
layer.rasterizationScale = screenScale;
[super layoutSubviews];
}
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (BOOL)enableInputClicksWhenVisible {
return YES;
}
@end
......@@ -4,12 +4,12 @@
#import <UIKit/UIKit.h>
#include "sky/shell/platform/ios/sky_app_delegate.h"
#include "sky/shell/platform/ios/flutter_app_delegate.h"
#include "sky/shell/platform/mac/platform_mac.h"
int main(int argc, const char* argv[]) {
return sky::shell::PlatformMacMain(argc, argv, ^() {
return UIApplicationMain(argc, (char**)argv, nil,
NSStringFromClass([SkyAppDelegate class]));
NSStringFromClass([FlutterAppDelegate class]));
});
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERVIEWCONTROLLER_H_
#define FLUTTER_FLUTTERVIEWCONTROLLER_H_
#import <UIKit/UIKit.h>
@interface FlutterViewController : UIViewController
/**
* Initialize the view controller using the specified framework bundle
* containing the precompiled Dart code.
*
* @param dartBundle the framework bundle containing the precompiled Dart code.
*
* @return the initialized view controller.
*/
- (instancetype)initWithDartBundle:(NSBundle*)dartBundle;
/**
* Initialze the view controller using the specified framework bundle
* containing the precompiled dart code.
*
* @param dartBundleOrNil the framework bundle containing the precompiled Dart
* code.
* @param nibNameOrNil the nib name.
* @param nibBundleOrNil the bundle containing the nib.
*
* @return the initialized view controller.
*
* @discussion this is the designated initializer for this class. Subclasses
* must call this method during initialzation.
*/
- (instancetype)initWithDartBundle:(NSBundle*)dartBundleOrNil
nibName:(NSString*)nibNameOrNil
bundle:(NSBundle*)nibBundleOrNil
NS_DESIGNATED_INITIALIZER;
@end
#endif // FLUTTER_FLUTTERVIEWCONTROLLER_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <UIKit/UIKit.h>
#import "sky/shell/shell_view.h"
@interface SkySurface : UIView
- (instancetype)initWithShellView:(sky::shell::ShellView*)shellView;
- (void)visibilityDidChange:(BOOL)visible;
@end
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "sky_view_controller.h"
#import "sky_surface.h"
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#include "sky/shell/shell.h"
#include "sky/shell/shell_view.h"
#include "sky/services/platform/ios/system_chrome_impl.h"
@implementation SkyViewController {
UIInterfaceOrientationMask _orientation_preferences;
}
- (instancetype)init {
self = [super init];
if (self) {
_orientation_preferences = UIInterfaceOrientationMaskAll;
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onOrientationPreferencesUpdated:)
name:@(flutter::platform::kOrientationUpdateNotificationName)
object:nil];
}
return self;
}
- (void)loadView {
auto shell_view = new sky::shell::ShellView(sky::shell::Shell::Shared());
SkySurface* surface = [[SkySurface alloc] initWithShellView:shell_view];
surface.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view = surface;
[surface release];
}
- (void)onOrientationPreferencesUpdated:(NSNotification*)notification {
// Notifications may not be on the iOS UI thread
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary* info = notification.userInfo;
NSNumber* update =
info[@(flutter::platform::kOrientationUpdateNotificationKey)];
if (update == nil) {
return;
}
NSUInteger new_preferences = update.unsignedIntegerValue;
if (new_preferences != _orientation_preferences) {
_orientation_preferences = new_preferences;
[UIViewController attemptRotationToDeviceOrientation];
}
});
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return _orientation_preferences;
}
- (SkySurface*)surface {
DCHECK([self isViewLoaded]);
return reinterpret_cast<SkySurface*>(self.view);
}
- (void)viewDidAppear:(BOOL)animated {
[self.surface visibilityDidChange:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[self.surface visibilityDidChange:NO];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册