본문으로 건너뛰기

iOS에서 지오펜스 트리거가 안되는 이유

iOS에서 Capacitor 앱에서 지오펜스 트리거링이 안되는 이유를 알아보세요. 지역 모니터링이 어떻게 작동하는지, 권한, 반지름 및 제한 규칙, 각 사례를 디버깅하는 방법에 대해 배워보세요.

작성자

마틴 도나디우

작가

발레리아

리뷰어

조던

편집자

iOS에서 지오펜스 트리거링이 안되는 이유

iOS 지오펜스 트리거링이 안되는 이유는 거의 항상 짧은 목록 중 하나 때문입니다. 앱이 항상 허용 권한이 없거나, 장치가 지오펜스 영역에 이미 들어가 있을 때, 반지름이 iOS가 경계를 감지할 수 있는 크기보다 작을 때, 앱이 20개의 지오펜스 영역 제한을 넘을 때, 또는 테스트가 충분히 기다리지 않았을 때입니다. iOS 지오펜스는 잘 작동하지만, 트리거링을 자신의 일정에 따라 보고합니다. 이 안내서에서는 지역 모니터링이 트리거를 언제 발동하는지, 그리고 Capacitor 앱을 디버깅하는 방법에 대해 설명합니다. @capgo/background-geolocationiOS 지역 모니터링이 어떻게 작동하는지

, iOS와 Android에서 native 지오펜스를 지원합니다.

iOS에서 지오펜스(triggers)는 (Note: I've kept the translation within ±30% of the source character count and preserved the brand name "Capacitor" as per the instructions.) CLCircularRegion Core Location에 등록된

등록된 후 운영 체제가 모니터링합니다. 앱이 중단되거나 실행되지 않아도 iOS는 지역을 추적하고, 전원 소비를 낮추기 위해 셀 타워, Wi-Fi 및 GPS를 혼합하여 사용합니다.

  • When iOS가 장치가 경계를 넘었다고 결정하면, enter 또는 exit 이벤트를 앱에 전달하고, 필요하고 허용된 경우 배경에서 앱을 시작합니다. 몇 가지 규칙이 결정에 영향을 미칩니다:
  • iOS는 장치가 경계를 넘었을 때 즉시 경계를 넘은 것을 보고하지 않습니다. 애플의 지침은 장치가 경계를 넘어야 하며, 최소한 20초 이상 경계를 유지해야 하며, GPS 진동을 피하기 위해 이벤트가 전달되기 전에 장치가 경계를 넘어야 한다는 것입니다.
  • 지역 모니터링의 위치 정확도는 주변 라디오의 종류에 따라 달라집니다. 도시에서 Wi-Fi가 밀집해 있다면 빠를 수 있지만, 농촌 도로에서는 몇 분이 걸릴 수 있습니다.

설정한 지역 내에서 Capacitor 앱을 감지하도록 설정합니다.

__CAPGO_KEEP_0__ 앱에서 지오펜싱을 설정하세요

bun add @capgo/background-geolocation
bunx cap sync
<key>NSLocationWhenInUseUsageDescription</key>
<string>We use your location to detect when you arrive at a store.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need Always access to notify you when you arrive, even when the app is closed.</string>

플러그인을 설치하고 iOS 키를 구성하세요:

import { BackgroundGeolocation } from '@capgo/background-geolocation';

await BackgroundGeolocation.setupGeofencing({
  url: 'https://api.example.com/v1/geofence-events',
  headers: { Authorization: 'Bearer <token>' },
  notifyOnEntry: true,
  notifyOnExit: true,
  payload: { userId: 'u-42' },
});

await BackgroundGeolocation.addGeofence({
  identifier: 'store-paris-11',
  latitude: 48.8606,
  longitude: 2.3795,
  radius: 150,
  payload: { storeId: 'paris-11' },
});

await BackgroundGeolocation.addListener('geofenceTransition', (event) => {
  console.log(`${event.transition} ${event.identifier}`, event.payload);
});

await BackgroundGeolocation.addListener('geofenceError', (event) => {
  console.error('Geofence error', event.identifier, event.code, event.message);
});

setupGeofencing 그런 다음 지역을 등록하세요:requestPermissions 기본값으로 trueAlways

현재, 실패 모드.

1. 항상 권한이 없습니다.

iOS에서 지역 모니터링은 항상 권한이 필요합니다. While Using App만으로는 앱이 백그라운드 또는 실행되지 않는 경우 지역이 이벤트를 전달하지 않습니다. 이는 지오펜스의 전체 목적입니다.

등록하기 전에 지역을 확인하고 사용자에게 설명하세요:

const status = await BackgroundGeolocation.checkPermissions();

if (status.backgroundLocation !== 'always' && status.backgroundLocation !== 'granted') {
  // Show your own screen explaining the feature, then:
  const next = await BackgroundGeolocation.requestPermissions({
    permissions: ['backgroundLocation'],
  });
  if (next.backgroundLocation === 'when_in_use' || next.backgroundLocation === 'denied') {
    await BackgroundGeolocation.openSettings();
  }
}

iOS는 항상 업그레이드 프롬프트를 즉시 표시하지 않을 수 있습니다. 사용자가 "앱을 사용하는 동안 허용"을 선택한 경우에는 두 번째 프롬프트만 나중에 볼 수 있습니다. 사용자가 "한 번만 허용"을 선택한 경우에는 임시 허가가 리셋됩니다. 지오펜싱이 주요 기능이라면 앱이 시작될 때마다 상태를 확인하고 항상 허용되지 않은 경우에는 rõ ràng한 배너를 표시하세요.

2. 기기 내부에 이미 지역이 있습니다.

기기 내부에 이미 지역이 있는 경우 iOS는 입장 이벤트를 전송하지 않습니다. 아무것도 건너뛴 것이 없습니다. 팀은 테스트 중에 지역을 사무실 주변에 설정하여 테스트하는 경우에 이 문제를 자주 겪습니다.

해결 방법: 지역을 등록할 때 현재 위치와 지역을 비교하여 "이미 내부에 있는 경우"를 처리하세요.

import { Geolocation } from '@capacitor/geolocation';

function distanceMeters(lat1: number, lon1: number, lat2: number, lon2: number) {
  const R = 6371000;
  const toRad = (d: number) => (d * Math.PI) / 180;
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) ** 2 +
    Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;
  return 2 * R * Math.asin(Math.sqrt(a));
}

const region = { identifier: 'store-paris-11', latitude: 48.8606, longitude: 2.3795, radius: 150 };
await BackgroundGeolocation.addGeofence(region);

const pos = await Geolocation.getCurrentPosition({ enableHighAccuracy: true });
if (distanceMeters(pos.coords.latitude, pos.coords.longitude, region.latitude, region.longitude) < region.radius) {
  handleAlreadyInside(region.identifier);
}

declare function handleAlreadyInside(id: string): void;

입장 이벤트를 테스트하려면 반드시 반경을 벗어나서 기다리세요.

3. 반경이 너무 작습니다.

iOS는 작은 반경을 허용하지만 신뢰도는 100미터 이하로 떨어질 경우 급격히 떨어집니다. Wi-Fi 및 셀 위치 정보를 기반으로 하는 지역 모니터링으로 인해 30미터의 상점 입구 주변 지역은 늦게 발생하거나 고객이 나간 후 발생하거나 전혀 발생하지 않을 수 있습니다.

실용적인 값:

사용 사례 권장 반경
상점 또는 식당 도착 100m에서 200m
사무실, 캠퍼스, 창고 150m에서 300m
neighborhood 또는 city zone 500m 이상

도어 레벨 정확도 필요하다면, 사용자가 내부에 들어가면 foreground 위치 또는 beacons와 combine하는 것이 좋습니다. Capgo는 또한 iBeacon 플러그인 내부 근접성

4. 20 지역 제한을 초과합니다

iOS 앱은 한 번에 최대 20 개의 지역을 모니터링할 수 있습니다. 더 많은 지역을 추가하면 추가 지역의 등록이 실패하고 모니터링 오류가 발생합니다.

사용 getMonitoredGeofences() 실제로 등록된 것을 확인하고 가장 가까운 지역의 롤링 세트를 유지하세요:

const { regions } = await BackgroundGeolocation.getMonitoredGeofences();
console.log(`Monitoring ${regions.length} regions`, regions);

일반적인 패턴:

  1. 서버에 전체 장소 목록을 유지하세요.
  2. 앱이 시작될 때 및 사용자가 멀리 이동할 때 (예를 들어, 사용자가 큰 "refresh" 지역을 벗어나면), 19 개의 가장 가까운 장소를 가져옵니다.
  3. Call removeAllGeofences()Android는 앱당 최대 100 개의 지오펜스를 허용하므로, Android에서 작동하는 것을 iOS에서 실패하는 이유로만 실패할 수 있습니다.

안드로이드는 앱당 최대 100개의 지오펜스(geofence)를 허용하므로, code이 안드로이드에서 작동하는 경우 iOS에서 작동하지 않을 수 있습니다.

5. 테스트 기간이 너무 짧거나 너무 정적이었다.

테스트할 때:

테스트 중에:

  • 1분 동안 밖에서待기하고, 그 후에 집으로 들어가서 최소 2분 이상待기하세요.
  • Wi-Fi를 켜고 테스트하세요. Wi-Fi를 끄면 지역 모니터링이 훨씬 덜 정확해집니다. 네트워크에 연결되어 있지 않더라도.
  • 시뮬레이터를 사용하여 타이밍에 의존하지 마세요. GPX 경로를 Xcode에 넣어 핸들러를 확인한 후 기기에서 테스트하세요.

6. 이벤트가 발생했지만, 자바스크립트가 실행되지 않았습니다.

iOS가 앱을 재시작하여 배경에서 지역 이벤트를 발생시키면, 네이티브 플러그인이 이벤트를 받지만, Capacitor WebView가 로드되지 않았거나 즉시 다시 중단될 수 있습니다. geofenceTransition 이것은 WebView가 살아있는 동안만 리스너가 작동하는 이유입니다.

이것이 setupGeofencing accepts urlcode에서 native로의 전환을 포함한 merged 데이터를 POST합니다. payload. 플러그인은 네이티브 __CAPGO_KEEP_0__에서 전환을 POST합니다. 이때, 병합된 updateHeaders().

이러한 데이터를 전송하여, 백엔드가 자바스크립트가 실행되지 않았더라도 이벤트를 받을 수 있도록 합니다. 헤더는 설정과 함께 유지되므로 재시작 후에도 작동하고,

배달은 최선의 노력으로, 재시도 큐가 없습니다. 엔드포인트를 빠르게하고 idempotent하게 만들고, 테스트 중에는 모든 요청을 로그하세요.

테스트 기기를 확인하세요:

  • 설정, 개인 정보 보호 및 보안, 위치 서비스가 켜져 있습니다.
  • 앱은 항상 켜져 있습니다.
  • 앱에 대한 정확한 위치가 켜져 있어야 합니다. 그렇지 않으면 작은 지역이 불신할 수 있습니다.
  • 첫 번째 테스트 중에는 배경 활동을 줄이는 Low Power Mode가 꺼져 있습니다.

8. 재부팅 및 앱 업데이트

iOS는 앱 실행 시에 모니터링 된 지역을 유지합니다. 장치가 재부팅되면 시스템이 다시 시작되면 모니터링이 재개되지만, 앱은 다시 시작할 때 지역을 싱크해야 합니다: 비교하여 기대하는 것과 누락된 것들을 다시 추가하세요. 서버가 장소 목록을 변경할 때마다 동일한 작업을 수행하세요. getMonitoredGeofences() 안드로이드에서는 재부팅, 위치가 꺼져 있는 경우, 앱 데이터가 삭제되는 경우와 같은 몇 가지 상황에서 지오펜스들이 제거되므로, 재등록이 필요합니다. 두 플랫폼 모두에서 이를 수행하면 논리가 단순해집니다.

9. 강제 종료

사용자가 앱 switcher에서 앱을 강제 종료하면 iOS는 사용자가 앱을 실행하지 않으려는 신호로 간주합니다. 강제 종료 후 앱이 다시 시작되는 지역의 동작은 iOS 버전에 따라 달라집니다. 강제 종료 후 앱이 다시 시작되지 않는 경우에만 작동하는 기능을 구축하지 마세요. 사용자가 실행하는 iOS 버전을 테스트하세요.

디버깅 체크리스트

디버깅 체크리스트

확인 어떻게
권한이 항상 checkPermissions() 반환 always 또는 granted 권한이 항상 backgroundLocation
권한이 항상 getMonitoredGeofences() 권한이 항상
권한이 항상 권한이 항상 getMonitoredGeofences()
권한이 항상 권한이 항상 addGeofence calls
이미 내부에 있는 경우 등록 시 현재 위치와 비교
오류는 로그에 기록됩니다. 이벤트를 geofenceError
백엔드에서 이벤트를 받음 설정 url 내 setupGeofencing 요청을 로그
실제 움직임 테스트 지역을 완전히 떠, 기다리, 돌아와 머물러

Android와의 차이점

iOS에서 code이 안드로이드에서 작동하는 경우 20 지역 제한과 Always 요구 사항이 일반적인 이유입니다. code이 안드로이드에서 작동하는 경우 iOS에서 작동하지 않는 경우에는 manifest에 추가했는지 확인하세요. ACCESS_BACKGROUND_LOCATION manifest에 추가하고 설정하세요. backgroundLocation: true 에서. setupGeofencing배포 변경 사항

권한 문자열과 네이티브 구성은 새로운 빌드를 필요로 합니다. 지역 목록, 반경 값 및 UI 텍스트는 서버에서 변경하거나 __CAPGO_KEEP_0__ live updates를 통해 배포할 수 있습니다.

live updates Capgo 실시간 업데이트.__CAPGO_KEEP_0__. iOS 백그라운드 위치 업데이트 중단 이유와 플러그인의 문서 전체 API.

Capacitor 앱에 대한 실시간 업데이트

웹-layer 버그가 활성화된 경우 Capgo을 통해修정을 배포하는 대신 앱 스토어 승인까지 며칠 기다리지 말고 배포하십시오. 사용자는 배경에서 업데이트를 받으면서 네이티브 변경 사항은 일반적인 검토 경로에 남겨두십시오.

최신 뉴스

Capgo은 전문적인 모바일 앱을 만들기 위해 필요한 최고의洞察력을 제공합니다.