본문으로 건너뛰기
Unveilydocs

위치 (GPS)

디바이스 GPS 위치 정보에 접근합니다.

개요

GPS 및 네트워크를 통한 현재 위치 조회를 지원합니다. Android와 iOS에서 동일한 JS API를 사용합니다.

기능AndroidiOS
현재 위치 조회✓ (Android 7.0+)✓ (iOS 13+)
위치 변경 감지✓ (Android 7.0+)✓ (iOS 13+)

지원 플랜: Basic 이상


iOS 전제조건

iOS에서 위치 기능을 사용하려면 Info.plist에 위치 권한 설명을 추가해야 합니다.

Info.plist
<key>NSLocationWhenInUseUsageDescription</key>
<string>현재 위치를 기반으로 서비스를 제공하기 위해 위치 정보가 필요합니다.</string>

앱 심사를 통과하려면 권한 설명이 실제 사용 목적과 일치해야 합니다. 백그라운드 위치가 필요하면 NSLocationAlwaysAndWhenInUseUsageDescription도 추가하세요.


Android 권한 안내

Android에서 위치 기능을 사용하려면 먼저 AndroidManifest.xml에서 위치 권한을 주석 해제해야 합니다. SDK는 이 권한들을 기본적으로 주석 처리한 상태로 배포하므로, 실제로 사용하는 권한만 활성화하세요 (Google Play 데이터 안전성 정책).

AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

SDK가 위치 권한을 요청할 때, Android 버전에 따라 사용자에게 표시되는 선택지가 다릅니다.

Android 버전사용자 선택지
Android 11 이하앱 사용 중 허용 / 한 번 허용 / 거부
Android 12 ~ 16정밀 위치 또는 대략적 위치 중 선택 가능
Android 17+"앱 사용 중에만" 정밀 위치를 임시 부여하는 옵션 추가

사용자가 **대략적 위치(Approximate)**를 선택하면 반경 약 3km 수준의 좌표가 반환됩니다. SDK는 정밀 위치(ACCESS_FINE_LOCATION)를 요청하지만 사용자 선택을 강제할 수 없습니다.

Android 17에서 추가된 임시 정밀 위치 옵션을 선택하면, 앱이 백그라운드로 이동한 뒤 다시 위치를 요청할 때 권한이 만료되어 있을 수 있습니다. SDK는 이 경우를 자동으로 처리합니다 — 권한이 없으면 권한 요청 다이얼로그를 다시 표시하고, 위치 획득에 실패하면 isSuccess: false로 콜백이 호출됩니다.


현재 위치 조회

window.unveilyBridge.location.get({
  accuracy: "high",   // "high" | "medium" | "low"
  timeout: 10000,     // 최대 대기 시간 (ms)
  onResult: "onLocationResult",
  onError: "onLocationError"
});

function onLocationResult(result) {
  const { latitude, longitude, accuracy } = JSON.parse(result);
  console.log(`위도: ${latitude}, 경도: ${longitude}, 정확도: ${accuracy}m`);
}

function onLocationError(error) {
  const { code, message } = JSON.parse(error);
  if (code === "PERMISSION_DENIED") {
    alert("위치 권한을 허용해 주세요.");
  }
}

응답 구조

{ "latitude": 37.5665, "longitude": 126.9780, "accuracy": 15.0 }

위치 변경 감지 (지속 수신)

window.unveilyBridge.location.watch({
  minDistance: 10,   // 최소 이동 거리(m) 이상일 때 콜백
  onUpdate: "onLocationUpdate"
});

function onLocationUpdate(result) {
  const { latitude, longitude } = JSON.parse(result);
  updateMap(latitude, longitude);
}

// 감지 중지
window.unveilyBridge.location.stopWatch();

에러 코드

코드설명
PERMISSION_DENIED위치 권한 없음
TIMEOUT지정 시간 내 위치를 가져오지 못함
UNAVAILABLEGPS 또는 네트워크 위치 사용 불가

서버측 위치 저장

app.post('/api/location', (req, res) => {
  const { latitude, longitude } = req.body;
  const userId = req.session.userId;

  db.query(
    'INSERT INTO user_locations (user_id, latitude, longitude, recorded_at) VALUES (?, ?, ?, NOW())',
    [userId, latitude, longitude]
  );

  res.json({ ok: true });
});
[HttpPost("location")]
[Authorize]
public async Task<IActionResult> SaveLocation([FromBody] LocationRequest request)
{
    await _locationService.SaveAsync(User.GetUserId(), request.Latitude, request.Longitude);
    return Ok(new { ok = true });
}
@PostMapping("/api/location")
@PreAuthorize("isAuthenticated()")
public ResponseEntity<?> saveLocation(@RequestBody LocationRequest request,
                                       @AuthenticationPrincipal UserDetails user) {
    locationService.save(user.getUsername(), request.getLatitude(), request.getLongitude());
    return ResponseEntity.ok(Map.of("ok", true));
}
<?php
$data = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare(
    'INSERT INTO user_locations (user_id, latitude, longitude, recorded_at) VALUES (?, ?, ?, NOW())'
);
$stmt->execute([$_SESSION['user_id'], $data['latitude'], $data['longitude']]);
echo json_encode(['ok' => true]);
<%
Dim lat, lng
lat = Request.Form("latitude")
lng = Request.Form("longitude")

Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open Application("ConnectionString")
conn.Execute "INSERT INTO user_locations (user_id, latitude, longitude) VALUES (" & _
    Session("user_id") & ", " & lat & ", " & lng & ")"

Response.ContentType = "application/json"
Response.Write "{""ok"": true}"
%>

On this page