簡體   English   中英

背景中的iBeacons有時會有延遲

[英]iBeacons ranging in background sometimes has delay

我有一個iBeacons應用程序,可以在后台或不運行時為信標范圍。 我實現了UILocalNotifications並且它們工作正常,這意味着當我到達信標的范圍時我會收到通知。

沒有真正的燈塔,我創建了一個應用程序(對於另一個設備,讓我們說下一個場景的iPad )就像2個不同的信標,這意味着它可以廣播2個不同的信號,相同的UUID但不同的Major/Minor值(稱為此信標A和B),一次一個。 我的問題是在這種情況下:

  1. 將我的iPhone(關閉iBeacons應用程序)鎖定在屏幕上
  2. 激活我的iPad應用程序,廣播信標A.
  3. 我的iPhone反應向我顯示通知
  4. 我從廣播信標A停止iPad應用程序,等待1秒,開始廣播信標B.
  5. 我的iPhone 沒有反應
  6. 我阻止iPad播放
  7. 幾分鍾后(大約2分鍾),我的iPhone向我顯示了信標B的通知

現在我不明白的是這個延遲,這是我的iPhone第一次立即做出反應,第二次需要大約2分鍾通知我燈塔。

如果在信標B通知之后,我重新開始廣播信標(A或B),我的iPhone立即做出反應,那么下次它總是等待2分鍾。

為什么會這樣? 我讀過一些文章說這是因為當應用程序處於后台時藍牙每隔2-4分鍾喚醒一次,所以我可以獲得的信息不會比這次更快。 但是我覺得這沒有多大意義,因為每當我得到第二個通知時,信標的廣播(我的場景中的B )已經停止 ,這意味着如果藍牙在那個時刻醒來,那么沒有信標在空中! 但是我得到了通知,所以這意味着在我停止播放之前我的iPhone發現了它。

這是一個可以解決的問題嗎?

用一些代碼編輯

這是我的viewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Initialize location manager and set ourselves as the delegate and beacons dictionary
    _beacons = [[NSMutableDictionary alloc] init];
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    // Create a NSUUID with the same UUID as the broadcasting beacon
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"6C1AA496-1653-403D-BD1E-7F630AA6F254"];

    // Setup a new region with that UUID and same identifier as the broadcasting beacon
    self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                             identifier:@"testregion"];

    NSLog(@"startMonitoring");
    // Tell location manager to start monitoring for the beacon region
    [self.locationManager startMonitoringForRegion:self.myBeaconRegion];
    [self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];

    _myBeaconRegion.notifyEntryStateOnDisplay = YES;

    // Check if beacon monitoring is available for this device
    if (![CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]){
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Monitoring not available" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; return;
    }

}

現在,每當我得到一個燈塔,我發送通知,我只是想嘗試它是如何工作所以我沒有實現只發送1通知的方式,這意味着我得到大約9通知,每秒1,這是活動時間代碼可以在后台運行,我猜想(1秒輸入區域,9范圍為信標)

-(void)locationManager:(CLLocationManager*)manager
       didRangeBeacons:(NSArray*)beacons
              inRegion:(CLBeaconRegion*)region
{
    if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground){
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = @"Found Beacon";
        notification.soundName = @"Default";
        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
    }
}

實際上更具體一點,如果我從多任務處理視圖中完全關閉我的應用程序,或者只是讓它在后台,只要我開始播放一個信標,我就會得到通知** S **(1秒延遲)。 然后停止廣播並重新播放延遲變為大約幾分鍾。

現在對於一個真實場景,我應該在同一個地方有許多信標,這種延遲可能是一個問題,只要我收到通知,我可能已經遠離信標本身。

我的代碼有問題嗎? 我讀過這些文章,但我從未發現延遲15分鍾。

EDIT2之后davidgyoung建議

我修改了我的代碼,正如你所說,使用2個不同的區域作為信標A和B,延遲始終為空。 我還記錄了你提供的代碼,我發現了這一點。

  1. 廣播Region_1的信標
  2. 設備顯示Region_1的通知
  3. 停止播放Region_1的信標
  4. 日志說我仍然在該地區,只有幾分鍾后我得到“OUTSIDE Region_1 ”的日志,剛才我可以重新播放廣播以獲得Region_1另一個通知。

所以我很好奇這個,我讀了文章http://beekn.net/2014/03/apple-ios-7-1-launches-major-ibeacon-improvement/

作者說,從iOS 7.1開始,退出一個地區的響應能力很快,實際上我正在運行7.1但我也有幾分鍾的延遲。 為什么這個? 你在測試中發現了同樣的問題嗎?

現在,我讀到一個設備可以監聽不超過20個區域嗎?這意味着如果我有100個信標,我可以設置20個區域並將這100個分成20組,獲得不超過20個通知(假設這100個在同一個地方,都在我的設備范圍內)? 這可能是一個問題,因為它將強制用戶在前台運行應用程序以獲取所有信息(假設100個信標中的每一個都具有特定的單位角色),我是對的嗎?

編輯:這是我看到代碼之前的第一個答案。

我無法根據您的描述解釋此行為,但我懷疑設置可能存在問題,即延遲您的本地通知或在發送通知時不准確地報告信標區域B的狀態。

有兩件事可以幫助驗證/消除這個可能的原因:

  1. didDetermineState: forRegion: callback中添加NSLog語句,如下所示,然后重復測試報告日志結果。

     // put this in your AppDelegate - (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region { if(state == CLRegionStateInside) { NSLog(@"locationManager didDetermineState INSIDE for %@", region.identifier); } else if(state == CLRegionStateOutside) { NSLog(@"locationManager didDetermineState OUTSIDE for %@", region.identifier); } else { NSLog(@"locationManager didDetermineState OTHER for %@", region.identifier); } } 
  2. 發布設置監視的代碼並在檢測時發出通知。

如果你還沒有讀過這篇文章,你可能想快速瀏覽一下我測量背景檢測時間的類似測試:

http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html

http://developer.radiusnetworks.com/2014/03/12/ios7-1-background-detection-times.html

看到代碼后,我想這里有幾個問題:

  1. 該代碼僅定義包含BOTH信標A和信標B的單個區域,防止獨立區域進入/退出監視回調,並且當從發送信標A切換到信標B時停止電話被喚醒。這是關鍵的,因為這意味着如果你從發射信標A切換到信標B,iOS將認為自己仍然在一個區域。 這可以防止手機獲得將在后台喚醒手機的監控事件。

  2. 測距回調中沒有代碼來檢查哪個信標是可見的,因此似乎無法確定哪個信標導致了通知。 即使傳遞給測距回調方法的信標數組為空(即,如果沒有檢測到信標),通知也會觸發。

  3. 測距通常不適用於后台。 唯一的例外是在進入/退出某個區域后幾秒鍾。 我懷疑你報告的兩分鍾延遲是iPhone為iBeacons執行下一次后台掃描所需的時間(此延遲可以是2,4或15分鍾,具體取決於手機狀態)。 在執行下一次下一次掃描之后,檢測到區域轉換(可能是因為沒有正在發送的退出區域通知),並且范圍啟動5秒以發出通知。

如果沒有直接記錄我的第一個答案中提到的監控區域回調以及測距回調,並且記錄檢測到的信標的標識符,則很難進行測試和故障排除。 確保您了解哪些回調正在觸發哪些信標,並且不要立即嘗試排除太多故障!

除了首先對各個回調進行故障排除外,我還建議:

  • 更改代碼以使每個信標具有一個區域以獲得最大的背景響應。
  • 將檢測到的信標標識符放入通知中,以便您知道信標會導致通知觸發。

DavidGYoung是對的。 當感測到信標區域遍歷時,iOS7.1將在終止時調用您的應用程序。 但是,這是至關重要的,iOS只會在您輸入或退出信標區域時調用已終止的應用程序,並且僅當您的應用程序先前已注冊該特定信標區域的位置事件時。

在上面的解釋中,看起來您只監視一個信標區域(您沒有指定主要/次要號碼,因此任何具有相同UUID的信標都符合條件)。 不幸的是,您創建了兩個具有相同UUID的信標發射器。 因此,當你啟動燈塔時,你會得到一個通知(ENTER),但不得不等待幾分鍾而另一個(退出)。 通常我會在信標停止傳輸后大約30秒看到退出通知。

如果您想再次執行實驗,請嘗試注冊兩個不同的信標區域(聲明兩個帶有差異主要/次要編號的區域,或制作兩個差異UUID),然后在信標發射器中使用這兩個差異值。 應該工作。 湯姆

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM