2014-10-14 2 views
5

모니터링 및 거리 측정의 차이점을 이해했으며 여기에 설명 된 바와 같이 영역을 시작하거나 종료 할 때 비콘 측정이 전경이나 배경에서만 발생할 수 있다는 점에서 iOS의 한계를 이해합니다 (http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html) . 하지만 일반적인 시나리오를 해결하는 방법을 알아 내려고 노력 중입니다.iOS의 백그라운드에서 비콘으로 이동

백화점에 여러 개의 표지를 설치했다면 해당 표지의 범위 내에서 사람이 이동할 때 어떻게 감지 할 수 있습니까? 현재 작동하는 방식으로 모든 비컨 수집이 하나의 큰 지역으로 작동하기 때문에 사용자가 상점에 입장하면 앱에서 이벤트를 받게됩니다 (didEnterRegion). 그러나 비컨이 사용자가 빠져 나가서 다시 지역에 들어가기에 충분히 멀리 있지 않으면 사용자가 상점의 다른 섹션 사이를 이동한다는 것을 알 수있는 방법이 없습니다. 이는 실제로 실용적이지 않습니다.

백그라운드에서 비컨의 범위를 지정하려는 이유는 사용자가 해당 섹션에 대한 특정 쿠폰/정보 (알림을 통해)를 표시하기 위해 상점의 특정 섹션/제품에 있다는 것을 알아야 할 필요가 있습니다. 사용자가 앱을 열어야합니다.

이것은 쇼핑몰과 박물관 등에서 매우 일반적인 시나리오처럼 보입니다 ... 다른 개발자가이 문제를 어떻게 해결했는지 또는 내가 원하는 것을 성취 할 수있는 또 다른 방법이 있는지 궁금합니다.

문제는 코드와 관련이 없으므로 여기에 코드 스 니펫을 포함하지 않았습니다. 단지 개념적 문제 일뿐입니다. 설명이나 코드가 필요한 경우 추가 할 수 있습니다.

고마워요.

+0

https://github.com/RadiusNetworks/ibeacon-background-demo/tree/background-task이 질문을 해결할 수있는 답이있다? 또는 그것을 해결할 수 있습니까? – aeren

답변

3

저는 여러 지역으로 상점을 나눠서 모델링했습니다. 그들이 모델링되는 방법은 알림이 트리거되었을 때 가지고있는 유스 케이스를 기반으로합니다.

모든 UUID를 부여하지만 다른 주요 값을 지정하면됩니다. 그런 다음 마이너 값을 사용하여 상점을 구분하십시오. 이렇게하면 지역에서 이동할 때 앱이 didEnter 이벤트를 등록합니다.

약 20 개의 지역을 등록 할 수 있으므로 비콘을 함께 그룹화 할 때주의해야합니다. 예를 들어

:

  • UUID : 754A5D70-C59E-4E39-AA56-ED646903EF5B 전공 : 1 → 입구
  • UUID : 754A5D70-C59E-4E39-AA56-ED646903EF5B 전공 : 2 → 금전 등록기
  • UUID : 754A5D70-C59E-4E39-AA56-ED646903EF5B 전공 : 의류 → 3
  • UUID : 754A5D70-C59E-4E39-AA56-ED646903EF5B 전공 : 4 → 가정 용품
  • ...

그런 다음 앱 사용자가 저장소를 통해 이동하면 영역 경계를 넘을 때 작업을 트리거 할 수 있습니다.당신이 할 수있는

이 방법 :

  1. 엔터 종료 콜백을 가져 오기 (각 비컨 저장 또는 고유 당 수) 마이너 값
  2. 로컬 보내기를 찾을 이르기까지
  3. 시작 알림
+0

나는 그것에 대해 생각했다. 문제는 비콘을 여러 지역으로 나누면 세분화되지 않을 수도 있다는 것입니다. 경우에 따라 특정 단일 신호와 관련하여 오퍼 나 정보를 표시해야 할 수도 있습니다. 그리고 iOS는 이해할 수있는 모든 앱에서 전역 제한이 20 개이므로 실제적이지 않습니다. –

+0

나는이 문제를 해결할 수 있다고 생각한다. – csexton

+0

설명 주셔서 감사합니다. 또 다른 문제는 지역 입력 콜백을 받으면 약 10 초 동안 만 범위를 지정할 수 있다는 것입니다. 그 후 앱이 배경으로 돌아갑니다. 그래서 우리가 커다란 의류 섹션을 가지고 있다면, 우리는 특정 지역에 대한 알림을 표시 할 필요가있을 때를 대비하여 지역의 가장자리를 중심으로 범위를 정할 것입니다. 사용자가 앱을 열지 않는 한 –

2

해야 할 일은 모든 비콘의 UUID가 동일한 지 확인하는 것입니다. 그런 다음 해당 UUID 만 지정하는 모니터링을 위해 단일 CLBeaconRegion을 등록하십시오. 주 값 또는 부 값을 포함하지 마십시오. 이로 인해 해당 UUID가 일치하는 모든 비컨 (주 값과 부 값이 와일드 카드 됨)이 호출 될 때 didEnterRegion:이 호출됩니다. 그러나 여기에 반환 된 CLBeaconRegion에는 UUID 만 있고 중요/부전공이 없으므로 등록한 방법과 동일하게 정확히 어떤 신호를 발사했는지 모릅니다. 장치가 어떤 비컨을보고 있는지 정확하게 파악하려면 didEnterRegion:이 호출되면 위치 관리자에게 입력 된 지역으로 startRangingBeaconsInRegion:으로 알립니다. 위치 관리자는 didRangeBeacons:이 CLBeacons의 배열을 전달하여 다시 전화 할 것입니다. 이 CLBeacons는 메이저 및 마이너 값을 알 수 있으므로 사용자가 저장소의 어느 부분에 있는지 정확하게 확인할 수 있습니다 (주/보조가 배치 된 신호가 어디에 있는지 알기 때문에). 앱이 백그라운드에있는 동안이 작업을 모두 수행 할 수 있습니다.

이렇게하면 하나의 CLBeaconRegion 만 등록하면되지만 등록 된 UUID와 일치하는 모든 신호와 계속 상호 작용할 수 있습니다.

나는이 방법을 사용하여 전 영역과 배경에서 모두 성공적으로 실행 된 한 영역에 80 개 이상의 비컨을 성공적으로 배치했습니다. 이 작업을 수행하기 위해 사용자가 앱을 열지 않아도됩니다.

+0

이것은 내가 지금하는 일입니다. 그러나 이것은 일단 당신이 그 지역에 있다면 당신이 비컨에 대한 범위를 유지하는 것을 허락하지 않습니다. 따라서 사용자가 지역에 입장하면 어떤 신호가 발사되는지 즉시 확인할 수 있습니다. 그러나 그들이 지역 안쪽을 돌아 다니면 이동하는 신호를 보지 못합니다. –

+0

일단 지역을 입력하고 해당 지역에서 startRangingBeaconsInRegion을 호출하면 위치 관리자는 didExitRegion이 호출 될 때까지 해당 UUID로 보이는 모든 비컨의 범위를 유지합니다.이 시점에서 stopRangingBeaconsInRegion을 호출해야합니다. 그게 네가 겪은 것이 아닌가? –

+0

이상한. 아니, 그게 내가 겪고있는 것이 아니야. 나에게'didEnterRegion'이 생기면'startRangingBeaconsInRegion'을 호출하면 약 10 초 동안 정기적 인 콜백 (초당 1 회)이 제공됩니다. 그 후 아무것도. –

7

가장 큰 부분은이 질문에 대한 다른 대답으로 동료 @csexton이 기술 한 기술입니다.

전환 후 10 초의 거리 시간 만 가져 오는 두 번째 문제를 해결하기 위해 추가 시간을 요청할 수 있습니다. iOS를 사용하면 백그라운드에서 최대 180 초 동안 계속해서 작업 할 수 있습니다. 배경 모드가 필요없고 AppStore의 특별한 허가가 필요하지 않습니다. 여기

는 당신이 것을 설정하는 방법은 다음과 같습니다

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region 
{ 
    if (_inBackground) { 
     [self extendBackgroundRunningTime]; 
    } 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    [self logString: [NSString stringWithFormat:@"applicationDidEnterBackground"]]; 
    [self extendBackgroundRunningTime]; 
    _inBackground = YES; 
} 


- (void)extendBackgroundRunningTime { 
    if (_backgroundTask != UIBackgroundTaskInvalid) { 
     // if we are in here, that means the background task is already running. 
     // don't restart it. 
     return; 
    } 
    NSLog(@"Attempting to extend background running time"); 

    __block Boolean self_terminate = YES; 

    _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"DummyTask" expirationHandler:^{ 
     NSLog(@"Background task expired by iOS"); 
     if (self_terminate) { 
      [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask]; 
      _backgroundTask = UIBackgroundTaskInvalid; 
     } 
    }]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSLog(@"Background task started"); 

     while (true) { 
      NSLog(@"background time remaining: %8.2f", [UIApplication sharedApplication].backgroundTimeRemaining); 
      [NSThread sleepForTimeInterval:1]; 
     } 

    }); 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [self logString: [NSString stringWithFormat:@"applicationDidBecomeActive"]]; 
    _inBackground = NO; 
} 

에는 은색 총알이 백그라운드에서 범위를 180 초입니다 얻기 없지만, 10 초하지 않는 것을 많은 사용 사례를 해결합니다.

현재 테스트 결과와 함께, 이것이 어떻게 작동하는지에 대한 전체 작성자를 읽을 수 있습니다

+0

사용자가 멀티 태스킹 응용 프로그램을 수동으로 종료 한 경우이 기능이 작동합니까? –

+0

멀티asker에서 앱을 종료하면 즉시 범위 지정이 중단됩니다. 그러나 iOS 7.1 이상에서는 모니터링 된 신호가 감지되면 백그라운드에서 앱을 실행하고 프로세스를 다시 시작합니다. iOS 7.0에서는 멀티 태스킹에서 앱을 종료하면 사용자가 수동으로 다시 시작할 때까지 앱이 중지됩니다. – davidgyoung

+0

의미가 있습니다. 따라서 사용자가 비컨의 범위에 서있는 동안 앱을 종료하면 즉시 다시 실행됩니까? 또는 지역 입장 콜백을 받기 위해 퇴장하고 다시 입장해야합니까? –

관련 문제