그다지 많이 소개되지 않은 Couchbase Lite의 멋진 기능 중 하나는 두 장치 간에 P2P 복제를 수행할 수 있는 기능입니다. Couchbase Lite에는 애플리케이션이 Couchbase Lite를 실행하는 다른 기기에서 HTTP 연결을 수락하고 데이터를 동기화할 수 있는 Couchbase Lite 리스너라는 추가 구성 요소가 패키지로 포함되어 있습니다.

몇 달 전, 웨인 카터(모바일 수석 아키텍트)와 트라운 레이든(안드로이드 엔지니어)이 저에게 스카이프를 통해 간단한 P2P 사진 공유 앱을 만들 수 있는 아이디어를 제안하면서 Couchbase Lite를 사용하여 P2P 애플리케이션을 얼마나 쉽게 개발할 수 있는지 보여줬습니다. 그 이후로 저는 며칠 동안 PhotoDrop이라는 작은 P2P iOS 사진 공유 앱을 만들었습니다. 이 블로그 게시물에서는 Couchbase Lite를 사용하여 애플리케이션을 개발한 방법을 보여드리겠습니다. 마지막에는 이렇게 완성하게 될 것입니다:

개요

PhotoDrop은 여러 디바이스 간에 사진을 전송하는 데 사용할 수 있는 iOS AirDrop 기능과 유사한 P2P 사진 공유 앱입니다. 코드를 살펴보기 전에 애플리케이션을 개발할 때 고려했던 P2P 관련 사항과 디자인 선택에 대해 간략히 설명하겠습니다.

피어 검색 는 여러 가지 방법으로 수행할 수 있습니다. iOS에서는 봉쥬르 서비스를 사용하여 동료를 검색할 수 있지만 나중에 다른 플랫폼에서 애플리케이션을 개발하려는 경우 문제가 될 수 있습니다. PhotoDrop에서는 QR코드를 사용하여 더 간단하고 직접적인 방법을 사용하고 있습니다. 발신자가 사진을 스캔하여 전송할 수 있는 임시 엔드포인트 URL을 광고하는 데 QR코드를 사용합니다.

피어 신원 는 피어 디스커버리와 관련된 주제입니다. 피어 식별은 일반적으로 사용자 등록, 사용자 로그인, 피어 승인과 같은 원치 않는 단계를 애플리케이션에 도입하지 않으면 해결하기가 어렵습니다. QR코드를 사용하고 두 사람이 직접 명시적으로 상호 작용하여 사진을 주고받도록 요구함으로써 이 문제를 완화할 수 있습니다.

인증 는 액세스 제어(이 경우 사진을 다른 사용자의 데이터베이스에 푸시하는 쓰기 액세스 권한)가 올바른 사람에게 부여되도록 하기 위해 필요합니다. PhotoDrop에서는 Couchbase Lite에서 이미 지원하던 기본 인증을 사용하고 있습니다. 일회성 사용자 이름과 비밀번호를 안전하게 생성하고 URL 엔드포인트와 함께 번들로 묶은 다음 수신자가 발신자에게 제시하는 QR코드로 모두 인코딩합니다. 발신자가 QR코드를 스캔하면 발신자는 기본 인증을 위한 사용자 아이디와 비밀번호를 갖게 됩니다.

안전한 커뮤니케이션 채널 는 특히 민감한 정보를 전송할 때 필요합니다. 이 앱에서는 보안 통신을 구현하지 않았습니다. 하지만 최근 Jen Alfke는 자체 서명된 인증서를 즉시 생성하는 API를 포함한 TLS 지원을 iOS Couchbase Lite 리스너에 추가했습니다. 모든 작업이 완료되었으므로 이에 대한 지원을 매우 쉽게 추가할 수 있습니다.

결국, 포토드롭의 현재 흐름은 매우 간단합니다. 친구에게 공유할 사진을 선택하고 QR코드 스캐너를 열어 선택한 사진이 전송될 대상 엔드포인트를 스캔합니다. 다른 쪽에서 친구는 애플리케이션을 열고 QR코드를 보여주며 사진을 스캔하고 전송할 때까지 기다립니다. 다음 섹션에서는 애플리케이션에 대한 모든 구현 세부 정보를 제공합니다.

사진 선택

여러 사진 선택을 지원하지 않는 UIImagePickerViewController 때문에 PhotoDrop은 ALAssetsLibrary를 사용하여 iOS 디바이스의 카메라 롤 앨범에 있는 사진에 액세스합니다.

사진은 UICollectionViewController에 표시됩니다. 사진 썸네일과 사진의 선택된 상태를 나타내는 확인란을 표시하기 위해 PhotoViewCell이라는 간단한 사용자 지정 UICollectionViewCell이 만들어집니다.

사진 보내기

선택한 사진을 전송할 준비가 되어 전송 버튼을 터치하면 SendViewController에 선택한 사진이 표시됩니다.

SendViewController가 표시되면, DatabaseUtil 클래스에서 "db"라는 빈 데이터베이스 객체를 가져오는 viewDidLoad() 함수가 나타납니다. 새 데이터베이스를 가져오는 이유는 이전 공유 세션에서 보류 중인 문서가 없는지 확인하기 위해서입니다.
DatabaseUtil 클래스의 getEmptyDatabase() 함수는 데이터베이스가 있는 경우 삭제하고 새 데이터베이스를 다시 생성하여 주어진 이름의 빈 데이터베이스를 반환합니다.

SendViewController가 표시되면 viewDidAppear(animated:Bool) 함수에 들어갑니다. viewDidAppear 함수에서 AVFoundation의 QRCode 캡처 세션을 시작하여 QRCode 스캐너를 표시합니다.

QR코드를 캡처하면 사진을 전송할 원격 URL인 엔드포인트 URL을 추출합니다. 사진 문서를 생성하고 전송하는 핵심 코드는 약 50줄의 코드가 있는 replicate(url: NSURL) 함수에서 시작하고 끝납니다.

코드는 공유자산 배열의 각 사진을 루핑하는 것으로 시작합니다. 각 사진에 대해 바이너리 표현을 가져와 빈 Couchbase Lite 문서에 첨부합니다.

사진 문서 생성이 끝나면 해당 문서를 다른 장치로 보냅니다. 이를 위해 푸시 리플리케이터를 만들고 리플리케이트할 문서의 ID를 설정합니다. 일반적으로 복제기에 대한 문서 ID 설정은 선택 사항입니다. ID를 제공하지 않으면 복제기는 데이터베이스에 있는 모든 문서를 그냥 복제합니다.

복제기를 시작하기 전에 복제 상태를 관찰하는 알림 옵저버를 설정하여 복제가 진행 중일 때 복제 상태를 적절하게 표시할 수 있도록 합니다.

사진 받기

사진 수신은 사용자가 수신 버튼을 터치하면 ViewController 화면에서 표시되는 ReceiveViewController에서 수행됩니다. ReceiveViewController가 표시되면 viewDidLoad() 메서드에서 "db"라는 이름의 새 데이터베이스를 가져옵니다. viewDidAppear(animated: Bool) 함수에서 startListener()를 호출하여 CBLListener 객체를 생성하고 시작합니다. CBLListener는 HTTP 요청을 수신하고 해당 요청을 적절한 핸들러로 라우팅하여 복제 작업을 수행하는 임베디드 경량 HTTP 서버입니다. 리스너가 시작되면 리스너의 URL을 가져와 URL을 인코딩한 QR코드를 제공할 수 있습니다. 보너스로, iOS CoreImage는 QRCode 필터를 지원하므로 QRCode 이미지를 생성하는 것이 매우 쉽습니다.)

startListener()에서 리스너를 설정할 때 생성된 사용자 아이디/비밀번호 쌍으로 기본 인증을 사용하도록 설정합니다. 생성된 사용자 아이디/비밀번호 쌍은 권한이 없는 사용자가 수신자에게 이미지를 푸시하는 것을 방지하는 안전한(충분한) 솔루션을 제공하는 일회성 쌍으로 사용됩니다. 사용자 아이디와 비밀번호를 생성하기 위해 암호학적으로 안전한 임의의 값을 생성하는 iOS 무작위화 서비스 API(SecRandomCopyBytes)를 사용합니다.

startListener() 함수가 끝나면 startObserveDatabaseChange() 함수가 호출되어 kCBLDatabaseChangeNotification이라는 알림을 통해 데이터베이스에 발생하는 모든 변경 사항을 관찰합니다. 이제 다른 디바이스의 사진 문서가 언제 복제되는지 관찰하고 디바이스의 카메라 롤에 사진을 저장할 수 있습니다.

사진을 기기의 카메라 롤에 저장하는 함수는 다음과 같습니다. 이 함수는 문서 첨부 파일에서 이미지를 가져와서 CGImage를 생성한 다음 ALAssetsLibrary의 writeImageDataToSavedPhotosAlbum() 함수를 통해 카메라 롤에 저장하기만 하면 됩니다. 사진을 저장하면 화면에 썸네일이 표시됩니다.

마무리

PhotoDrop 앱을 개발하는 방법에는 여러 가지가 있으며, Couchbase Lite를 사용하는 것이 가장 쉬운 방법 중 하나일 것입니다. 사진 송수신을 위한 핵심 코드는 100줄에 불과하며 네트워크 통신과 직접 관련된 코드는 0줄도 포함되어 있지 않습니다. 이 블로그 게시물과 PhotoDrop 애플리케이션 자체가 P2P 애플리케이션에 Couchbase Lite를 사용하기 위한 영감과 아이디어를 제공해 주었으면 합니다. 복제 포토드롭 깃허브 리포지토리를 클릭하고 플레이해보고 의견을 알려주세요!

작성자

게시자 파신 수리엔트라콘, 수석 소프트웨어 엔지니어, Couchbase

파신 수리엔트라콘은 Couchbase 모바일의 선임 소프트웨어 엔지니어입니다. 이전에는 오라클에서 엔지니어로 근무하며 오라클 세일즈 클라우드 iOS 및 안드로이드 애플리케이션용 모바일 사용자 인터페이스 렌더링 프레임워크 개발을 주도했습니다.

댓글 하나

  1. 감사합니다, 좋은 글입니다! 블루투스를 사용하여 여러 장치에서 복제를 동기화 할 수 있습니까 (예 : 멀티 피어 연결 프레임 워크 (일부 안정성 문제가 있음) 등)? 더 이상 와이파이가 필요없을 정도로~!

    1. 파신 수리엔트라콘 2월 17, 2015에서 6:55 오후

      봉쥬르를 사용하면 블루투스를 통해 P2P 복제를 할 수 있습니다. 멀티피어 커넥티비티 프레임워크는 봉쥬르 위에 구축된 프레임워크이므로 이를 사용하여 앱을 다시 빌드할 수 있습니다. 한 가지 아쉬운 점은 봉쥬르와 멀티피어 커넥티비티는 모두 크로스 플랫폼이 아니라는 점입니다.

      1. 멀티피어 연결 프레임워크에서 URL을 어떻게 얻나요? 내가 알기로는 CBLListener에서 사용할 수없는 MCPeerID(displayName myDisplayName : 문자열)만 얻을 수 있습니까? iOS 멀티피어 연결 프레임워크를 사용하여 복제 앱을 구축하는 방법에 대해 알고 싶습니다.

  2. 이를 안드로이드에서도 구현할 수 있으면 좋겠습니다.
    또한 용량 테스트를 해보셨나요?

    1. 파신 수리엔트라콘 2월 17, 2015에서 7:52 오후

      앱을 Android 플랫폼으로 포팅할 계획이 있는데, Android와 Xamarin 플랫폼 중 어느 것을 먼저 해야 할지 고민 중입니다. 아직 공식적인 성능 테스트나 프로파일링을 해본 적이 없습니다. 일반적으로 이 앱은 합리적인 시간 내에 10장 이상의 원시 사진을 전송하는 등 일반적인 용도로는 꽤 잘 작동하는 것 같습니다.

      1. Android/Xamarin에서 이 기능을 사용할 수 있나요? Xamarin Android 태블릿 앱용 카우치베이스에 관심이 있는데 이 기능이 필요합니다.

        1. 제임스 노센티니 6월 9, 2015에서 7:03 오후

          안녕하세요 제레미, 여기 Android용 PhotoDrop 버전이 있습니다. https://github.com/couchbasela….

          1. 안녕하세요 @James 링크가 작동하지 않습니다. 링크를 공유해 주시고 업데이트해 주세요.

  3. 폰갭/코도바에서도 이 기능이 작동했으면 좋겠어요. 아직 시도해 본 사람을 알고 있나요? 안드로이드나 자마린 데모 이후에 사용해 볼 계획이 있으신가요?

    1. 파신 수리엔트라콘 6월 9, 2015에서 5:37 오후

      폰갭/코도바 버전은 아무도 작업하지 않은 것 같습니다. Xamarin 버전은 계획이 있지만 현재 CBL Xamarin 플랫폼의 P2P 구성 요소는 아직 진행 중입니다. CBL Xamarin P2P 복제의 진행 상황은 포럼(https://forums.couchbase.com/c.... 보든(짐 보든)이 이에 대한 통찰력을 제공할 수 있습니다.

댓글 남기기