diff --git a/iOS/SonarKit/FlipperDiagnosticsViewController.h b/iOS/SonarKit/FlipperDiagnosticsViewController.h index a729dd827..58854c43c 100644 --- a/iOS/SonarKit/FlipperDiagnosticsViewController.h +++ b/iOS/SonarKit/FlipperDiagnosticsViewController.h @@ -7,11 +7,13 @@ */ #ifdef FB_SONARKIT_ENABLED +#include "FlipperStateUpdateListener.h" #import -@interface FlipperDiagnosticsViewController : UIViewController +@interface FlipperDiagnosticsViewController : UIViewController @property(strong, nonatomic) UIScrollView *scrollView; @property(strong, nonatomic) UILabel *stateLabel; +- (void)onUpdate; @end #endif diff --git a/iOS/SonarKit/FlipperDiagnosticsViewController.m b/iOS/SonarKit/FlipperDiagnosticsViewController.m index 01342238a..d6e89980d 100644 --- a/iOS/SonarKit/FlipperDiagnosticsViewController.m +++ b/iOS/SonarKit/FlipperDiagnosticsViewController.m @@ -12,8 +12,9 @@ text.text = @"Flipper Diagnostics"; [self.view addSubview:text]; - self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height - 50)]; + self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height - 100)]; self.stateLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1000)]; + self.stateLabel.numberOfLines = 0; self.stateLabel.text = [[SonarClient sharedClient] getState]; [self.scrollView addSubview:self.stateLabel]; @@ -22,8 +23,23 @@ } - (void)onUpdate { - self.stateLabel.text = [[SonarClient sharedClient] getState]; - self.scrollView.contentSize = self.stateLabel.frame.size; + FlipperDiagnosticsViewController __weak *weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + FlipperDiagnosticsViewController *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + NSString *state = [[SonarClient sharedClient] getState]; + strongSelf.stateLabel.text = state; + [strongSelf.stateLabel sizeToFit]; + strongSelf.scrollView.contentSize = strongSelf.stateLabel.frame.size; + }); +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + id weakSelf = self; + [[SonarClient sharedClient] subscribeForUpdates:weakSelf]; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { diff --git a/iOS/SonarKit/FlipperStateUpdateListener.h b/iOS/SonarKit/FlipperStateUpdateListener.h new file mode 100644 index 000000000..dc1989055 --- /dev/null +++ b/iOS/SonarKit/FlipperStateUpdateListener.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#ifdef FB_SONARKIT_ENABLED + +@protocol FlipperStateUpdateListener +- (void)onUpdate; +@end + +#endif diff --git a/iOS/SonarKit/SKStateUpdateCPPWrapper.h b/iOS/SonarKit/SKStateUpdateCPPWrapper.h new file mode 100644 index 000000000..6f25f2073 --- /dev/null +++ b/iOS/SonarKit/SKStateUpdateCPPWrapper.h @@ -0,0 +1,19 @@ +#ifdef FB_SONARKIT_ENABLED + +#include +#import "FlipperStateUpdateListener.h" + +/* + * This class exists to bridge the gap between Objective C and C++. + * A SKStateUpdateCPPWrapper instance allows for wrapping an Objective-C object + * and passing it to the pure C++ SonarClient, so it can be triggered when updates occur. + */ +class SKStateUpdateCPPWrapper : public SonarStateUpdateListener { +public: + SKStateUpdateCPPWrapper(id delegate_); + void onUpdate(); +private: + __weak id delegate_; +}; + +#endif diff --git a/iOS/SonarKit/SKStateUpdateCPPWrapper.mm b/iOS/SonarKit/SKStateUpdateCPPWrapper.mm new file mode 100644 index 000000000..0485b6bf6 --- /dev/null +++ b/iOS/SonarKit/SKStateUpdateCPPWrapper.mm @@ -0,0 +1,16 @@ +#ifdef FB_SONARKIT_ENABLED + +#include "SKStateUpdateCPPWrapper.h" + +SKStateUpdateCPPWrapper::SKStateUpdateCPPWrapper(id controller) { + delegate_ = controller; +} + +void SKStateUpdateCPPWrapper::onUpdate() { + if (!delegate_) { + return; + } + [delegate_ onUpdate]; +} + +#endif diff --git a/iOS/SonarKit/SonarClient.h b/iOS/SonarKit/SonarClient.h index a8bbb48d4..d44da890b 100644 --- a/iOS/SonarKit/SonarClient.h +++ b/iOS/SonarKit/SonarClient.h @@ -8,6 +8,7 @@ #import #import "SonarPlugin.h" +#import "FlipperStateUpdateListener.h" /** Represents a connection between the Sonar desktop och client side. Manages the lifecycle of attached @@ -50,6 +51,11 @@ Get the current state of the sonar client */ - (NSString *)getState; +/** +Subscribe a ViewController to state update change notifications +*/ +- (void)subscribeForUpdates:(id)controller; + // initializers are disabled. You must use `+[SonarClient sharedClient]` instance. - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/iOS/SonarKit/SonarClient.mm b/iOS/SonarKit/SonarClient.mm index a7400102e..e5bf17e6f 100644 --- a/iOS/SonarKit/SonarClient.mm +++ b/iOS/SonarKit/SonarClient.mm @@ -13,6 +13,8 @@ #include #include #import +#include "SKStateUpdateCPPWrapper.h" +#import "FlipperDiagnosticsViewController.h" #if !TARGET_OS_SIMULATOR //#import "SKPortForwardingServer.h" @@ -125,6 +127,11 @@ using WrapperPlugin = facebook::sonar::SonarCppWrapperPlugin; return @(_cppClient->getState().c_str()); } +- (void)subscribeForUpdates:(id)controller { + auto stateListener = std::make_shared(controller); + _cppClient->setStateListener(stateListener); +} + @end #endif