LoginSignup
85
90

More than 5 years have passed since last update.

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

Posted at

概要

  • 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端末間の表示にズレが出ることがあるので、少なくともユーザのアクションの実行時間はデータとして持たせる必要がある
    • エラー処理全般を入れていないので、相手が遠く離れた時やアプリを終了したときなど対応が必要
    • 上記に関連するが、状況によってデータが相手に届かないことがある。ロストしたデータのフォローも必要

参考

85
90
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
85
90