Skip to content

Commit 2ae58ca

Browse files
authored
Merge pull request #1 from code-matt/feature/multipeer
Feature/multipeer WIP !!
2 parents 84dc8e2 + 796bc2e commit 2ae58ca

File tree

8 files changed

+414
-3
lines changed

8 files changed

+414
-3
lines changed

.DS_Store

8 KB
Binary file not shown.

ios/.DS_Store

6 KB
Binary file not shown.

ios/RCTARKit.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#import "RCTARKitDelegate.h"
1414
#import "RCTARKitNodes.h"
15+
#import "RCTMultiPeer.h"
1516

1617
typedef void (^RCTBubblingEventBlock)(NSDictionary *body);
1718
typedef void (^RCTARKitResolve)(id result);
@@ -22,16 +23,19 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error
2223

2324
+ (instancetype)sharedInstance;
2425
+ (bool)isInitialized;
26+
- (instancetype)initWithARViewAndBrowser:(ARSCNView *)arView multipeer:(MultipeerConnectivity *)multipeer;
2527
- (instancetype)initWithARView:(ARSCNView *)arView;
2628

2729

2830
@property (nonatomic, strong) NSMutableArray<id<RCTARKitTouchDelegate>> *touchDelegates;
2931
@property (nonatomic, strong) NSMutableArray<id<RCTARKitRendererDelegate>> *rendererDelegates;
3032
@property (nonatomic, strong) NSMutableArray<id<RCTARKitSessionDelegate>> *sessionDelegates;
33+
@property (nonatomic, strong) NSMutableArray<id<MultipeerConnectivityDelegate>> *multipeerDelegate;
3134

3235

3336
#pragma mark - Properties
3437
@property (nonatomic, strong) ARSCNView *arView;
38+
@property (nonatomic, strong) MultipeerConnectivity *multipeer;
3539
@property (nonatomic, strong) RCTARKitNodes *nodeManager;
3640

3741
@property (nonatomic, assign) BOOL debug;
@@ -60,6 +64,14 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error
6064
@property (nonatomic, copy) RCTBubblingEventBlock onEvent;
6165
@property (nonatomic, copy) RCTBubblingEventBlock onARKitError;
6266

67+
@property (nonatomic, copy) RCTBubblingEventBlock onPeerConnected;
68+
@property (nonatomic, copy) RCTBubblingEventBlock onPeerConnecting;
69+
@property (nonatomic, copy) RCTBubblingEventBlock onPeerDisconnected;
70+
71+
@property (nonatomic, copy) RCTBubblingEventBlock onMultipeerJsonDataReceived;
72+
73+
74+
6375

6476
@property NSMutableDictionary *planes; // plane detected
6577

@@ -70,6 +82,7 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error
7082
- (void)resume;
7183
- (void)reset;
7284
- (void)hitTestPlane:(CGPoint)tapPoint types:(ARHitTestResultType)types resolve:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject;
85+
- (void)getCurrentWorldMap:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject;
7386
- (void)hitTestSceneObjects:(CGPoint)tapPoint resolve:(RCTARKitResolve) resolve reject:(RCTARKitReject)reject;
7487
- (SCNVector3)projectPoint:(SCNVector3)point;
7588
- (float)getCameraDistanceToPoint:(SCNVector3)point;

ios/RCTARKit.m

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88

99
#import "RCTARKit.h"
1010
#import "RCTConvert+ARKit.h"
11+
#import "RCTMultiPeer.h"
1112

1213
@import CoreLocation;
1314

14-
@interface RCTARKit () <ARSCNViewDelegate, ARSessionDelegate, UIGestureRecognizerDelegate> {
15+
@interface RCTARKit () <ARSCNViewDelegate, ARSessionDelegate, UIGestureRecognizerDelegate, MultipeerConnectivityDelegate> {
1516
RCTARKitResolve _resolve;
1617
}
1718

1819
@property (nonatomic, strong) ARSession* session;
1920
@property (nonatomic, strong) ARWorldTrackingConfiguration *configuration;
21+
@property (nonatomic, strong) ARWorldMap *worldMap;
2022

2123
@end
2224

@@ -49,15 +51,17 @@ + (instancetype)sharedInstance {
4951
dispatch_once_on_main_thread(&onceToken, ^{
5052
if (instance == nil) {
5153
ARSCNView *arView = [[ARSCNView alloc] init];
54+
MultipeerConnectivity *multipeer = [[MultipeerConnectivity alloc] init];
5255
instance = [[self alloc] initWithARView:arView];
56+
multipeer.delegate = instance;
57+
instance.multipeer = multipeer;
5358
}
5459
});
5560

5661
return instance;
5762
}
5863

5964
- (bool)isMounted {
60-
6165
return self.superview != nil;
6266
}
6367

@@ -102,7 +106,55 @@ - (instancetype)initWithARView:(ARSCNView *)arView {
102106
return self;
103107
}
104108

105-
109+
- (void)receivedDataHandler:(NSData *)data PeerID:(MCPeerID *)peerID
110+
{
111+
id parsedJSON;
112+
@try {
113+
NSError *error = nil;
114+
parsedJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
115+
} @catch (NSException *exception) {
116+
// TODO: make a onMultipeerDataFailure callback
117+
} @finally {
118+
119+
}
120+
121+
if (parsedJSON) {
122+
if (self.onMultipeerJsonDataReceived) {
123+
dispatch_async(dispatch_get_main_queue(), ^{
124+
self.onMultipeerJsonDataReceived(@{
125+
@"data": parsedJSON,
126+
});
127+
});
128+
}
129+
} else {
130+
id unarchived = [NSKeyedUnarchiver unarchivedObjectOfClass:[ARWorldMap classForKeyedUnarchiver] fromData:data error:nil];
131+
132+
if ([unarchived isKindOfClass:[ARWorldMap class]]) {
133+
NSLog(@"[unarchived class]====%@",[unarchived class]);
134+
ARWorldMap *worldMap = unarchived;
135+
self.configuration = [[ARWorldTrackingConfiguration alloc] init];
136+
self.configuration.worldAlignment = ARWorldAlignmentGravity;
137+
self.configuration.planeDetection = ARPlaneDetectionHorizontal|ARPlaneDetectionVertical;
138+
self.configuration.initialWorldMap = worldMap;
139+
[self.arView.session runWithConfiguration:self.configuration options:ARSessionRunOptionResetTracking|ARSessionRunOptionRemoveExistingAnchors];
140+
141+
return;
142+
}
143+
144+
unarchived = [NSKeyedUnarchiver unarchivedObjectOfClass:[ARAnchor classForKeyedUnarchiver] fromData:data error:nil];
145+
146+
if ([unarchived isKindOfClass:[ARAnchor class]]) {
147+
NSLog(@"[unarchived class]====%@",[unarchived class]);
148+
ARAnchor *anchor = unarchived;
149+
150+
[self.arView.session addAnchor:anchor];
151+
152+
return;
153+
}
154+
155+
NSLog(@"unknown data recieved from \(%@)",peerID.displayName);
156+
}
157+
}
106158

107159

108160
- (void)layoutSubviews {
@@ -128,6 +180,19 @@ - (void)session:(ARSession *)session didFailWithError:(NSError *)error {
128180
}
129181

130182
}
183+
184+
- (void)getCurrentWorldMap:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject {
185+
[self.arView.session getCurrentWorldMapWithCompletionHandler:^(ARWorldMap * _Nullable worldMap, NSError * _Nullable error) {
186+
NSLog(@"got the current world map!!!");
187+
if (error) {
188+
NSLog(@"error====%@",error);
189+
}
190+
191+
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:worldMap requiringSecureCoding:true error:nil];
192+
[[ARKit sharedInstance].multipeer sendToAllPeers:data];
193+
}];
194+
}
195+
131196
- (void)reset {
132197
if (ARWorldTrackingConfiguration.isSupported) {
133198
[self.session runWithConfiguration:self.configuration options:ARSessionRunOptionRemoveExistingAnchors | ARSessionRunOptionResetTracking];
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

ios/RCTARKitManager.m

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
#import <UIKit/UIKit.h>
1313
#import <Photos/Photos.h>
1414
#import "color-grabber.h"
15+
#import "RCTMultiPeer.h"
1516

17+
@interface RCTARKitManager () <MCBrowserViewControllerDelegate>
18+
19+
@end
1620
@implementation RCTARKitManager
1721

1822
RCT_EXPORT_MODULE()
@@ -172,13 +176,21 @@ - (NSDictionary *)constantsToExport
172176
RCT_EXPORT_VIEW_PROPERTY(onAnchorUpdated, RCTBubblingEventBlock)
173177
RCT_EXPORT_VIEW_PROPERTY(onAnchorRemoved, RCTBubblingEventBlock)
174178

179+
RCT_EXPORT_VIEW_PROPERTY(onMultipeerJsonDataReceived, RCTBubblingEventBlock)
180+
181+
// TODO: Option to lock these three below down for host only
182+
RCT_EXPORT_VIEW_PROPERTY(onPeerConnected, RCTBubblingEventBlock)
183+
RCT_EXPORT_VIEW_PROPERTY(onPeerConnecting, RCTBubblingEventBlock)
184+
RCT_EXPORT_VIEW_PROPERTY(onPeerDisconnected, RCTBubblingEventBlock)
185+
175186
RCT_EXPORT_VIEW_PROPERTY(onTrackingState, RCTBubblingEventBlock)
176187
RCT_EXPORT_VIEW_PROPERTY(onFeaturesDetected, RCTBubblingEventBlock)
177188
RCT_EXPORT_VIEW_PROPERTY(onLightEstimation, RCTBubblingEventBlock)
178189
RCT_EXPORT_VIEW_PROPERTY(onTapOnPlaneUsingExtent, RCTBubblingEventBlock)
179190
RCT_EXPORT_VIEW_PROPERTY(onTapOnPlaneNoExtent, RCTBubblingEventBlock)
180191
RCT_EXPORT_VIEW_PROPERTY(onEvent, RCTBubblingEventBlock)
181192
RCT_EXPORT_VIEW_PROPERTY(onARKitError, RCTBubblingEventBlock)
193+
RCT_EXPORT_VIEW_PROPERTY(worldMap, NSObject);
182194

183195
RCT_EXPORT_METHOD(pause:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
184196
[[ARKit sharedInstance] pause];
@@ -199,6 +211,43 @@ - (NSDictionary *)constantsToExport
199211
resolve(@([ARKit isInitialized]));
200212
}
201213

214+
RCT_EXPORT_METHOD(openMultipeerBrowser:(NSString *)serviceType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
215+
[[ARKit sharedInstance].multipeer openMultipeerBrowser:serviceType];
216+
}
217+
218+
RCT_EXPORT_METHOD(startBrowsingForPeers:(NSString *)serviceType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
219+
[[ARKit sharedInstance].multipeer startBrowsingForPeers:serviceType];
220+
}
221+
222+
RCT_EXPORT_METHOD(advertiseReadyToJoinSession:(NSString *)serviceType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
223+
[[ARKit sharedInstance].multipeer advertiseReadyToJoinSession:serviceType];
224+
}
225+
226+
// TODO: Should be optionally to only be available to host
227+
RCT_EXPORT_METHOD(sendDataToAllPeers:(NSDictionary *)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
228+
[self sendData:[RCTARKit sharedInstance].multipeer.connectedPeers data:data callback:resolve];
229+
}
230+
231+
// TODO: Should be optional to lock it down so peers can only send to host
232+
RCT_EXPORT_METHOD(sendDataToPeers:(NSDictionary *)data recepientPeerIDs:(NSArray *)recepientPeerIDs resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
233+
NSError *error = nil;
234+
NSMutableArray *peers = [NSMutableArray array];
235+
for (NSString *peerUUID in recepientPeerIDs) {
236+
[peers addObject:[[RCTARKit sharedInstance].multipeer.connectedPeers valueForKey:peerUUID]];
237+
}
238+
[self sendData:[RCTARKit sharedInstance].multipeer.connectedPeers data:data callback:resolve];
239+
}
240+
241+
// TODO: Should be optional to only be available to host
242+
RCT_EXPORT_METHOD(sendWorldmapData:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
243+
[[ARKit sharedInstance] getCurrentWorldMap:resolve reject:reject];
244+
}
245+
246+
// TODO: Should be optional to only be available to host
247+
RCT_EXPORT_METHOD(getAllConnectedPeers:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
248+
//TODO: get all peer ids
249+
}
250+
202251
RCT_EXPORT_METHOD(isMounted:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
203252
if( [ARKit isInitialized]) {
204253
dispatch_async(dispatch_get_main_queue(), ^{
@@ -228,6 +277,23 @@ - (NSDictionary *)constantsToExport
228277
[[ARKit sharedInstance] hitTestSceneObjects:point resolve:resolve reject:reject];
229278
}
230279

280+
- (void)sendData:(NSArray *)recipients data:(NSDictionary *)data callback:(RCTResponseSenderBlock)callback {
281+
NSError *error = nil;
282+
NSMutableArray *peers = [NSMutableArray array];
283+
// for (NSString *peerUUID in recipients) {
284+
// [peers addObject:[[ARKit sharedInstance].multipeer.session.connectedPeers valueForKey:peerUUID]];
285+
// }
286+
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:&error];
287+
[[ARKit sharedInstance].multipeer.session sendData:jsonData toPeers:recipients withMode:MCSessionSendDataReliable error:&error];
288+
NSLog(@"Sending data...");
289+
if (error == nil) {
290+
callback(@[[NSNull null]]);
291+
}
292+
else {
293+
callback(@[[error description]]);
294+
}
295+
}
296+
231297

232298

233299

@@ -398,4 +464,24 @@ - (void)storeImage:(UIImage *)image options:(NSDictionary *)options reject:(RCTP
398464
resolve(@{});
399465
}
400466

467+
- (void)browserViewControllerDidFinish:(nonnull MCBrowserViewController *)browserViewController {
468+
dispatch_async(dispatch_get_main_queue(), ^{
469+
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
470+
471+
[rootViewController dismissViewControllerAnimated:YES completion:^{
472+
473+
}];
474+
});
475+
}
476+
477+
- (void)browserViewControllerWasCancelled:(nonnull MCBrowserViewController *)browserViewController {
478+
dispatch_async(dispatch_get_main_queue(), ^{
479+
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
480+
481+
[rootViewController dismissViewControllerAnimated:YES completion:^{
482+
483+
}];
484+
});
485+
}
486+
401487
@end

ios/RCTMultiPeer.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// MultipeerConnectivity.h
3+
// ARKit
4+
//
5+
// Created by Mac on 2018/6/5.
6+
// Copyright © 2018年 AR. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
#import <MultipeerConnectivity/MultipeerConnectivity.h>
11+
12+
NS_ASSUME_NONNULL_BEGIN
13+
14+
typedef void (^RCTBubblingEventBlock)(NSDictionary *body);
15+
typedef void (^RCTARKitResolve)(id result);
16+
typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error);
17+
18+
@protocol MultipeerConnectivityDelegate <NSObject>
19+
@optional
20+
21+
- (void)receivedDataHandler:(NSData *)data PeerID:(MCPeerID *)peerID;
22+
23+
@end
24+
25+
@interface MultipeerConnectivity : UIView
26+
27+
@property(nonatomic, strong)MCPeerID *myPeerID;
28+
29+
@property(nonatomic, strong)MCSession *session;
30+
31+
@property(nonatomic, strong)MCNearbyServiceAdvertiser *serviceAdvertiser;
32+
33+
@property(nonatomic, strong)MCNearbyServiceBrowser *serviceBrowser;
34+
@property(nonatomic, strong)MCBrowserViewController *mpBrowser;
35+
36+
@property(nonatomic, strong)NSMutableDictionary *connectedPeersDictionary;
37+
38+
@property(nonatomic, weak)id <MultipeerConnectivityDelegate> delegate;
39+
40+
- (void)sendToAllPeers:(NSData *)data;
41+
42+
- (void)startBrowsingForPeers:(NSString *)serviceType;
43+
- (void)advertiseReadyToJoinSession:(NSString *)serviceType;
44+
- (void)openMultipeerBrowser:(NSString *)serviceType;
45+
46+
//@property (nonatomic, copy) RCTBubblingEventBlock onPeerConnected;
47+
//@property (nonatomic, copy) RCTBubblingEventBlock onPeerConnecting;
48+
//@property (nonatomic, copy) RCTBubblingEventBlock onPeerDisconnected;
49+
50+
- (NSArray<MCPeerID *> *)connectedPeers;
51+
52+
@end
53+
54+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)