Skip to main content
미리보기 — 정식 배포가 아닙니다. Flutter SDK 는 평가용으로 제공되며 API 가 바뀔 수 있습니다. 정식 지원 SDK 는 iOS · Android SDK 입니다.
Flutter SDK 는 OneS1ght iOS·Android SDK 를 감싼 플러그인입니다. 측위, 구역 진입·이탈·체류 판정, 전송·재시도는 전부 네이티브 SDK 가 하고, Dart 는 호출을 넘기고 결과를 Dart 타입으로 바꾸기만 합니다. 그래서 앱이 백그라운드로 가 Dart 가 멈춰도 SDK 동작은 네이티브 앱과 같습니다.
Dart API 이름은 iOS SDK 를 따르고, 네이티브 콜백(onZoneEnter·onPosition 등)은 같은 이름의 Stream 입니다.

요구사항

측위가 안 되는 기기에서도 앱은 정상 동작하고 측위만 비활성됩니다. SDK 가 실제로 동작하려면 아래 항목이 먼저 준비되어 있어야 합니다. 자세한 내용은 SDK 설치 전 체크리스트를 참고해 주세요.

설치

pubspec.yaml 에 git 의존성으로 추가합니다. 미리보기라 pub.dev 에는 올라가 있지 않습니다.
ref 에는 태그(v0.0.1) 를 넣어 주세요. main 을 넣으면 저장소가 바뀔 때마다 앱 빌드가 조용히 달라집니다.

iOS 설정

Swift Package Manager 로만 붙습니다. CocoaPods 는 지원하지 않습니다 — 측위 엔진이 동적 프레임워크라 CocoaPods 로는 앱에 실리지 않고, 앱이 실행 즉시 종료됩니다. Swift Package Manager 가 꺼져 있으면 pod install 이 아래 명령을 안내하며 멈춥니다.
iOS 배포 타깃을 18.0 으로 올립니다(ios/Runner.xcodeproj → IPHONEOS_DEPLOYMENT_TARGET). ios/Runner/Info.plist 에 아래 키를 넣습니다. 앞의 세 개가 없으면 권한을 요청하는 순간 앱이 종료됩니다.
NSLocationTemporaryUsageDescriptionDictionary 안의 키는 Positioning 이어야 합니다. 다르면 iOS 가 요청을 오류도 로그도 없이 무시합니다.
iOS 27.2 이상에서는 위치 권한이 ‘항상’ 이어야 층을 찾습니다. NSLocationAlwaysAndWhenInUseUsageDescription 을 넣고, ‘앱 사용 중’ 허용 뒤 앱이 직접 ‘항상’ 을 요청해 주세요(예: permission_handler 의 Permission.locationAlways.request()). SDK 는 ‘항상’ 을 요청하지 않습니다. 이유는 iOS 연동 가이드를 참고해 주세요.
UIBackgroundModes 에 bluetooth-central 은 넣지 마세요. SDK 는 백그라운드에서 측위를 멈춰 이 모드를 쓰지 않고, App Store 심사에서 쓰지 않는 백그라운드 모드(2.5.4)로 거절될 수 있습니다.

Android 설정

MainActivity 를 FlutterFragmentActivity 로 바꿉니다. SDK 의 권한 요청에는 ComponentActivity 가 필요한데, Flutter 기본 FlutterActivity 는 그렇지 않습니다.
android/app/build.gradle.kts 에서 빌드 버전을 맞춥니다.
측위 권한(RANGING·ACCESS_FINE_LOCATION·ACCESS_COARSE_LOCATION·BLUETOOTH_SCAN)과 INTERNET 은 Android SDK 매니페스트에서 자동으로 병합됩니다. 따로 넣지 않습니다.

SDK 초기화

앱 시작 시 한 번 호출합니다. 키 검증과 테넌트 설정 수신을 함께 합니다.
  • 실패하면 OneS1ghtException 을 던집니다 — 다시 호출하면 재시도입니다.
  • 성공 후 다시 호출해도 무시되고, 다른 키로 호출하면 세션을 새로 구성합니다.
  • 기기 지원 여부는 여기서 보지 않습니다. 측위가 안 되는 기기에서도 건물·층·구역 조회는 됩니다.

환경별 API 키 활용법

OneS1ght 콘솔에서는 API 키를 개발용(Development)과 운영용(Production)으로 구분하여 발급할 수 있습니다. 키는 코드에 넣지 말고 빌드할 때 넘기는 것을 권장합니다.

기기 지원 확인

Android 에서는 deviceAvailability() 를 initialize() 다음에 읽어 주세요. 그 전에는 UWB 칩을 확인할 수 없어 deviceNotSupported 가 오고 디버그 로그에 경고가 남습니다. iOS 는 언제 읽어도 됩니다.

권한 요청

  • 이미 답한 권한이면 창 없이 바로 돌아옵니다. initialize 전에도 부를 수 있습니다.
  • iOS 는 Nearby Interaction 권한을 묻고, 위치 권한은 측위를 시작할 때 SDK 가 묻습니다. Android 는 UWB·정밀 위치· 근처 기기 권한을 한 번에 묻습니다.
  • Android 에서 MainActivity 가 FlutterFragmentActivity 가 아니면 코드 unsupportedActivity 오류가 납니다.

프로필 생성 및 연결

  • 속성은 자유롭게 정할 수 있습니다. 나이는 정확한 값 대신 연령대("20s")를 권장합니다.
  • 로그아웃 등으로 연결을 끊을 때는 identify(profileId: null) 을 호출합니다.
  • 조회·교체·삭제: fetchProfile(id) · replaceProfile(id, attributes: …)(전체 교체) · deleteProfile(id).

건물·층 선택 (선택)

setFloorMap 을 부르지 않으면 측위 엔진이 BLE 로 층을 찾습니다. 처음 지정할 때는 buildingId 를 함께 넘겨 주세요 (없으면 E3001). setFloorMap(null) 은 층 지정을 비웁니다.

엔진이 찾은 층 따라가기

도면 표시

floors() 목록에는 도면 이미지가 비어 있습니다. 지도를 그릴 층만 floor(buildingId:, floorId:) 로 받으면 image(원본 바이트)가 채워져 옵니다. 좌표는 도면 로컬 미터이며 originX·originY·widthM·heightM 으로 화면 좌표로 바꿉니다.

측위 시작과 종료

begin() 이 실패하면 OneS1ghtException 을 던집니다 — E1001(초기화 안 함) · E1004(identify 안 함) · E2001(OS 낮음) · E2002(기기 미지원).

일시정지와 재개

측위가 닫혔을 때

이벤트 수신

이벤트는 모두 Stream 입니다. 여러 곳에서 동시에 들어도 됩니다.

구역정보 업데이트

콘솔 변경 수신

SDK 는 이 신호로 아무것도 하지 않습니다. 구역을 다시 받을 때마다 진출입 판정이 처음부터 시작되므로, 연달아 오는 ZonesChanged 는 접어서 한 번만 처리해 주세요.

데이터 전송 제어

세션 재설정

오류 처리

모든 실패는 OneS1ghtException 입니다. code 는 네이티브 SDK 의 에러 코드이며 iOS·Android 가 같습니다.

디버그 로그

로그 등급과 해석은 로그 사용법을 참고해 주세요. 운영 빌드에서는 구독하지 않는 것을 권장합니다. SDK 로그·안내 문구의 언어는 OneS1ght.setLanguage('ko') 로 지정할 수 있습니다('ko'·'ja'·'en', null 이면 기기 언어).

백그라운드 동작

UWB 측위는 iOS·Android 모두 포그라운드 전용입니다. 앱이 백그라운드로 가면 네이티브 SDK 가 측위를 멈추고 남은 좌표를 전송합니다. 이 동작은 Dart 가 아니라 네이티브 SDK 가 하므로 Flutter 앱에서도 같습니다.
실제 측위는 시뮬레이터·에뮬레이터에서 확인할 수 없습니다. UWB 를 지원하는 실기기에 설치하여 테스트해 주세요.

네이티브 SDK 와 다른 점

문제 해결하기

로그 사용법

개발 중 로그 사용법을 안내합니다.

에러 코드 안내

개발 중 발생하는 오류 내용을 안내합니다.