2014-05-04 24 views
3

我有一個iBeacons應用程序能夠在後臺運行或不運行時爲信號範圍。我實施了UILocalNotifications,它們工作正常,這意味着當我達到信標範圍時我會收到通知。iBeacons在後臺有時會延遲

不具有真實的信標我創建一個應用程序(用於另一個裝置,比方說一個ipad公司下一個場景),其作用就像2點不同的信標,這意味着它可以播放兩種不同的信號,同樣UUID但不同Major/Minor值(稱這個燈塔A和B),顯然是一次一個。我的問題是這樣的情景:

  1. 有我的iPhone(帶iBeacons應用程序關閉)在鎖屏
  2. 激活我的的iPad應用,廣播信標的
  3. 我的iPhone嚴正顯示我的通知
  4. 我停止iPad應用程序從廣播信標的,等待1秒,開始廣播臺B
  5. 我的iPhone DOES NOT反應
  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分鐘。 davidgyoung建議

我修改了代碼後

EDIT2照你說的用信標A和B 2個不同地區的延遲總是空。我還記錄了你給出的一段代碼,並且我發現了這一點。

  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個信標中的每一個都具有特定和單位角色),對嗎?

+0

如果您跳過第6步。是否發生過7次? – danh

+0

是的,我在幾分鐘後得到通知 – r4id4

+0

即使使用iOS7.1,背景檢測也不是即時的,可能需要幾分鐘的時間。我甚至發佈了一個證明! (請參閱我的第一個答案鏈接。)。是的,iOS將您限制在20個監控區域,因此您必須謹慎地設置它們。如果可以的話,請確定您將傳輸重疊的信標id,併爲這些信號使用單獨的區域。 (或者只是將多個信標的侷限性視爲單個區域) – davidgyoung

回答

1

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

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

兩件事情將幫助驗證/消除這種可能的原因:

  1. didDetermineState: forRegion:回調添加的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

+0

我編輯了我的問題並添加了一些代碼。我還記錄了'didDetermineState',但它看起來不錯,這意味着沒有關於這個 – r4id4

1

後看到代碼,我想這裏有幾個問題在這裏:

  1. 該代碼僅定義了包含BOTH信標A和B的單個區域,防止獨立區域進入/退出監控回調,以及在從傳輸信標A切換到信標B時阻止電話被喚醒。這很關鍵,因爲這意味着如果您從傳輸信標A切換到信標B,iOS將認爲自己仍然在一個地區。這可以防止手機獲取將在後臺喚醒手機的監控事件。

  2. 測距回調中沒有代碼來檢查哪個信標是可見的,所以似乎無法確定哪個信標引起通知。即使傳遞給測距回調方法的信標陣列爲空(即,如果沒有檢測到信標,該通知也會觸發)。

  3. 測距一般不會在後臺工作。進入/退出區域之後,唯一的例外是幾秒鐘。我懷疑你報告的兩分鐘延遲是你的iPhone執行下一個iBeacons後臺掃描所花費的時間(根據手機狀態,這個延遲可能是2,4或15分鐘)。之後,執行下一次掃描,檢測到區域轉換(可能是因爲沒有任何正在發送的出口區域通知),並且測距啓動持續5秒發出通知。

這是非常困難的測試和故障排除,無需登錄,直接將作爲我的第一個答案以及測距回調提到的監測區域回調,並記錄檢測到的信標標識符。確保您瞭解哪些回調觸發了哪些信標,並且不要立即嘗試排除太多問題!

除了第一個人回調故障排除,我也建議:

  • 更改代碼,每有一個燈塔地區最大背景響應。
  • 將檢測到的信標標識符放入通知中,以便您知道信標導致通知觸發。
+0

的特別報告謝謝你的回答!我會嘗試你所說的,記錄更多:D,現在我更好地理解事情的工作方式。但你也意味着我應該爲我應該達到的每個燈塔創造一個區域?在我的代碼中,我剛剛創建了一個單一的UUID區域,所有的信標廣播了相同的UUID,但不同的主要/次要,現在我應該創建(在這種情況下)2區域區分區域定義不僅是UUID,但主要/次要的,我是對的嗎?在這種情況下,我可以一次監控多少個地區?意思是說,如果我有100個信標,我可以尋找100個地區嗎?謝謝 – r4id4

+0

我已經在你的建議後再次編輯了我的第一個問題,如果你能看,我會很高興在它告訴你的印象。再次感謝 – r4id4

0

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

在上面的解釋中,它看起來像只監視一個信標區域(您沒有指定主要/次要數字,因此具有相同UUID的任何信標都有資格)。不幸的是,您創建了兩個具有相同UUID的信標發送器。所以當你啓動燈塔時,你會收到一個通知(ENTER),但必須等待幾分鐘才能完成另一個(EXIT)。通常我在信標停止傳輸約30秒後纔看到退出通知。

如果要再次執行實驗,請嘗試註冊兩個不同的信標區域(聲明兩個區域,其中包含差異主要/次要數字,或製作兩個差異UUID),然後在信標發射機中使用這兩個差異值。那麼應該工作。 Tom