diff --git a/docs/README.md b/docs/README.md index c820bf0815a..0f521994141 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,12 +1,18 @@ # Hippy 简介 -Hippy 是 TDF 腾讯端框架(Tencent Device-oriented Framework)下的开源跨平台应用开发解决方案。 +版本:3.2.0 -Hippy 可以理解为一个精简版的浏览器,从底层做了大量工作,抹平了 iOS 和 Android 双端差异,提供了接近 Web 的开发体验,目前上层支持了 React 和 Vue 两套界面框架,前端开发人员可以通过它,将前端代码转换为终端的原生指令,进行原生终端 App 的开发。 +更新时间:2024-4-10 -同时,Hippy 从底层进行了大量优化,在启动速度、渲染性能、动画速度、内存占用、包体积等方面都提供了业内顶尖的性能表现。 +SDK介绍:Hippy 是 TDF 腾讯端框架(Tencent Device-oriented Framework)下的开源跨平台应用开发解决方案。Hippy 可以理解为一个精简版的浏览器,从底层做了大量工作,抹平了 iOS 和 Android 双端差异,提供了接近 Web 的开发体验,目前上层支持了 React 和 Vue 两套界面框架,前端开发人员可以通过它,将前端代码转换为终端的原生指令,进行原生终端 App 的开发。同时,Hippy 从底层进行了大量优化,在启动速度、渲染性能、动画速度、内存占用、包体积等方面都提供了业内顶尖的性能表现。 -在Hippy 3.0版本,我们对 Hippy 架构做了一次比较大的重构, 采用 Driver,Dom Manager,Renderer 分层解耦的设计理念,其设计目标就是希望框架在未来具有很好的可扩展性,以复用的 DOM 管理、排版布局为核心连接上层 Driver 和下层 Renderer,同时支持不同 Driver 和 Renderer 的接入和自由切换。 +更新日志:[Change log](https://github.com/Tencent/Hippy/releases) + +服务提供方:深圳市腾讯计算机系统有限公司 + +[接入指引](development/react-vue-integration-guidelines.md) + +[Hippy SDK隐私保护指引](development/privacy.md) ## 和 Web 接近的开发体验 @@ -53,7 +59,7 @@ Hippy 的包体积在业内也是非常具有竞争力的。 ## 可扩展的架构设计 -
+在Hippy 3.0版本,我们对 Hippy 架构做了一次比较大的重构, 采用 Driver,Dom Manager,Renderer 分层解耦的设计理念,其设计目标就是希望框架在未来具有很好的可扩展性,以复用的 DOM 管理、排版布局为核心连接上层 Driver 和下层 Renderer,同时支持不同 Driver 和 Renderer 的接入和自由切换。
3.0架构 ### 驱动层 diff --git a/framework/ios/base/bridge/HippyBridge.mm b/framework/ios/base/bridge/HippyBridge.mm index e20be172175..d1767140d6b 100644 --- a/framework/ios/base/bridge/HippyBridge.mm +++ b/framework/ios/base/bridge/HippyBridge.mm @@ -47,7 +47,7 @@ #import "HippyLog.h" #import "HippyOCToHippyValue.h" #import "HippyUtils.h" -#import "NSObject+Render.h" +#import "UIView+RenderManager.h" #import "TypeConverter.h" #import "VFSUriLoader.h" #import "HippyBase64DataHandler.h" diff --git a/framework/ios/module/dev/HippyRedBox.h b/framework/ios/module/dev/HippyRedBox.h index c209450e2bf..4fb59485cdf 100644 --- a/framework/ios/module/dev/HippyRedBox.h +++ b/framework/ios/module/dev/HippyRedBox.h @@ -53,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) HippyRedBox *redBox; /// The last current active bridge instance. -+ (nullable id)currentBridge; ++ (nullable instancetype)currentBridge; /// Record the last active bridge instance. /// - Parameter currentBridge: bridge instance, pass nil to reset. diff --git a/framework/ios/module/dev/HippyRedBox.mm b/framework/ios/module/dev/HippyRedBox.mm index 5f4d77b5695..05b4d84c603 100644 --- a/framework/ios/module/dev/HippyRedBox.mm +++ b/framework/ios/module/dev/HippyRedBox.mm @@ -30,7 +30,6 @@ #import "HippyJSStackFrame.h" #import "HippyLog.h" #import "HippyUtils.h" - #import "HippyDefines.h" #if HIPPY_DEBUG @@ -452,6 +451,9 @@ + (instancetype)currentBridge { + (void)setCurrentBridge:(nullable HippyBridge *)currentBridge { HippyCurrentBridgeInstance = [HippyWeakProxy weakProxyForObject:currentBridge]; + HippySetRedBoxFunction(^(NSString *errMsg, NSMutableArray *stacks) { + [([HippyBridge currentBridge]).redBox showErrorMessage:errMsg withStack:stacks]; + }); } diff --git a/hippy.podspec b/hippy.podspec index f617abfffa0..1d5142f4c90 100644 --- a/hippy.podspec +++ b/hippy.podspec @@ -47,8 +47,8 @@ Pod::Spec.new do |s| s.subspec 'Framework' do |framework| puts 'hippy subspec \'framework\' read begin' - framework.source_files = 'framework/ios/**/*.{h,m,c,mm,s,cpp,cc}' - framework.public_header_files = 'framework/ios/**/*.h' + framework.source_files = ['framework/ios/**/*.{h,m,c,mm,s,cpp,cc}', 'renderer/native/ios/**/*.{h,m,mm}'] + framework.public_header_files = ['framework/ios/**/*.h', 'renderer/native/ios/**/*.h'] if js_engine == "jsc" framework.exclude_files = ['framework/ios/base/enginewrapper/v8', 'framework/ios/utils/v8'] elsif js_engine == "v8" @@ -66,7 +66,7 @@ Pod::Spec.new do |s| framework.dependency 'hippy/JSDriver' framework.dependency 'hippy/Image' framework.dependency 'hippy/iOSVFS' - framework.dependency 'hippy/NativeRenderer' + framework.dependency 'hippy/DomUtils' puts 'hippy subspec \'framework\' read end' end @@ -234,18 +234,6 @@ Pod::Spec.new do |s| puts 'hippy subspec \'driver\' read end' end - s.subspec 'NativeRenderer' do |renderer| - puts 'hippy subspec \'nativerenderer\' read begin' - renderer.libraries = 'c++' - renderer.source_files = 'renderer/native/ios/**/*.{h,m,mm}' - renderer.public_header_files = 'renderer/native/ios/**/*.h' - renderer.dependency 'hippy/Base' - renderer.dependency 'hippy/DomUtils' - renderer.dependency 'hippy/Image' - renderer.dependency 'hippy/iOSVFS' - puts 'hippy subspec \'nativerenderer\' read end' - end - s.subspec 'Dom' do |dom| puts 'hippy subspec \'dom\' read begin' dom_source_files = Array['dom/include/**/*.h', 'dom/src/**/*.cc'] @@ -306,7 +294,7 @@ Pod::Spec.new do |s| s.subspec 'Taitank' do |taitank| puts 'hippy subspec \'Taitank\' read begin' taitank.source_files = ['dom/dom_project/_deps/taitank-src/src/*.{h,cc}'] - taitank.public_header_files = ['dom/include/dom/taitank_layout_node.h', 'dom/dom_project/_deps/taitank-src/src/*.h'] + taitank.public_header_files = ['dom/dom_project/_deps/taitank-src/src/*.h'] if use_frameworks header_search_paths = framework_header_path else diff --git a/modules/ios/base/HippyLog.h b/modules/ios/base/HippyLog.h index f2555c25504..ce422c182b1 100644 --- a/modules/ios/base/HippyLog.h +++ b/modules/ios/base/HippyLog.h @@ -121,4 +121,19 @@ HIPPY_EXTERN void HippyPerformBlockWithLogPrefix(void (^block)(void), NSString * HIPPY_EXTERN void HippyLogNativeInternal(HippyLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4, 5); + +#if HIPPY_DEBUG + +/* + * A handler that displays a red screen when an exception occurs + */ +typedef void (^HippyRedBoxFunction)(NSString *errMsg, NSMutableArray *stacks); + +/* + * Set a handler that displays a red screen when an exception occurs + */ +HIPPY_EXTERN void HippySetRedBoxFunction(HippyRedBoxFunction redBoxFunction); + +#endif /* HIPPY_DEBUG */ + #endif // defined(__OBJC__) diff --git a/modules/ios/base/HippyLog.mm b/modules/ios/base/HippyLog.mm index fc846788b09..16dbe0790f6 100644 --- a/modules/ios/base/HippyLog.mm +++ b/modules/ios/base/HippyLog.mm @@ -21,8 +21,6 @@ */ #import "HippyLog.h" -#import "HippyBridge.h" -#import "HippyRedBox.h" #include "footstone/logging.h" #pragma mark NativeLog Methods @@ -43,6 +41,13 @@ HippyLogLevel HPDefaultLogThreshold = HippyLogLevelInfo; #endif +#if HIPPY_DEBUG +static HippyRedBoxFunction hippyCurrentRedBoxFunction; +void HippySetRedBoxFunction(HippyRedBoxFunction redBoxFunction) { + hippyCurrentRedBoxFunction = redBoxFunction; +} +#endif /* HIPPY_DEBUG */ + static HippyLogFunction HPCurrentLogFunction; static HippyLogLevel HPCurrentLogThreshold = HPDefaultLogThreshold; @@ -200,9 +205,9 @@ void HippyLogNativeInternal(HippyLogLevel level, const char *fileName, int lineN } }]; dispatch_async(dispatch_get_main_queue(), ^{ - // red box is thread safe, but by deferring to main queue we avoid a startup - // race condition that causes the module to be accessed before it has loaded - [((HippyBridge *)[HippyBridge currentBridge]).redBox showErrorMessage:message withStack:stack]; + if (hippyCurrentRedBoxFunction) { + hippyCurrentRedBoxFunction(message, stack); + } }); } #endif diff --git a/modules/ios/base/NSObject+Render.mm b/modules/ios/base/NSObject+Render.mm deleted file mode 100644 index fd4291d02d5..00000000000 --- a/modules/ios/base/NSObject+Render.mm +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * iOS SDK - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "NSObject+Render.h" -#import "objc/runtime.h" - -#include "dom/render_manager.h" - -@interface RenderManagerWrapper : NSObject - -@property(nonatomic, assign) std::weak_ptr renderManager; - -@end - -@implementation RenderManagerWrapper - -@end - -@implementation UIView (HippyRenderManager) - -- (void)setRenderManager:(std::weak_ptr)renderManager { - RenderManagerWrapper *wrapper = [[RenderManagerWrapper alloc] init]; - wrapper.renderManager = renderManager; - objc_setAssociatedObject(self, @selector(renderManager), wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (std::weak_ptr)renderManager { - RenderManagerWrapper *wrapper = objc_getAssociatedObject(self, _cmd); - return wrapper.renderManager; -} - -@end diff --git a/renderer/native/ios/renderer/HippyUIManager.mm b/renderer/native/ios/renderer/HippyUIManager.mm index a24615f8cc3..18bc1e1930c 100644 --- a/renderer/native/ios/renderer/HippyUIManager.mm +++ b/renderer/native/ios/renderer/HippyUIManager.mm @@ -42,7 +42,7 @@ #import "UIView+DomEvent.h" #import "UIView+Hippy.h" #import "UIView+Render.h" -#import "NSObject+Render.h" +#import "UIView+RenderManager.h" #import "HippyBridgeModule.h" #import "HippyModulesSetup.h" #import "NativeRenderManager.h" @@ -1485,7 +1485,8 @@ - (void)layoutAndMountOnRootNode:(std::weak_ptr)rootNode { }]; } [self addUIBlock:^(HippyUIManager *uiManager, __unused NSDictionary *viewRegistry) { - for (id node in uiManager->_componentTransactionListeners) { + NSArray *transactionListeners = [uiManager->_componentTransactionListeners allObjects]; + for (id node in transactionListeners) { [node hippyBridgeDidFinishTransaction]; } }]; diff --git a/renderer/native/ios/renderer/UIView+Render.h b/renderer/native/ios/renderer/UIView+Render.h index 5b5fb2549ed..3c8972b98ca 100644 --- a/renderer/native/ios/renderer/UIView+Render.h +++ b/renderer/native/ios/renderer/UIView+Render.h @@ -28,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN @interface UIView (Render) +/// Convenient method to get HippyUIManager instance - (HippyUIManager *)uiManager; @end diff --git a/renderer/native/ios/renderer/UIView+Render.mm b/renderer/native/ios/renderer/UIView+Render.mm index 4a271125469..bc1cfcf579d 100644 --- a/renderer/native/ios/renderer/UIView+Render.mm +++ b/renderer/native/ios/renderer/UIView+Render.mm @@ -22,11 +22,12 @@ #import "UIView+Render.h" #import "HippyUIManager.h" -#import "NSObject+Render.h" +#import "UIView+RenderManager.h" #import "NativeRenderManager.h" - +#import "dom/render_manager.h" #include + @implementation UIView (Render) - (HippyUIManager *)uiManager { @@ -39,3 +40,32 @@ - (HippyUIManager *)uiManager { } @end + + +#pragma mark - + +@interface RenderManagerWrapper : NSObject + +/// holds weak_ptr of hippy::RenderManager +@property (nonatomic, assign) std::weak_ptr renderManager; + +@end + +@implementation RenderManagerWrapper + +@end + +@implementation UIView (HippyRenderManager) + +- (void)setRenderManager:(std::weak_ptr)renderManager { + RenderManagerWrapper *wrapper = [[RenderManagerWrapper alloc] init]; + wrapper.renderManager = renderManager; + objc_setAssociatedObject(self, @selector(renderManager), wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (std::weak_ptr)renderManager { + RenderManagerWrapper *wrapper = objc_getAssociatedObject(self, _cmd); + return wrapper.renderManager; +} + +@end diff --git a/modules/ios/base/NSObject+Render.h b/renderer/native/ios/renderer/UIView+RenderManager.h similarity index 88% rename from modules/ios/base/NSObject+Render.h rename to renderer/native/ios/renderer/UIView+RenderManager.h index 2b3ad2d569d..ed4cb516c6c 100644 --- a/modules/ios/base/NSObject+Render.h +++ b/renderer/native/ios/renderer/UIView+RenderManager.h @@ -20,8 +20,10 @@ * limitations under the License. */ -#import +#ifndef UIView_RenderManager_h +#define UIView_RenderManager_h +#import #include NS_ASSUME_NONNULL_BEGIN @@ -32,11 +34,14 @@ class RenderManager; }; }; -// FIXME: remove this category + @interface UIView (HippyRenderManager) +/// Get the hippy::RenderManager instance @property(nonatomic, assign) std::weak_ptr renderManager; @end NS_ASSUME_NONNULL_END + +#endif /* UIView_RenderManager_h */