Hello everyone,I am trying to run a simple CLI application using MultipeerConnectivity.My concern is that startBrowsingForPeer seems to work only on a graphical application (NSApplication) when startAdvertisingPeerseems to work properly on both graphical and CLI apps.Indeed, by executing the same code on the CLI and UI versions, I get this result:- UI browsing / UI advertising = working- UI browsing / CLI advertising = working (startAdvertisingPeer works on CLI)- UI advertising / CLI browsing = not working (startBrowsingForPeer doesn'twork on CLI)I can't figure out if it's a permissions issue (signature, entitlements, etc...) or if it's just that the browsing API can only work in the context of an NSApplication.Steps to reproduce: (Setup)
1.
git clone this repo (UI app):
https://github.com/krugazor/MCChat 2. git clone this repo (CLI app): https://github.com/aeddi/test-cli-multipeerconnectivy (Working case) 3. Open the UI app project in XCode and run the macOS or iOS app 4. Click on the join button 5. In a terminal, go to the CLI app directory and enter: make host (Not working case) 6. Open the UI app project in XCode and run the macOS or iOS app 7. Click on the host button 8. In a terminal, go to the CLI app directory and enter: make guestDetails:The command line testing tool code looks like this:main.m#import <Foundation/Foundation.h>
#import "MPCManager.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
if (argc > 1 && !strcmp(argv[1], "host")) {
[[MPCManager alloc] hostWithDisplayName:@"cli-host"];
} else {
[[MPCManager alloc] joinWithDisplayName:@"cli-guest"];
}
dispatch_main();
}
return 0;
}MPCManager.h#ifndef MPCManager_h
#define MPCManager_h
#import <Foundation/Foundation.h>
#import <MultipeerConnectivity/MultipeerConnectivity.h>
@interface MPCManager : NSObject
- (instancetype) hostWithDisplayName:(NSString*)n;
- (instancetype) joinWithDisplayName:(NSString*)n;
@end
#endif /* MPCManager_h */MPCManager.m#import "MPCManager.h"
static NSString * const AppServiceType = @"chat-service";
@interface MPCManager () <mcnearbyserviceadvertiserdelegate, mcnearbyservicebrowserdelegate,="" mcsessiondelegate="">
@property(nonatomic, copy) NSString *displayName;
@property(nonatomic, strong) MCPeerID *localPeerID;
@property(nonatomic, strong) MCNearbyServiceAdvertiser *advertiser;
@property(nonatomic, strong) MCNearbyServiceBrowser *browser;
@property(nonatomic) MCSession *session;
@end
@implementation MPCManager
- (MCSession*) createOrGetSession {
NSLog(@"createOrGetSession");
if (self.session == nil) {
self.session = [[MCSession alloc] initWithPeer:self.localPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
self.session.delegate = self;
}
return self.session;
}
- (instancetype)hostWithDisplayName:(NSString *)n {
NSLog(@"initAsHostWithDisplayName: %@", n);
self.displayName = n;
self.localPeerID = [[MCPeerID alloc] initWithDisplayName:n];
self.advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.localPeerID discoveryInfo:nil serviceType:AppServiceType];
self.advertiser.delegate = self;
[self.advertiser startAdvertisingPeer];
return self;
}
- (instancetype)joinWithDisplayName:(NSString *)n {
NSLog(@"joinWithDisplayName: %@", n);
self.localPeerID = [[MCPeerID alloc] initWithDisplayName:n];
self.browser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.localPeerID serviceType:AppServiceType];
self.browser.delegate = self;
[self.browser startBrowsingForPeers];
return self;
}
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler: (void(^)(BOOL accept, MCSession *session))invitationHandler {
NSLog(@"didReceiveInvitationFromPeer: %@", [peerID displayName]);
invitationHandler(YES, [self createOrGetSession]);
}
- (void) browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(nullable NSDictionary *)info {
NSLog(@"foundPeer: %@", [peerID displayName]);
[browser invitePeer:peerID toSession:[self createOrGetSession] withContext:nil timeout:30.0]; // 30s
}
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID {
NSLog(@"lostPeer: %@", [peerID displayName]);
}
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state {
NSLog(@"didChangeState: %ld", state);
}
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {
NSLog(@"didReceiveData: %@", [peerID displayName]);
}
- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID {
NSLog(@"didReceiveStream: %@", [peerID displayName]);
}
- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress {
NSLog(@"didStartReceivingResourceWithName: %@", [peerID displayName]);
}
- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error {
NSLog(@"didFinishReceivingResourceWithName: %@", [peerID displayName]);
}
@endAnd I compile this code using:- Compiler: Apple clang version 11.0.0 (clang-1100.0.33.17)- OS: macOS 10.5.3- Command: clang *.m -framework Foundation -framework MultipeerConnectivityI don't sign it in any way.Note: I also tried to create a Command Line Tool project in XCode containing this code, but when I run it, not only the browing still not work, but advertising doesn't work either, regardless of the many signature and capability settings I tried.
Selecting any option will automatically load the page