Multipeer Connectivity에 의한 iPad간 통신으로 빨리 푸시 버튼을 만들었다

개요



2팀 대항 퀴즈 이벤트를 위해 빠른 푸시 버튼 iOS 앱을 쉽게 구현했습니다.
두 개의 iPad를 사용하여 각 팀이 iPad를 빠른 푸시 버튼으로 사용합니다.

iOS 단말간의 P2P 통신을 가능하게 하는 프레임워크, Multipeer Connectivity를 이용하고 있습니다.
응답 버튼을 누를 때의 시간을 단말간에 통신하여 정확한 타이밍 판정을 실현했습니다.

화면에 나오는 숫자는 점수 카운터입니다.

피 c. 라고 r. 이 m/W5ZC2zw — Bluemo (@blu3mo) March 2, 2020


메커니즘



Multipeer Connectivity는 Bluetooth 등을 이용하여 통신하고 있습니다.

통신 메시지를 받는 데 지연이 있기 때문에 두 가지 가능한 패턴이 있습니다.

각각의 패턴으로 먼저 누른 분을 판정하기 위해서, 이하와 같은 통신이 행해집니다.



1. 한쪽이 다른 쪽보다 압도적으로 빨리 누르면



(아래의 '승리', '패'는 어느 쪽이 먼저 눌렸는지 판단하는 것을 의미합니다.)

빨리 눌러진 쪽의 단말을 A로 했을 경우, 아래의 그림과 같이 됩니다.

1. A는 B에 버튼을 눌렀을 때의 시간을 알려줍니다.

2. B는 버튼이 아직 눌러지지 않았기 때문에 B는 화면에 패배를 표시합니다.

3. 그러나, 이 시점에서는 A단말측은 자신이 이겼는지 어떤지는 모릅니다. 그러므로 B는 잃어버린 것을 표시한 후 A에게 'B가 잃은 것'을 알립니다.

4. A는 그 메시지를 받으면 자신이 이긴 것을 알고 화면에 승리를 표시합니다.



2. 두 팀의 타이밍이 약간 차이가 났을 경우



A 메시지가 발신된 후 도착할 때까지 B를 누르면 다음과 같습니다.

1. A를 누르면 방금전과 같이 B로 눌렀을 때의 시간을 보냅니다.

2. 그것을 B가 받기 전에 B도 눌러지고 B가 눌러졌을 때의 시간을 A에 보냅니다.

3. 그 후, B에게 A로부터의 통신이 도착합니다. B는 자신이 누른 시간과 A가 누른 시간을 비교합니다. 그러면 B는 자신이 잃은 것을 알고 화면에 패배를 표시합니다.

4. 마찬가지로 A에 B로부터의 통신이 도착하면 시간을 비교하여 자신이 이긴 것을 알고 화면에 승을 표시합니다.



구현



전체는 Github에 둡니다.

htps : // 기주 b. 코 m / b 3도 / 쿠이 z 부톤

다음은 MCService.swift의 일부입니다.



빨리 푸시 버튼을 눌렀을 때의 송/수신 주위의 구현은 다음과 같이 되어 있습니다.

메시지는 데이터 형식으로 인코딩하고 상호 작용합니다.




MCService.swift

extension MCService: MCSessionDelegate {

    func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
        // Debug用
        switch state {
        case .connected:
            print("connected: \(peerID.displayName)")
        case .connecting:
            print("connecting: \(peerID.displayName)")
        case .notConnected:
            print("not connected: \(peerID.displayName)")
            //self.state = .open
        }
    }

    func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
        let decodedString = String(data: data, encoding: .utf8)

        var message: Message
        switch decodedString {
        case "youwin":
            message = .youWin
        default: //date
            let date = dateFromString(string: decodedString!, format: dateStringFormat)
            message = .triedDate(date)
        }

        model.reactMessage(message: message)
    }

    func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {

    }

    func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {

    }

    func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {

    }

}

extension MCService: JudgeModelConnectionOutput {

    var isConnected: Bool {
        get {
            return (mcSession.connectedPeers.count == 0)
        }
    }

    func sendMessage(message: Message) {
        var sendingString: String = ""

        switch message {
        case .youWin:
            sendingString = "youwin"
        case .triedDate(let date):
            sendingString = stringFromDate(date: date, format: dateStringFormat)
        }

        do {
            try mcSession.send(sendingString.data(using: .utf8)!, toPeers: mcSession.connectedPeers, with: .reliable)
        } catch {
            print("sending error") //TODO
        }
    }

    func advertise() {
        let mcAdvertiserAssistant = MCAdvertiserAssistant(serviceType: serviceTypeId, discoveryInfo: nil, session: self.mcSession)
        mcAdvertiserAssistant.start()
    }

    func getBrowser() -> UIViewController {
        let mcBrowser = MCBrowserViewController(serviceType: serviceTypeId, session: mcSession)
        mcBrowser.delegate = self
        mcBrowser.maximumNumberOfPeers = 1
        mcBrowser.minimumNumberOfPeers = 1

        return mcBrowser
    }

}



자세한 사양은 Multipeer Connectivity 공식Documentation을 확인하십시오.



운영



실제 이벤트에서는 2대의 iPad를 관객을 향해 설치해, 마우스를 각각에 접속했습니다.

(최근 iPad에서도 마우스를 사용할 수 있도록 되었습니다)

응답자가 마우스를 클릭하면 버튼이 눌린 판정이 됩니다.



비고



· Qiita 첫 투고 & 아마추어이므로 개선점 등이 있으면 알려주세요 🙏

・이번은 2단자간의 통신이 되고 있습니다만, 접속수의 제한을 해제하면 동

제 구조로 3대 이상도 문제 없을 것입니다.

· Multipeer Connectivity에 대해서는 불안정하다는 의견도 존재합니다.

MultipeerConnectivity를 사용할 수 있습니까? by @YearCentury



참고



iOS Swift Tutorial: Transfer Data with the Multipeer Connectivity Framework

htps://w w. 요츠베. 소 m/화 tch?v=H5C4보 6p5Fg



ActionSheet Popover on iPad in Swift

htps : // 메이 m. 코 m / @ ck Mee Han / A c Chionshi t-popo ょ r-on-pa-d-in-su ft-5768d 82094


좋은 웹페이지 즐겨찾기