메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

스위프트(Swift)와 함께하는 iOS8의 멀티피어 연결

한빛미디어

|

2014-11-27

|

by HANBIT

21,839

제공 : 한빛 네트워크
저자 : Paris Buttfield-Addison
역자 : 이도행
원문 : Multipeer Connectivity on iOS 8 with Swift

디바이스들이 서로 서로를 발견하고, 연결하고, 데이터 보내기

Hand Set 멀티피어 연결성(Multipeer Connectivity)은 서로를 연결하고, 식별하는 서비스면서, 매우 쉽고, 최소한의 설정만으로 데이터 보내기/받기를 허락한다. 만약에 여러분이 Bonjour와 비슷하다고 생각하는 중이라면, 그게 맞다. 하지만, Bonjour는 디바이스를 발견하는 서비스이지, 연결과 전송을 위한 건 아니다. 멀티피어 연결성은 모든 것을 하나의 깔끔한 패키지로 다룬다.

멀티피어 연결성은 몇 개의 다른 컴포넌트로 구성되어 있지만, 응용 프로그램이 요구하는 그들의 서비스를 연결을 사용 할 수 있는 것들에만 알림으써 동작한다. 서비스 브라우져는 이러한 알림을 듣고, 디바이스들 사이에 연결을 생성하도록 요청 할 수 있다. 만약에 연결이 승인되면, 세션 내부의 모든 건 피어 오브젝트로 표현된 세션이 생성된다.

이러한 과정을 보여주기 위해, 스위프트(애플의 새로운 언어)를 이용한 간단한 채팅 프로그램을 하나 만들어 볼 것이다.

이 실습은 iOS8에 의해 쓰여졌지만, OS X에서도 멀티피어 연결성 프레임워크는 동작한다.

1. 새로운 Single View iPhone 애플리케이션을 만들고, MultipeerChat이라 이름을 짓자.

2. 프로젝트 네비게이터(Project navigator)에서 프로젝트를 열고, 이 프로젝트에 Linked Frameworks and Libraries 에 있는 MultipeerConnectivity 프레임워크를 추가하자.

3. Main.storyboard를 열고, UITextView를 추가하자. 대부분의 공간을 차지하게 만들고, 속성 편집기(Attributes Inspector)에서 editable 필드를 false로 지정하자.

4. UITextField를 추가하고, 2개의 버튼을 추가한다. 버튼의 이름은 "Browse" 와 "Send"로 지정하자.

5. UITextView는 chatView 프로퍼티와 연결하자.

6. UITextField는 messageField 프로퍼티와 연결하자.

7. Browse 버튼은 showBrowser 액션과 연결하고, Send 버튼은 sendChat 액션과 연결하자.

완료 되었으면, 여러분의 인터페이스는 아래와 비슷 할 것이다.



이제, ViewController를 다음과 같이 수정하자.
import UIKit
import MultipeerConnectivity

class ViewController: UIViewController, MCBrowserViewControllerDelegate,
    MCSessionDelegate {
    
    let serviceType = "LCOC-Chat"
    
    var browser : MCBrowserViewController!
    var assistant : MCAdvertiserAssistant!
    var session : MCSession!
    var peerID: MCPeerID!

    @IBOutlet var chatView: UITextView!
    @IBOutlet var messageField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.peerID = MCPeerID(displayName: UIDevice.currentDevice().name)
        self.session = MCSession(peer: peerID)
        self.session.delegate = self
        
        // viewcontroller 브라우저를 고유 서비스 이름으로 생성한다.
        self.browser = MCBrowserViewController(serviceType:serviceType,
            session:self.session)
        
        self.browser.delegate = self;
        
        self.assistant = MCAdvertiserAssistant(serviceType:serviceType,
            discoveryInfo:nil, session:self.session)
        
        // 우리의 엄청난 챗을 알리기 위해 assistant를 start 한다.
        self.assistant.start()
    }
    
    @IBAction func sendChat(sender: UIButton) {
        // 메시지 필드에 있는 걸 텍스트로 감싸고, 모두에게 보낸다. 
        // 피어들은 연결 되어 있다.
        
        let msg = self.messageField.text.dataUsingEncoding(NSUTF8StringEncoding,
            allowLossyConversion: false)
        
        var error : NSError?
        
        self.session.sendData(msg, toPeers: self.session.connectedPeers,
            withMode: MCSessionSendDataMode.Unreliable, error: &error)
        
        if error != nil {
            print("Error sending data: (error?.localizedDescription)")
        }
        
        self.updateChat(self.messageField.text, fromPeer: self.peerID)
        
        self.messageField.text = ""
    }
    
    func updateChat(text : String, fromPeer peerID: MCPeerID) {
        // Chat view에 텍스트를 추가한다.
 
        // 만약에 peerId가 현재 장치의 아이디와 같으면, 이름은 "Me"로 보여준다.
        var name : String

        switch peerID {
        case self.peerID:
            name = "Me"
        default:
            name = peerID.displayName
        }
        
        // 보여줄 때, 메시지에 이름을 추가한다.
        let message = "(name): (text)
"
        self.chatView.text = self.chatView.text + message
    }
    
    @IBAction func showBrowser(sender: UIButton) {
        // browser view controller를 보여준다.
        self.presentViewController(self.browser, animated: true, completion: nil)
    }
    
    func browserViewControllerDidFinish(
        browserViewController: MCBrowserViewController!)  {
        // browser view controller 가 dismisse될 때 불린다. (즉 Done 버튼이 눌리면)
        
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    
    func browserViewControllerWasCancelled(
        browserViewController: MCBrowserViewController!)  {
        // browser view controller 가 Cancel될 때 불린다.
        
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    
    func session(session: MCSession!, didReceiveData data: NSData!,
        fromPeer peerID: MCPeerID!)  {
        // 피어가 NSData를 우리에게 보낼 때 불린다. 
        // 메인큐로 동작 될 필요가 있다.
        dispatch_async(dispatch_get_main_queue()) {
            
            var msg = NSString(data: data, encoding: NSUTF8StringEncoding)
            
            self.updateChat(msg, fromPeer: peerID)
        }
    }
    
    // 이건 아무것도 하지 않지만, MCSessionDelegate protocol은 이게 구현 되길 요구한다.
    func session(session: MCSession!,
        didStartReceivingResourceWithName resourceName: String!,
        fromPeer peerID: MCPeerID!, withProgress progress: NSProgress!)  {
            
        // 우리에게 피어가 파일 보내기를 시작 했을 때 불린다.
  }
    
    func session(session: MCSession!,
        didFinishReceivingResourceWithName resourceName: String!,
        fromPeer peerID: MCPeerID!,
        atURL localURL: NSURL!, withError error: NSError!)  {
        // 다른 사용자들에게 파일 전송이 끝 났을 때 불린다.
    }
    
    func session(session: MCSession!, didReceiveStream stream: NSInputStream!,
        withName streamName: String!, fromPeer peerID: MCPeerID!)  {
        // 피어가 우리와 스트림(stream)이 구성 되었을 때 불린다.
    }
    
    func session(session: MCSession!, peer peerID: MCPeerID!,
        didChangeState state: MCSessionState)  {
        // 연결된 피어의 상태가 변할 때 불린다. (예를들어, 오프라인 상태로 들어갔다.)
    }
}
이 코드는 다음과 같이 동작한다.

1. ViewController 클래스의 MCBrowserViewControllerDelegate와 MCSessionDelegate 프로토콜로 지정한 확장 클래스를 추가하고, 이에 Multicast Peer 컴포넌트를 다루는 하나를 포함한 4개의 프로퍼티를 추가하여 생성한다.
  • MCBrowerViewController는 연결을 취급하고, 브라우징을 성사시키기 위한 미리 빌드된 view controller이다.

  • MCAdvertiserAssistant는 알림과 접속 및 세션 생성을 성사시키기 위한 또 다른 미리 빌드된 클래스이다.

  • MCSession은 성사된 세션에 고정되는 오브젝트이다.

  • MCPeerID는 여러분의 세션에 대한 peer ID를 의미한다.
2. viewDidLoad 메소드 안에 코드는 adveritser가 알람을 하기 전에, 모든 멀티캐스트 피어 오브젝트를 초기화한다.

3. sendChat 메소드에서, 세션의 sendData(topers:error) 메시지는 이 애플리케이션의 알맹이이다. 이 애플리케이션에서 이 메소드는 텍스트 필드로부터, 문자열 데이터를 보내는데 사용되는 방법이다.

4. 마지막으로, session(didReceiveData:fromPeer:)는 위임된 메소드고, 이 애플리케이션에서는 세션이 어떤 데이터를 받건 불리게된다. 이는 텍스트 뷰에 새로운 데이터를 추가하고, 텍스트 뷰에 받은 텍스트를 보여준다.

이제, 여러분과 여러분의 다른 친구(혹은 당신의 서로 다른 기기 2개)와 이 애플리케이션을 실행해보자, 여러분은 매우 놀랄만한 채팅앱을 가지게 될 것이다.
TAG :
댓글 입력
자료실

최근 본 책0