From 4480cc5ea34ab926d08a408ada74c33c72d57613 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 21 Feb 2018 11:16:57 +0100 Subject: [PATCH 1/5] bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e47a50..3f3c748 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "type": "git", "url": "https://github.com/HippoAR/react-native-arkit.git" }, - "version": "0.8.0", + "version": "0.9.0-beta.0", "description": "React Native binding for iOS ARKit", "author": "Zehao Li ", "license": "MIT", From 6bd946704c1e790d89cb25407a5f3f9b4c9bb9db Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 21 Feb 2018 14:40:58 +0100 Subject: [PATCH 2/5] implement isInitialized and isMounted --- ARKit.js | 13 +++++++------ ios/RCTARKit.h | 4 ++-- ios/RCTARKit.m | 15 ++++++++++++++- ios/RCTARKitManager.m | 13 +++++++++++++ startup.js | 7 ++++++- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ARKit.js b/ARKit.js index e9c8e85..7854b32 100644 --- a/ARKit.js +++ b/ARKit.js @@ -159,13 +159,12 @@ Object.keys(ARKitManager).forEach(key => { ARKit[key] = ARKitManager[key]; }); -const addDefaultsToSnapShotFunc = funcName => ({ - target = 'cameraRoll', - format = 'png' -} = {}) => ARKitManager[funcName]({ target, format }); +const addDefaultsToSnapShotFunc = funcName => ( + { target = 'cameraRoll', format = 'png' } = {}, +) => ARKitManager[funcName]({ target, format }); -ARKit.snapshot = addDefaultsToSnapShotFunc("snapshot"); -ARKit.snapshotCamera = addDefaultsToSnapShotFunc("snapshotCamera"); +ARKit.snapshot = addDefaultsToSnapShotFunc('snapshot'); +ARKit.snapshotCamera = addDefaultsToSnapShotFunc('snapshotCamera'); ARKit.exportModel = presetId => { const id = presetId || generateId(); @@ -197,6 +196,8 @@ ARKit.propTypes = { onTapOnPlaneUsingExtent: PropTypes.func, onTapOnPlaneNoExtent: PropTypes.func, onEvent: PropTypes.func, + isMounted: PropTypes.func, + isInitialized: PropTypes.func, }; const RCTARKit = requireNativeComponent('RCTARKit', ARKit); diff --git a/ios/RCTARKit.h b/ios/RCTARKit.h index 6d418a9..b6b97d7 100644 --- a/ios/RCTARKit.h +++ b/ios/RCTARKit.h @@ -21,6 +21,7 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error @interface RCTARKit : UIView + (instancetype)sharedInstance; ++ (bool)isInitialized; - (instancetype)initWithARView:(ARSCNView *)arView; @@ -72,8 +73,7 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error - (NSDictionary *)readCamera; - (NSDictionary* )getCurrentLightEstimation; - (NSArray * )getCurrentDetectedFeaturePoints; - - +- (bool)isMounted; #pragma mark - Delegates - (void)renderer:(id )renderer didRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time; diff --git a/ios/RCTARKit.m b/ios/RCTARKit.m index 5577297..bb7a099 100644 --- a/ios/RCTARKit.m +++ b/ios/RCTARKit.m @@ -36,9 +36,14 @@ void dispatch_once_on_main_thread(dispatch_once_t *predicate, @implementation RCTARKit +static RCTARKit *instance = nil; + ++ (bool)isInitialized { + return instance !=nil; +} + (instancetype)sharedInstance { - static RCTARKit *instance = nil; + static dispatch_once_t onceToken; dispatch_once_on_main_thread(&onceToken, ^{ @@ -47,9 +52,15 @@ + (instancetype)sharedInstance { instance = [[self alloc] initWithARView:arView]; } }); + return instance; } +- (bool)isMounted { + + return self.superview != nil; +} + - (instancetype)initWithARView:(ARSCNView *)arView { if ((self = [super init])) { self.arView = arView; @@ -85,6 +96,8 @@ - (instancetype)initWithARView:(ARSCNView *)arView { return self; } + + - (void)layoutSubviews { [super layoutSubviews]; //NSLog(@"setting view bounds %@", NSStringFromCGRect(self.bounds)); diff --git a/ios/RCTARKitManager.m b/ios/RCTARKitManager.m index f1f25c5..6c6ef67 100644 --- a/ios/RCTARKitManager.m +++ b/ios/RCTARKitManager.m @@ -134,6 +134,19 @@ - (NSDictionary *)constantsToExport resolve(@{}); } +RCT_EXPORT_METHOD(isInitialized:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { + resolve(@([ARKit isInitialized])); +} + +RCT_EXPORT_METHOD(isMounted:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { + if( [ARKit isInitialized]) { + dispatch_async(dispatch_get_main_queue(), ^{ + resolve(@([[ARKit sharedInstance] isMounted])); + }); + } else { + resolve(@(NO)); + } +} RCT_EXPORT_METHOD( hitTestPlanes: (NSDictionary *)pointDict diff --git a/startup.js b/startup.js index 4899c34..e1f0eba 100644 --- a/startup.js +++ b/startup.js @@ -6,5 +6,10 @@ export default () => { // when reloading the app, the scene should be cleared. // on prod, this usually does not happen, but you can reload the app in develop mode // without clearing, this would result in inconsistency - ARKitManager.clearScene(); + ARKitManager.isInitialized().then(isInitialized => { + console.log('was already initialized on startup', isInitialized); + if (isInitialized) { + ARKitManager.clearScene(); + } + }); }; From 54b4d370f7f5b1924a3a56218cd87a15a74ea05b Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 21 Feb 2018 14:43:23 +0100 Subject: [PATCH 3/5] remove log --- startup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/startup.js b/startup.js index e1f0eba..6817eeb 100644 --- a/startup.js +++ b/startup.js @@ -6,8 +6,8 @@ export default () => { // when reloading the app, the scene should be cleared. // on prod, this usually does not happen, but you can reload the app in develop mode // without clearing, this would result in inconsistency + // do this only when arkit was already initialized ARKitManager.isInitialized().then(isInitialized => { - console.log('was already initialized on startup', isInitialized); if (isInitialized) { ARKitManager.clearScene(); } From 804c37acb103ac9b3a99ffb6d6b43c1f9c032060 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 21 Feb 2018 15:02:21 +0100 Subject: [PATCH 4/5] update readme --- README.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index be9178c..ddb0cfc 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ These steps are mandatory regardless of doing a manual or automatic installation 2. ARKit only runs on arm64-ready devices so the default build architecture should be set to arm64: go to `Build settings` ➜ `Build Active Architecture Only` and change the value to `Yes`. + + ## Usage A simple sample React Native ARKit App @@ -83,6 +85,7 @@ export default class ReactNativeARKit extends Component { onPlaneDetected={console.log} // event listener for plane detection onPlaneUpdate={console.log} // event listener for plane update onPlaneRemoved={console.log} // arkit sometimes removes detected planes + onARKitError={console.log} // if arkit could not be initialized (e.g. missing permissions), you will get notified here > ` component or use any of its API. If user denies access, you will get an error in `onARKitError` +- *location service*: only needed if you use `ARKit.ARWorldAlignment.GravityAndHeading`. + +#### Is there an Android / ARCore version? + +Not yet, but there has been a proof-of-concept: https://github.com/HippoAR/react-native-arkit/issues/14. We are looking for contributors to help backporting this proof-of-conept to react-native-arkit. + +#### I have another question... + +[**Join Slack!**](https://join.slack.com/t/react-native-ar/shared_invite/enQtMjUzMzg3MjM0MTQ5LWU3Nzg2YjI4MGRjMTM1ZDBlNmIwYTE4YmM0M2U0NmY2YjBiYzQ4YzlkODExMTA0NDkwMzFhYWY4ZDE2M2Q4NGY) + ## Contributing From ee60c88e75e034723007d171576844e13ce5f498 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 21 Feb 2018 15:03:23 +0100 Subject: [PATCH 5/5] update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ddb0cfc..217ed7a 100644 --- a/README.md +++ b/README.md @@ -546,8 +546,8 @@ It uses https://developer.apple.com/documentation/scenekit/scnscenerenderer/1522 #### Which permissions does this use? -- *camera access* (see section iOS Project configuration above). The user is asked for permission, as soon as you mount an `` component or use any of its API. If user denies access, you will get an error in `onARKitError` -- *location service*: only needed if you use `ARKit.ARWorldAlignment.GravityAndHeading`. +- **camera access** (see section iOS Project configuration above). The user is asked for permission, as soon as you mount an `` component or use any of its API. If user denies access, you will get an error in `onARKitError` +- **location service**: only needed if you use `ARKit.ARWorldAlignment.GravityAndHeading`. #### Is there an Android / ARCore version?