Help us understand the problem. What is going on with this article?

iOSでBluetooth通信するサンプルコード

More than 3 years have passed since last update.

概要

  • iPhoneでBluetooth通信を動かしてみたかったので、かんたんなサンプルを書いてみました
  • 基本的に、MultipeerConnectivityで用意されている各クラスの初期化とデリゲートの実装だけ行えば、簡単にBluetooth通信ができました

つくったもの(Bluetooth通信のサンプル)

  • 画面をタップすると、自分の端末に円がアニメーション表示されます
  • Bluetooth通信で座標を送り、相手の端末にも同じ円が表示します
  • 長押しで円がでかくなります
  • スプラトゥーン風にしたかったのですが、だいぶコレジャナイ

sample.png

サンプルコード

  • BluetoothGameSample
    • (エラー処理などいろいろ足りないです。とりあえずのサンプルになってます)

実行時の注意

  • 端末のBluetooth設定をONにする必要があります(「設定」アプリ > Bluetooth > オン)
  • アプリ起動すると、周囲に同じアプリが起動していないか探しに行きます(60秒タイムアウト)
  • Bluetooth通信はシミュレータでは試せないようです

要点

0.使用したクラスについて

  • 参考サイトにもあるように、MCBrowserViewControllerを使うと簡単に接続先の選択~接続の確立までをUI付きで提供してくれます。
  • ただ、今回は接続先の 選択画面を挟みたくなかった ので、MCBrowserViewControllerの代わりにMCNearbyServiceBrowserを使用し、最初に見つけた端末に即接続しに行っています

1.Bluetooth通信準備

  • サンプルではちょっと処理を加えていますが、Bluetooth通信に最低限必要な初期化処理は以下のはず。
  • MCNearbyServiceAdvertiserMCNearbyServiceBrowserの役割については、参考サイトの招待状の例えがわかりやすかったです
    func initialize() {
        self.peerID = MCPeerID(displayName: UIDevice.currentDevice().name)
        self.session = MCSession(peer: peerID)
        self.session.delegate = self

        self.advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: serviceType)
        self.advertiser.delegate = self
        self.advertiser.startAdvertisingPeer()

        self.browser = MCNearbyServiceBrowser(peer: peerID, serviceType: serviceType)
        self.browser.delegate = self
        self.browser.startBrowsingForPeers()
    }
    // MARK: - MCNearbyServiceAdvertiserDelegate
    func advertiser(advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: NSData?, invitationHandler: (Bool, MCSession) -> Void) {
        invitationHandler(true, self.session);
    }
    // MARK: - MCNearbyServiceBrowserDelegate
    func browser(browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
        self.browser.invitePeer(peerID, toSession: session, withContext: nil, timeout: 60)
    }

2.データの送信

  • ViewControllerのタッチイベントで、「相手端末への座標の送信」と「自分の座標への円の描画」を行っています
  • 以下はデータ送信部分
NearbyManager.swift
    func sendMessage(point : PointModel) {
        do {
            let data = NSKeyedArchiver.archivedDataWithRootObject(point)
            try self.session.sendData(data,
                toPeers: self.session.connectedPeers,
                withMode: MCSessionSendDataMode.Unreliable)
        } catch {
            print(error)
        }
    }

3.データの受信

  • 受け取った座標データに従って、相手の円を描画しています
  • 以下はデータ受信部分
NearbyManager.swift
    // MARK: - MCSessionDelegate
    func session(session: MCSession, didReceiveData data: NSData,
        fromPeer peerID: MCPeerID)  {
            dispatch_async(dispatch_get_main_queue()) {
                let point = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! PointModel
                self.canvasVC?.paintEnemyPuddle(point)
            }
    }

まとめと課題

  • MultipeerConnectivityで用意されている各クラスのデリゲートを実装すれば、Bluetooth通信は簡単に実装できる
  • いろいろ考慮が足りていないので、実際に使うとなるといろいろ手を入れる必要がありそう
    • この実装だと通信のタイムラグで2端末間の表示にズレが出ることがあるので、少なくともユーザのアクションの実行時間はデータとして持たせる必要がある
    • エラー処理全般を入れていないので、相手が遠く離れた時やアプリを終了したときなど対応が必要
    • 上記に関連するが、状況によってデータが相手に届かないことがある。ロストしたデータのフォローも必要

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away