Tuesday, March 25, 2014

Multipeer Connectivity quick tutorial

Multipeer Connectivity quick tutorial


Screen Shot 2013-09-28 at 4.40.44 PMMultipeer Connectivity is a new framework introduced in iOS 7. The framework provides support for discovering nearby devices using either Wi-Fi networks, peer-to-peer Wi-Fi, and Bluetooth personal area networks and communicating with those by sending data, streaming data and resources.
This tutorial will guide you through a very simple chatting app that connect nearby devices and chat to each other. Before coding the first line, let’s take a look at how multipeer connectivity works in iOS 7.
Consider two different users – Alice and Bob, who are using your app and are nearby each other. This is how these users would create a peer-to-peer session:
  1.  Alice (the “advertise”) calls everyone around her: “Hey, I want to connect to you, anybody here?”.
  2. Bob (the “browser”) listens to any call around him, searching for a nearby service to connect to.
  3.  Once Bob finds Alice, he sends her a connection request. “Hello Alice, please connect to me!”.
  4.  Alice accept or reject the request. If she accept the request, a peer-to-peer session is created between the two and they start to exchange data together.
The framework comes with an easy to use API to do all this, including some useful UI to advertise and browse nearby devices, the main classes in multipeer connectivity are:
  •  MCPeerID: represents a peer in a session with custom display name.
  •  MCSession: communicate between connected peer devices. You can create a session and invite other peers to join it, or you can join a session when invited by another peer.
  •  MCNearbyServiceAdvertiser: tell nearby peers that you are willing to join sessions of a specified type.
  •  MCNearbyServiceBrowser: search for nearby devices that are advertising.
  •  MCAdvertiserAssistant: provide same functionality as MCNearbyServiceAdvertiser, along with a standard UI when invitation is sent. If you want to do additional programmatic logic and custom UI when sending invitation, use MCNearbyServiceAdvertiser instead.
  •  MCBrowserViewController: provide standard UI that allows user to search and choose peers to invite.

GETTING STARTED
Because this app is about connecting devices and share data between them, so you must have at least 1 iOS device (along with 1 simulator) to test. Alternatively, you can create a new user on MAC, and run the project on 2 users, but you’ll have to switch user every now and then.
For simplicity,  we will use the standard UI Apple provided for searching and inviting: MCAdvertiserAssistant and MCBrowserViewController. Now open your XCode 5 and go to File/New/Project, choose “single view application” and click “Next”. Name your project “SimpleChat” or whatever you want and click “Next”, choose a Folder to save and click “Create”.
Compile and run the app, you should see a white blank screen:
Screen Shot 2013-09-27 at 4.53.17 PM
Next, I’ll show you how to connect to nearby devices using standard UI. Add each part of this one by one and I’ll explain what exactly does each do.
1.  Add Required Framework
The first thing you have to do when using Multipeer Connectivity framework is, of cause, add it to your project. To add it, click on the “SimpleChat” project in the groups and files tree, switch to “Build Phases” tab and expand the “Link Binary with Libraries” section, click the ” + ” button and select Multipeer Connectivity framework.
Screen Shot 2013-09-27 at 5.02.07 PM

2. Declares properties in ViewController.m
Open file ViewController.m add modify its interface so it looks like this:
This import the header you need to use Multipeer framework, and create instance variable you’ll need. The first 4 vars are needed for advertising, browsing device and inviting nearby device, the last 3 are chatting UI components.
3. Set up UI
Add a method to ViewController.m to setup UI components:
The “setup the browse button” part add a button to the view with a label “Browse”. The next 2 parts add a text box and a chat box which will be used to chat with nearby users.
Then, modify the viewDidLoad method:
Compile and Run the project, you should see:
Screen Shot 2013-09-27 at 5.44.01 PM
4.  Setup Multipeer components
Similarly, add a method called “setUpMultipeer” and call it in ViewController.m:
[UIDevice currentDevice].name return the name of current Device (case simulator, the name is “iPhone simulator”),  so the first line create a new PeerID representing your device with a display name of your device.
The “setup session” line create a session with myPeerID as the local peer
The “setup browser view controller” create a new View Controller with Apple’s standard UI that handles searching for nearby devices and inviting them to session. The serviceType parameter is a short text string used to describe the  app’s networking protocol.  It should be in the same format as a  Bonjour service type: up to 15 characters long and valid characters  include ASCII lowercase letters, numbers, and the hyphen.  A short name that distinguishes itself from unrelated services is recommended; for  example, a text chat app made by ABC company could use the service type ”abc-txtchat”. Right now, just simply put it “chat”.
The final line create a new advertiser that handle telling other devices that you are willing to join them. The discoveryInfo is a NSDictionary containing info you want others to receive right when they found you, you can put it nil for now.
Now compile and run the project and try to tap the browse button, you’ll see … oops! Nothing happened, because no action was setup.
5. Setup some action.
Add an action method in your ViewController.m:
and add this line in the setUpUI method to connect this action with the browser button:
Now run the project once again, you can see that a browse view controller with Apple’s standard UI will be presented when you tap the browse button.
Screen Shot 2013-09-28 at 11.35.35 AM
See the indicator spinning in the Searching cell? MCBrowserViewController automatically  search for nearby devices once it’s presented so you don’t have to do anything. There are 2 buttons “Done” and “Cancel” on top of the controller, purposed to dismiss it when you’re done with browsing and connecting to nearby devices or simply want to cancel the operation. To setup action when “Done” or “Cancel” button are tapped, implement the 2 method of the MCBrowserViewControllerProtocol (which you declared ViewController to adopt earlier):
You also need the set the bowser view controller’s delegate to ViewController, add this line to setUpMultipeer method:
Now when you tap the “Cancel” button, the browser view controller will dismiss and return to view controller.
6. Inviting and Connecting.
Connect your iPhone(or iPad) to your PC and run the project on both simulator and your connected device, try to browse for nearby peer on simulator. It would take about forever for your simulator to discover your iPhone because we’re still missing the “Alice calls everyone around her” part. Browser can only detect device that are advertising that they are willing to join. To do the advertising part, add this line to setUpMultipeer method, right after advertiser’s initialization:
This will get the advertiser to start advertising, quite simple huh? To stop advertising simply call method [self.advertiser stop], but you don’t need to do that in this simple app. Now run project on simulator and your iPhone and browse again, your simulator should detect your device:
Screen Shot 2013-09-28 at 3.03.51 PM
Tap on the device you want to connect, your device should appear an alert message like this:
Screen Shot 2013-09-28 at 3.06.24 PM

Accept it of cause, and that’s it! Your simulator and iPhone are now connected via MCSession.

Next, we’ll get to the sharing data part using MCSession and complete a very simple chat app.
1. Implement UITextFieldDelegate
After connecting complete, all data sharing process is executed by MCSession and MCPeerID. You can forget about MCAdvertiserAssistant and MCBrowserViewController now. MCSession provides several easy-to-use methods to send data to connected peers, the easiest to implement is
This simply send a NSData object to peers in peerIDs array, with 2 modes: reliable (MCSessionSendDataReliable) and unreliable (MCSessionSendDataUnreliable). The reliable mode provide guaranteed reliable and in-order delivery with the cost of slow transfer while the other send data immediately without queuing, no guaranteed delivery. With the small and simple data (short text) in our app, it’s more efficient to choose the unreliable way to avoid traffic. Only consider use reliable mode when data is big like images.
Now imagine the chatting app, we’ll input our text to the chat box then tap ‘send’, the text box from both sender and receiver will appear that text along with sender’s display name. So let’s add a method:
that we’ll modify later and implement the UITextFieldDelegate method:
and set the chat box delegate to view controller in setUpUI method:
so that when you tap the “send” button on the keyboard the method sendText would be called.
2. Handle Text
When user send or receive a message, the message is appear in text box with sender’s display name, so add a method appendText in ViewController.m:

3. Sending data
Implement the sendText method we created earlier:
We retrieve text from chat box, clear chat box, convert text to NSData using a common encoding NSUTF8StringEncoding then send this data to all connected peers, then append the sent message to your own text box. [self.mySession connectedPeers] return a NSArray contain all connected peers to session, in some case you can set another array contain only specific peers you want to send data to.
4. Final Step: Receiving data – MCSessionDelegate
Until now, your app actually sent data and received data, but when receiving data your app does nothing. To get it in action, we need to implement the MCSessionDelegate’s methods.
All 5 methods are required in this protocol so we have to implement them all or we’ll receive complain from compiler. But the only method we’ll actually interact with is
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
which is invoked every time you receive data sent from nearby peer.
don’t forget to set the session’s delegate to view controller, add this line to method setUpMultipeer:
Now your app is able to search for nearby devices, connect to them and sending messages to each other. Try chat to your self, and you’ll see something like this on both simulator and iPhone:
Screen Shot 2013-09-28 at 4.27.44 PM
This is a very simple and far from “qualified” app you’ll create (you don’t even have to create a new single file), but it should give you a quick understanding of how the new framework works. For the full source code, click here. Hope you enjoy this tutorial.
Where to go from here?
So far it seems that we haven’t touched the MCNearbyServiceBrowser and MCNearbyServiceAdvertiser, but actually the two MCBrowserViewController and MCAdvertiserAssistant use them all the time behind the scene. Go ahead and try those lower api classes to set custom UI browser and additional programmatic logic through delegate’s protocols.

No comments:

Post a Comment