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
])
}
}
}