18

I'm working on a project that uses MC framework as a communication channel, and after some tests I have the perception that this channel is somehow unstable to rely on.

I've been following Apple's documentations and videos in order to use the framework properly, but happens that:

  • peers get disconnected kinda' often after paired, and even more ofter if I pair more than one peer.
  • some data packages have mixed data

Is there any kind of recommendation to work with the framework? i.e:

  • Specific project settings? (i.e: is there something in the capabilities section that needs to be enabled?)
  • Multithreading restrictions? (i.e: always call mc methods from the same thread)
  • Restrictions in terms of the amount of data to be sent?

I found this link that mentions something about the framework not performing ok under stress. That's the kind of advice I'm looking for :).

For the record:

  • I'm using an implementation based on this post since Apple's project is not working for me.
  • I'm using only one MCSession for all peers I try to pair with
  • Encryption preference is set to MCEncryptionNone
  • Using sendData: and sendResourceAtURL: to communicate with peers.
Community
  • 1
  • 1
Omer
  • 5,470
  • 8
  • 39
  • 64
  • 3
    Given how crappy AirDrop performs, and how I can barely ever get it to work, even on a brand new MacBook Pro and iPhone 6S Plus... I think this is just broken crap and Apple should be ashamed. It's like when iCloud first rolled out, any of us who tried to use that document syncing garbage, it was like jumping into a wood chipper legs first. – CommaToast Jan 12 '16 at 05:40
  • I read somewhere that when browsing/advertising peers aren't done on same device at the same time, it increases stability. In my app, only my Master device browses for peers, and my Slaves advertise, and it seemed to reduce a bit connection delay, and lowered disconnections. Hope that helps. – Thibaud David Jan 12 '16 at 10:01
  • "just use PubNub" :/ – Fattie Jan 13 '16 at 03:08
  • I once attended a special iOS session hosted by Apple and had a chance to talk about AirDrop with one of their engineers. Because of how it doesn't "Just Work", I jokingly said to him: "Tell me the truth: you guys didn't develop AirDrop yourselves, you must have acquired it from Microsoft!". He denied, embarrassingly. – Nicolas Miari Jan 13 '16 at 04:20
  • @CommaToast Airdrop is very slow - I think they're working around the issue of too much data killing the connection by throttling it. – DavidA Jan 13 '16 at 09:14

2 Answers2

3

I'm using the MC framework in a game and have found a few workarounds for its apparent instability:

1) I use a "keep alive" transaction sent every 15 seconds to maintain activity on the links. I found that this resolves almost all the connection losses I was experiencing.

2) I dispatch all processing triggered by data reception to the main thread and never carry any MCPeer nor MCSession objects between threads (except for the initial connection protocol). I also did that to minimize the time spent in the data reception code so that the thread used by MC regains control as fast as possible (which I also found was a source of some disconnects). I do not apply this rule for sending data (only when receiving)

3) I have NOT found a clean solution to the repetition of peers that appears when trying to establish a connection (both using the standard UI and my own). So far comparing MCPeer IDs to avoid duplicates only seems to remove some of the duplication. Also, it seemed that using the same MCSession for advertising (MCAdvertiserAssistant) and connecting to peers caused some conflicts so i'm using a new, separate MCSession instance every time I start the assistant.

Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • Hey, thanks you. About the threads, that's true, there is a hint on the documentation. About 2 & 3 I'll try that to see if it improves stability. Cheers – Omer Jan 13 '16 at 21:38
  • Hi, little late, but what do u mean by "keep alive" transaction. Does it mean u keep send and recieve some data every 15 secs in order to keep session alive? or something else? – Ammar Mujeeb Apr 03 '22 at 10:42
  • Yes. Based on the assumption that an inactive connection eventually closes itself (or gets cancelled somehow), it is a string sent over the link that performs no action on the receiving end but serves to prevent the connection from closing by "simulating" activity. – Alain T. Apr 03 '22 at 14:58
2

I'm using it in an app that transfers a large quantity of data regularly. A couple of workarounds have helped:

  • As soon as the connection to a peer is established, set up an NSOutputStream/NSInputStream pair to use for communication. Don't use the send data or send resource methods in the multipeer connectivity framework at all.

  • If an unexpected disconnect occurs, the state of the MCSession object cannot be trusted - tear it down and start again from scratch. UPDATE: An unexpected disconnection here is either of the streams being closed by the other end of the connection.

  • Prompt your user to check that all devices are on the same WiFi access point. If the peers are on the same network segment, but a different Wifi the browsers will see the advertisers and be able to connect, but will disconnect a few seconds later.

Update:

To establish an output stream:

-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
    switch(state)
    {
        // ...

        case MCSessionStateConnected:
            outputStream = [session startStreamWithName:@"Stream" toPeer:peerID error:&error];
            // Setup a stream handler for the stream and open it
            break;
        // ...
    }
}

To establish an input stream, implement this method is MCSessionDelegate:

-(void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID
{
    // Setup a stream handler for the stream and open it
}

This will get called as the other end of the connection opens it's output stream.

Now you have two streams ready to use for bi-directional communication.

DavidA
  • 3,112
  • 24
  • 35
  • Thank you for your time, couple of points: • any link of how to use `NSStream` with MC the right way? I have an implementation currently, but not sure it is correct. • What do you mean by "unexpected error occurs"? how to identify the scenario a session is corrupt? – Omer Jan 13 '16 at 21:28