> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ones1ght.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Flutter SDK

> SDK Version 0.0.3 (Preview)

## 패키지 선언

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
import 'package:ones1ght_sdk/ones1ght_sdk.dart';
```

## 초기화

### .initialize

OneS1ght API 키로 측위엔진을 초기화합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.initialize(sdkKey: 'YOUR_SDK_KEY');
```

### .requestPermission

측위엔진 사용을 위한 앱 권한을 요청합니다.

| 결과 | 뜻 |
| - | - |
| `authorized` | 측위 가능 |
| `denied` | 권한 거부됨 |
| `unsupported` | 측위 미지원 기기 |

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final status = await OneS1ght.requestPermission();
```

### .setLanguage

SDK 로그 문구 언어를 설정합니다.<br />
`ko` : 한국어,  `ja` : 일본어,  `en` : 영어, `null` : 시스템 설정 언어

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.setLanguage('ko');
```

### .onDebugLog

SDK 로그를 수신합니다.<br />
`ko` : 로그 레벨, `message` : 로그 메세지

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
OneS1ght.onDebugLog.listen((log) => debugPrint('[OneS1ght] ${log.level} ${log.message}'));
```

### .reset

로케이터의 세션을 초기화합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.reset();
```

## 상태 조회

### .isInitialized

초기화 성공 확인 여부를 반환합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final ready = await OneS1ght.isInitialized();
```

### .deviceAvailability

측위 가능 기기를 판별하고 미지원시 사유를 반환합니다.

| 값 | 뜻 |
| - | - |
| `available` | 측위 가능 |
| `osVersionTooLow` | iOS 27 · Android 17(API 37) 미만 |
| `deviceNotSupported` | UWB 미지원 기기 |

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
switch (await OneS1ght.deviceAvailability()) {
  case DeviceAvailability.available:
    break;
  case DeviceAvailability.osVersionTooLow:
    break;
  case DeviceAvailability.deviceNotSupported:
    break;
}
```

### .googleMapKey

도면을 표시할 Google Maps API 키를 반환합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final mapKey = await OneS1ght.googleMapKey();   // String?
```

### .sdkVersion

사용중인 네이티브 SDK 버전을 반환합니다. <br />
플러그인 버전은 `OneS1ght.pluginVersion`을 참조해 주세요.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final version = await OneS1ght.sdkVersion();
```

## 프로필

### .createProfile

새로운 개인화 프로필을 생성합니다. 성공적으로 생성하면 고유 프로필 ID를 반환합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final profileId = await OneS1ght.createProfile({'gender': 'F', 'ageBand': '20s'});
```

### .identify

수집할 측위 데이터를 묶을 프로필을 연결합니다. 연결 해제시 `null`으로 설정하세요.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.identify(profileId: profileId);
```

### .fetchProfile

프로필의 속성을 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final attributes = await OneS1ght.fetchProfile(profileId);
```

### .replaceProfile

프로필 속성을 교체하며 이전 데이터는 삭제됩니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.replaceProfile(profileId, attributes: {'gender': 'F', 'ageBand': '30s'});
```

### .deleteProfile

프로필 정보를 영구 삭제합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.deleteProfile(profileId);
```

## 공간 조회

### .buildings

테넌트와 연관된 모든 건물 목록을 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final buildings = await OneS1ght.buildings();
final building = await OneS1ght.building(id: buildingId);
```

### .floors

건물의 층 목록을 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final floors = await OneS1ght.floors(buildingId: buildingId);
```

### .floor

선택한 층의 상세 정보를 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final floor = await OneS1ght.floor(buildingId: buildingId, floorId: floorId);
final png = floor.image;   // Uint8List? — Image.memory(png)
```

### .zones

선택한 층의 모든 구역을 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final zones = await OneS1ght.zones(buildingId: buildingId, floorId: floorId);
final zone = await OneS1ght.zone(buildingId: buildingId, floorId: floorId, zoneId: zoneId);
```

### .locators

선택한 층의 로케이터 정보를 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final floorLocators = await OneS1ght.locators(buildingId: buildingId, floorId: floorId);
```

## 층 지정

### .setFloorMap

측위를 시작할 층을 지정합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final floor = await OneS1ght.floor(buildingId: buildingId, floorId: floorId);
await OneS1ght.setFloorMap(floor, buildingId: buildingId);
```

### .refreshZones

최신화된 구역 정보를 조회합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final zones = await OneS1ght.refreshZones();
```

## 측위 세션

### .floorSession

선택한 층의 로케이터 세션을 획득합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final session = await OneS1ght.floorSession();
```

### .begin

사용자 측위를 시작합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await session.begin();
```

### .end

사용자 측위를 종료합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await session.end();
```

### .pause · .resume

사용자 측위를 중지, 재개합니다. 종료와 달리 SDK 내 측위 엔진은 종료하지 않습니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await session.pause();
await session.resume();
```

### .isRunning · .isPaused

측위 상태여부와 중지여부를 반환합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
final running = await session.isRunning();
final paused = await session.isPaused();
final current = await session.floor();   // Floor?
```

## 세션 이벤트

### .onPosition

실시간으로 사용자 좌표 반환 이벤트를 발생합니다. (기본값 1초당 4회)

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onPosition.listen((c) => debugPrint('${c.x}, ${c.y}'));
```

### .onZoneEnter · .onZoneExit

구역 진입, 이탈시 이벤트가 동작합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onZoneEnter.listen((zone) => debugPrint('IN ${zone.name}'));
session.onZoneExit.listen((zone) => debugPrint('OUT ${zone.name}'));
```

### .onZoneDwell

특정 구역의 체류 시간이 초과할 경우(`dwellSeconds` 기준) 이벤트가 발생합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onZoneDwell.listen((d) => debugPrint('DWELL ${d.zone.name} ${d.seconds}s'));
```

### .onTriggers

공간 내 이벤트(또는 시책) 동작시 이벤트가 발생합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onTriggers.listen((t) {
  for (final trigger in t.triggers) {
    debugPrint('${t.zoneId} ${trigger.type}');
  }
});
```

### .onFloorDetected

로케이터의 BLE 신호를 수신한 경우 이벤트가 발생합니다.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onFloorDetected.listen((floorId) async {
  if (floorId == null) return;
  final floor = await OneS1ght.floor(buildingId: buildingId, floorId: floorId);
  await OneS1ght.setFloorMap(floor, buildingId: buildingId);
});
```

### .onStopped

사용자 측위가 중지된 경우 이벤트가 발생합니다.

| 이유 | 뜻 |
| - | - |
| `ended` | `end()` · `reset` · 키 교체 |
| `engineFailed` | 측위엔진 구동 실패시 |

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onStopped.listen((reason) {
  if (reason == StopReason.engineFailed) { }
});
```

### .onConfigChanged

콘솔 페이지에서 설정이 변경되었을 경우 이벤트가 발생합니다.

| 신호 | 의미 |
| - | - |
| `ZonesChanged(floorId)` | 구역 변경 |
| `PlanChanged(floorId)` | 도면 변경 |
| `RulesChanged(zoneId)` | 시책 변경 |
| `SdkConfigChanged` | 원격 설정 변경 |
| `ResyncNeeded` | 재연결 · 이벤트 누락 |

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
session.onConfigChanged.listen((change) {
  switch (change) {
    case ZonesChanged() || ResyncNeeded():
      OneS1ght.refreshZones();
    case PlanChanged(:final floorId):
      debugPrint('redraw $floorId');
    default:
      break;
  }
});
```

## 데이터 전송

좌표는 300건 또는 60초마다, 그리고 백그라운드 진입과 `end()` 때 자동 전송됩니다.

### .uploadPendingPositions

쌓인 좌표 즉시 전송.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.uploadPendingPositions();
```

### .discardPendingPositions

쌓인 좌표 폐기.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
await OneS1ght.discardPendingPositions();
```

## 오류 처리

실패는 모두 `OneS1ghtException` 을 반환하며, 자세한 내용은 [에러 코드](/sdk/troubleshooting/error-codes)를 참고하세요.

```dart Dart icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/dart.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=02dee5dd767b4c76ef0e07bc8663c542" theme={null}
try {
  await OneS1ght.initialize(sdkKey: key);
} on OneS1ghtException catch (e) {
  debugPrint('${e.code} ${e.message}');   // "E1003" …
}
```

## 모델

목록은 `List<T>`, 바이트는 `Uint8List` 입니다.

### Coordinates

| 필드 | 타입 | 설명 |
| - | - | - |
| `x` · `y` | `double` | 도면 로컬 미터 |
| `z` | `double` | 높이 |

### Building · Floor

| 타입 | 필드 | 설명 |
| - | - | - |
| `Building` | `id` · `name` | 건물 ID · 이름 |
| | `floorCount: int?` | 층 수 |
| `Floor` | `id` · `name` | 층 ID · 이름 |
| | `image: Uint8List?` | 도면 이미지 (BASE64) |
| | `hasPlan: bool` | 도면 등록 여부 |
| | `originX` · `originY` | 도면 원점(미터) |
| | `widthM` · `heightM` | 도면 크기(미터) |
| | `minX` · `minY` · `maxX` · `maxY` | 배치 범위 |

### Locator · FloorLocators

| 타입 | 필드 | 설명 |
| - | - | - |
| `Locator` | `address: int` | UWB MAC 뒤 2바이트 |
| | `x` · `y` · `z` | 도면 로컬 미터 |
| `FloorLocators` | `locators` | 층의 로케이터 목록 |
| | `sessionId: int?` | UWB 세션 — 층마다 다름 |
| | `positioningReady: bool` | 로케이터와 세션이 모두 있는가 |

### Zone

| 필드 | 타입 | 설명 |
| - | - | - |
| `id` · `name` | `String` | 구역 ID · 이름 |
| `polygon` | `List<Position>` | 꼭짓점(`x`, `y` 미터) |
| `dwellSeconds` | `int?` | 체류 이벤트 기준(초) |

### Trigger

| 필드 | 타입 | 설명 |
| - | - | - |
| `triggerId` | `String` | 트리거 ID |
| `type` | `String` | `signage` · `coupon` · `tracking` · `merch` · `generic` |
| `payload` | `Map<String, String>?` | 타입별 부가 정보 |

열거형(`ConfigChange` · `StopReason` · `PermissionStatus` · `DeviceAvailability` · `LogLevel`)은 마이너 버전에서 값이 늘 수 있습니다 — `switch` 에 `default` 를 둡니다.

## 제약

* 모든 호출은 `Future`, 이벤트는 `Stream` — UI 를 바로 고쳐도 됩니다.
* UWB 측위는 포그라운드 전용이며 백그라운드에서 멈추고 돌아오면 다시 시작합니다.
* 좌표 버퍼는 앱상 메모리에 임시 저장되며 강제 종료 시 미전송 좌표는 사라집니다.
* 에뮬레이터에서는 측위할 수 없습니다.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.