I would like to setup a client-server architecture for streaming data between multiple iPhones. For instance, the 'server' iPhone hosts a master list of animals. An arbitrary number of client iPhones can connect to the server iPhone then read and edit the list. Some methods I have tried:
I'm willing to entertain 'hacky' solutions. I was thinking of broadcasting each animal as a separate characteristic, but this may slow down discovery and I have a feeling it will cause a few other headaches. Any help would be greatly appreciated
Multipeer Connectivity does only support 8 peers per session, but it supports multiple sessions. In your case, where there is a single 'server' device with many clients, and the clients don't need to see each other, the 'server' can just create new sessions as needed.
So with the 'server' peer acting as advertiser, and accepting invitations, have a method that returns an existing session or creates a new one:
- (MCSession *)availableSession {
//Try and use an existing session (_sessions is a mutable array)
for (MCSession *session in _sessions)
if ([session.connectedPeers count]<kMCSessionMaximumNumberOfPeers)
return session;
//Or create a new session
MCSession *newSession = [self newSession];
[_sessions addObject:newSession];
return newSession;
}
- (MCSession *)newSession {
MCSession *session = [[MCSession alloc] initWithPeer:_myPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
session.delegate = self;
return session;
}
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler {
MCSession *session = [self availableSession];
invitationHandler(YES,session);
}
I then have this method for sending:
- (void)sendData:(NSData *)data toPeers:(NSArray *)peerIDs reliable:(BOOL)reliable error:(NSError *__autoreleasing *)error {
if ([peerIDs count]==0)
return;
NSPredicate *peerNamePred = [NSPredicate predicateWithFormat:@"displayName in %@", [peerIDs valueForKey:@"displayName"]];
MCSessionSendDataMode mode = (reliable) ? MCSessionSendDataReliable : MCSessionSendDataUnreliable;
//Need to match up peers to their session
for (MCSession *session in _sessions){
NSError __autoreleasing *currentError = nil;
NSArray *filteredPeerIDs = [session.connectedPeers filteredArrayUsingPredicate:peerNamePred];
[session sendData:data toPeers:filteredPeerIDs withMode:mode error:¤tError];
if (currentError && !error)
*error = currentError;
}
}
There are certainly performance optimizations that can be made to this approach, but for the frequency with which I am sending data to peers this has worked well enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With