2017-10-25 11 views
0

iPhone上で動作するiBeaconデバイスを設計しています。この問題は、ビーコンを認識しているアプリとの非常に奇妙な不一致です。私は主にこの文書からのビーコンについて学習しました:iOSアプリケーションがiBeaconで不思議に動作しています

がデバイス::https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf はここに私のシステムについて簡単に紹介され - デバイス上のボタンを押して約2秒間は10HzでiBeacon BLE広告をトリガします。 - デバイスは20個のUUIDを順番に循環し、それぞれ異なるボタンを押すたびに使用します。これは、アプリケーションが「範囲外に出る」時間がないときに、急速なボタン押下の場合にボタンの押下を区別するためです。 20 UUIDは、アプリケーションが監視することが許されるAppleの制限です。

The App: - アプリは20個のUUIDを検索します。 - 検出時には、enterイベントとexitイベントがいくつかのアプリイベントをトリガし、レンジングは短時間割り当てられたバックグラウンド時間で短時間でMaj。Minを抽出します。ペア値。

テスト: テストのために、入力、範囲、および終了イベントが発生したときに、アプリケーションがポップアップを表示するように設定されています。テストはフォアグラウンドでアプリケーションで行われます。私はボタンを押し、エンターとレンジイベントを監視し、領域を出て再び押すまで待つ。 BLEスキャナでテストすると、デバイスがうまく動作し、20 UUIDを正しく循環するボタンプレスの100%をブロードキャストしていることがわかります。

問題: アプリ内テストでは、問題が発生し、奇妙なパターンが続きます。アプリは最初の9回ほどのボタン押下/ UUIDの井戸を認識します。その後、通常は10番目のボタンを押すと、アプリケーションはビーコンに応答しなくなります。ポップアップはありません。私のBLEスキャナでは、デバイスが適切に放送されていることがはっきり分かります。デバイスは通常、デバイスが最初のUUIDに戻ってきたときに再びビーコンの認識を開始します。私は '普通に'と言っています。なぜなら時々11番のUUIDで止まり、20番のUUIDで再び始まり、12番のUUIDを無作為に見たとしても、通常はこの間隙または「不感地帯」があります。 UUIDの。私は、ボタンをすばやくマッシュアップすると動作させることができます。ポップアップがすぐに表示され、UUIDのサイクリングが20時まで表示されるので、UUIDの状態が良好で、アプリが可能であることがわかります。この問題は、ボタンの押下間の時間が1分以上ある場合に発生します。 私ができるもう一つの奇妙なことは、ボタンをマッシュして、アプリケーションのポップアップを見て、私がUUIDの「dead zone」の範囲10-20にいるときに停止することです。私が1分待ってからもう一度押すと、7回ボタンを押した後、最初のUUIDに再び到達するまで機能しません。 その他の注意: - 私はいつも地域の出口ポップアップを見ない、時には本当にすぐに終了する、時にはそれは時間がかかる。 - パターンは厳密に一貫していません。それは時々変わる。時にはそれは完全なサイクルのために働くが、通常このギャップパターンに入る。 - iOS 11と10の2台の電話機でテストしています。

アイデア: ほとんどの場合、最初のUUIDで作業を開始するのは奇妙です。だから、これは絶対的なタイミングの問題ではないと思うし、さもなければUUIDリストではなく時間的にギャップが存在すると思います。 すばやくサイクリングされているときに機能するのは奇妙です。

アップルはUUIDをスパムしていると思っているので、10の後に他のUIDをブラックリストに載せていますか。 iOS BLEキャッシングに関する深い問題ですか? iOS BLEバックグラウンドスキャンスケジューラの問題のタイミングに問題はありますか? これはちょうどアプリコードのバグのように聞こえますか?

ありがとうございました!(:CLLocationManager、didRangeBeaconsビーコン:[CLBeacon]、領域内:CLBeaconRegion _マネージャ){

let knownBeacons = beacons.filter{ $0.proximity != CLProximity.unknown } 

    for closestBeacon in knownBeacons 
    { 
     let closestBeaconFound = closestBeacon as CLBeacon 
     var beaconProximity = "" 

     switch (closestBeaconFound.proximity) 
     { 
      case CLProximity.unknown: beaconProximity = "Unknown" 
      case CLProximity.far:  beaconProximity = "Far" 
      case CLProximity.near:  beaconProximity = "Near" 
      case CLProximity.immediate: beaconProximity = "Immediate" 
     } 

     if inDidRangeShowPopup == false{ 
      HelperClass.showAlert(value: "identifier and proximityUUID in did Range: \(region.identifier) \(region.proximityUUID)") 
      inDidRangeShowPopup = true 
      let when = DispatchTime.now() + 5 // change 2 to desired number of seconds 
      DispatchQueue.main.asyncAfter(deadline: when) { 
       inDidRangeShowPopup = false 
      } 
     } 

     let status = "Ranging" 
     let uuid = String(describing: region.proximityUUID) 
     let major = closestBeaconFound.major as! Int 
     let minor = closestBeaconFound.minor as! Int 
     var pressType = "" 

     print("closestBeacon",closestBeaconFound.proximityUUID, closestBeaconFound.major,closestBeaconFound.minor,closestBeaconFound.proximity.rawValue, beaconProximity, closestBeaconFound.accuracy,closestBeaconFound.rssi) 

     let majorHex = String(closestBeaconFound.major as! Int, radix : 2) 
     print("Hex Major : \(majorHex)") 

     let paddedBits = HelperClass.paddedBinaryString(with: majorHex) 
     print("paddedBits : \(paddedBits)") 

     let emergencyCode = paddedBits.substring(to: 8).asBinaryInt() 
     let deviceID = paddedBits.substring(from: 8).asBinaryInt() 


     if emergencyCode == 0 
     { 
      if iBeaconOption1Done == false 
      { 
       iBeaconOption1Done = true 

       let when = DispatchTime.now() + 10 // change 2 to desired number of seconds 
       DispatchQueue.main.asyncAfter(deadline: when) { 
        iBeaconOption1Done = false 
       } 

       for addressStr in HelperClass.getMyMacAddres() 
       { 
        let address = addressStr as! String 
        if address == String(deviceID!) 
        { 
         pressType = "option1" 
         self.setDeviceStatusAndSetTimer(mac_address: address , deviceId : deviceID!, status: status, uuid: uuid, major: major, minor: minor, pressType: pressType) 

         if HelperClass.getAppFlagValueForAttribute (attribute : "isHomeViewed") == true { 

          self.option1Service(flag : "option1", deviceId: deviceID!) 
         } 
         else{ 
          self.option1Service(flag : "test_option1", deviceId: deviceID!) 
         } 
        } 
       } 

      } 
     } 
     else if emergencyCode == 1 
     { 
      print("Call option2") 
      for addressStr in HelperClass.getMyMacAddres() 
      { 
       let address = addressStr as! String 
       if address == String(deviceID!) 
       { 
        pressType = "Option2" 
        self.setDeviceStatusAndSetTimer(mac_address: address , deviceId : deviceID!, status: status, uuid: uuid, major: major, minor: minor, pressType: pressType) 
       } 
      } 
      if HelperClass.getAppFlagValueForAttribute (attribute : "isHomeViewed") == true { 

       self.sendOption2 (flag : "device" ,deviceId : deviceID!) 
      } 
     } 
     else if emergencyCode == 2 
     { 
      print("Call Advertisement") 

      if iBeaconStatusSent == false 
      { 
       iBeaconStatusSent = true 

       let when = DispatchTime.now() + 5 // change 2 to desired number of seconds 
       DispatchQueue.main.asyncAfter(deadline: when) { 
        iBeaconStatusSent = false 
       } 

       for addressStr in HelperClass.getMyMacAddres() 
       { 
        let address = addressStr as! String 
        if address == String(deviceID!) 
        { 
         pressType = "Check in" 
         self.setDeviceStatusAndSetTimer(mac_address: address , deviceId : deviceID!, status: status, uuid: uuid, major: major, minor: minor, pressType: pressType) 
        } 
       } 
      } 
     } 

    } 

} 

FUNCのgetDefaultBeacons()ここ

は、ビーコンのための私のアプリケーションコードは

FUNCのlocationManagerのイベントを紹介あります - > [CLBeaconRegion] {

return [ 

     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+3)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+4)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+5)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+6)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+7)"), 

     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+8)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+9)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+10)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+11)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+12)"), 

     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+13)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+14)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+15)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+16)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+17)"), 

     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+18)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+19)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+20)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+21)"), 
     CLBeaconRegion(proximityUUID: UUID(uuidString: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")!, identifier: "Fl\(BeaconIdentifierIntValue+22)") 
    ] 
} 

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { 

    print("iBeacon delegate:didEnterRegion called") 

    DispatchQueue.main.async() { 

     if let beaconRegion = region as? CLBeaconRegion { 

      print("identifier and proximityUUID in didEnterRegion: \(beaconRegion.identifier) \(beaconRegion.proximityUUID)") 

      HelperClass.showAlert(value: "identifier and proximityUUID in didEnterRegion: \(beaconRegion.identifier) \(beaconRegion.proximityUUID)") 

     } 
     else{ 
      print("Wrong Format in didEnterRegion") 
      Answers.logCustomEvent(withName: "didEnterRegion", customAttributes: [ 
       "error_text": "CLBeaconRegion Object Not Created", 
       "app_version" : AppVersion, 
       "app_build" : AppBuild 
       ]) 
     } 
    } 

} 

FUNCのlocationManager(_マネージャ:CLLocationManager、didExitRegion領域:CLRegion){

print("iBeacon delegate:didExitRegion called") 

    DispatchQueue.main.async() { 

     if let beaconRegion = region as? CLBeaconRegion { 

      print("identifier and proximityUUID in didExitRegion: \(beaconRegion.identifier) \(beaconRegion.proximityUUID)") 

      HelperClass.showAlert(value: "identifier and proximityUUID in didExitRegion: \(beaconRegion.identifier) \(beaconRegion.proximityUUID)") 

     } 
     else{ 
      print("Wrong Format in didExitRegion") 
      Answers.logCustomEvent(withName: "didExitRegion", customAttributes: [ 
       "error_text": "CLBeaconRegion Object Not Created", 
       "app_version" : AppVersion, 
       "app_build" : AppBuild 
       ]) 
     } 
    } 

} 

答えて

1

私は、のコードが、20の領域すべてを登録する前に、領域の制限に達したと思われます。これは、以前に登録された領域をCoreLocationがキャッシュしているために、以前のバージョンのコードとは別の領域が存在する可能性があるためです。

locationManager:monitoringDidFailForRegion:withError:へのコールバックを探して、これが起こっているかどうかをkCLErrorRegionMonitoringFailureエラーコードで確認できます。

実際にそうである場合は、locationManager.monitoredRegionsを呼び出して結果を反復処理し、それぞれに対してlocationManager.stopMonitoring(region: region)を呼び出して、登録済み領域を消去することができます。ただし、にはを指定しないでください。コードを実行するたびにプロセスがクリアされるようにしてください。できるだけ早く地域をオペレーティングシステムに登録し、地域の登録を解除し直してくださいラインの後ろにあなたを置きます。

0

@davidgyougあなたの答えは素晴らしいインスピレーションでした!それは解決されるようです!最初はあなたの提案されたコードはうまくいかなかったが、既に登録されている地域についてのあなたの言及は、私たちがビーコンを監視するために作った別の、しかしまったく異なるテストアプリがあることを実感しました。同じApple ID、Developer、およびTest Flightアカウントに登録されています。そのアプリを削除して、電話を再起動し、locationManagerのキャッシュをクリアすると、それを修正するように見えました!もう一つのヒントは、これまで開発したことのないiPhoneのテストでもうまくいきました。

これは、アプリごとに厳密にではなく、Apple ID /デベロッパーアカウントごとに20の監視領域しか許可されないのでしょうか?地域を監視する他のサードパーティのアプリも電話を妨害する可能性がありますか?

ありがとうございました!

関連する問題