|
| 1 | +#import <React/RCTXRModule.h> |
| 2 | + |
| 3 | +#import <FBReactNativeSpec_visionOS/FBReactNativeSpec_visionOS.h> |
| 4 | + |
| 5 | +#import <React/RCTBridge.h> |
| 6 | +#import <React/RCTConvert.h> |
| 7 | +#import <React/RCTUtils.h> |
| 8 | +#import "RCTXR-Swift.h" |
| 9 | + |
| 10 | +@interface RCTXRModule () <NativeXRModuleSpec> |
| 11 | +@end |
| 12 | + |
| 13 | +@implementation RCTXRModule { |
| 14 | + UIViewController *_immersiveBridgeView; |
| 15 | +} |
| 16 | + |
| 17 | +RCT_EXPORT_MODULE() |
| 18 | + |
| 19 | +RCT_EXPORT_METHOD(endSession |
| 20 | + : (RCTPromiseResolveBlock)resolve reject |
| 21 | + : (RCTPromiseRejectBlock)reject) |
| 22 | +{ |
| 23 | + [self removeImmersiveBridge]; |
| 24 | + resolve(nil); |
| 25 | +} |
| 26 | + |
| 27 | + |
| 28 | +RCT_EXPORT_METHOD(requestSession |
| 29 | + : (NSString *)sessionId resolve |
| 30 | + : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) |
| 31 | +{ |
| 32 | + RCTExecuteOnMainQueue(^{ |
| 33 | + UIWindow *keyWindow = RCTKeyWindow(); |
| 34 | + UIViewController *rootViewController = keyWindow.rootViewController; |
| 35 | + |
| 36 | + if (self->_immersiveBridgeView == nil) { |
| 37 | + self->_immersiveBridgeView = [ImmersiveBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId |
| 38 | + completionHandler:^(enum ImmersiveSpaceResult result){ |
| 39 | + if (result == ImmersiveSpaceResultError) { |
| 40 | + reject(@"ERROR", @"Immersive Space failed to open, the system cannot fulfill the request.", nil); |
| 41 | + [self removeImmersiveBridge]; |
| 42 | + } else if (result == ImmersiveSpaceResultUserCancelled) { |
| 43 | + reject(@"ERROR", @"Immersive Space canceled by user", nil); |
| 44 | + [self removeImmersiveBridge]; |
| 45 | + } else if (result == ImmersiveSpaceResultOpened) { |
| 46 | + resolve(nil); |
| 47 | + } |
| 48 | + }]; |
| 49 | + |
| 50 | + [rootViewController.view addSubview:self->_immersiveBridgeView.view]; |
| 51 | + [rootViewController addChildViewController:self->_immersiveBridgeView]; |
| 52 | + [self->_immersiveBridgeView didMoveToParentViewController:rootViewController]; |
| 53 | + } else { |
| 54 | + reject(@"ERROR", @"Immersive Space already opened", nil); |
| 55 | + } |
| 56 | + }); |
| 57 | +} |
| 58 | + |
| 59 | +- (facebook::react::ModuleConstants<JS::NativeXRModule::Constants::Builder>)constantsToExport { |
| 60 | + return [self getConstants]; |
| 61 | +} |
| 62 | + |
| 63 | +- (facebook::react::ModuleConstants<JS::NativeXRModule::Constants>)getConstants { |
| 64 | + __block facebook::react::ModuleConstants<JS::NativeXRModule::Constants> constants; |
| 65 | + RCTUnsafeExecuteOnMainQueueSync(^{ |
| 66 | + constants = facebook::react::typedConstants<JS::NativeXRModule::Constants>({ |
| 67 | + .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes |
| 68 | + }); |
| 69 | + }); |
| 70 | + |
| 71 | + return constants; |
| 72 | +} |
| 73 | + |
| 74 | +- (void) removeImmersiveBridge |
| 75 | +{ |
| 76 | + RCTExecuteOnMainQueue(^{ |
| 77 | + [self->_immersiveBridgeView willMoveToParentViewController:nil]; |
| 78 | + [self->_immersiveBridgeView.view removeFromSuperview]; |
| 79 | + [self->_immersiveBridgeView removeFromParentViewController]; |
| 80 | + self->_immersiveBridgeView = nil; |
| 81 | + }); |
| 82 | +} |
| 83 | + |
| 84 | +- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { |
| 85 | + return std::make_shared<facebook::react::NativeXRModuleSpecJSI>(params); |
| 86 | +} |
| 87 | + |
| 88 | +@end |
0 commit comments