为什么它找不到我的信标?

时间:2014-07-10 13:52:11

标签: ios bluetooth-lowenergy ibeacon

我正在编写需要在设备周围找到BLE信标的Android和iOS应用程序。

当我从Android运行我的代码时,它会在我所在的房间里找到几个信标。

我有8个信标。

当我从iPhone运行信标代码时,它会返回一个恰好为0个信标的列表。

这是我的代码:

    - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self initRegion];
    [self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion];
}

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}

- (void)initRegion {
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACONUUID];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:BEACONIDENTIFIER];
    [self.locationManager startMonitoringForRegion:self.beaconRegion];

}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
    NSLog(@"Beacon Found");
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
    NSLog(@"Left Region");
    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
    self.beaconFoundLabel.text = @"No";
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
    CLBeacon *beacon = [beacons lastObject];//<== is always 0

    self.beaconFoundLabel.text = @"Yes";
    self.proximityUUIDLabel.text = beacon.proximityUUID.UUIDString;
    self.majorLabel.text = [NSString stringWithFormat:@"%@", beacon.major];
    self.minorLabel.text = [NSString stringWithFormat:@"%@", beacon.minor];
    self.accuracyLabel.text = [NSString stringWithFormat:@"%f", beacon.accuracy];
    if (beacon.proximity == CLProximityUnknown) {
        self.distanceLabel.text = @"Unknown Proximity";
    } else if (beacon.proximity == CLProximityImmediate) {
        self.distanceLabel.text = @"Immediate";
    } else if (beacon.proximity == CLProximityNear) {
        self.distanceLabel.text = @"Near";
    } else if (beacon.proximity == CLProximityFar) {
        self.distanceLabel.text = @"Far";
    }
    self.rssiLabel.text = [NSString stringWithFormat:@"%ld", (long)beacon.rssi];
}

在我的didRangeBeaconsInRegion中,信标NSArray总是会出现0个对象。 虽然我有8个物体。我已经下载了几个不属于我的应用程序,他们都看到了我的几个信标。

为什么我的代码不能看到我的任何信标?

4 个答案:

答案 0 :(得分:2)

这是我在设置iBeacon应用程序时所做的事情。

并非所有这些都是必要的,但它会

  1. 工作
  2. 让您的用户满意
  3. (也许最重要的是)让Apple快乐

  4. 仅限iOS 8+

    首先要做的事情是:如果您使用的是iOS 8,则需要确保在使用CLLocationManager之前确实具有访问权限。

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    
    // You can either use requestAlwaysAuthorization, or requestWhenInUseAuthorization
    [self.locationManager requestAlwaysAuthorization];
    

    你的plist中还需要NSLocationAlwaysUsageDescription的条目(仅限iOS 8)


    iOS 7 +

    您应用的pList

    无论您使用的是iOS 8还是7,都应该将以下内容添加到plist文件中(您需要决定是否使用背景)。

    注意: 以下是KEY的形式:KEY TYPE:VALUE表示字符串,KEY:KEY TYPE:[Value1,Value2 .. 。] for Arrays

    NSLocationUsageDescription : String : "Gimmie access to your location or else..."
    NSBluetoothPeripheralUsageDescription : String : "Gimmie access to your blue tooth or else"
    
    // Optionally supply if you need background modes.  I don't believe you need this either if you plan to turn these options on using the Capabilities section of your App's Settings (see below section)
    UIBackgroundModes : Array : [ location, bluetooth-central ]
    UIApplicationExitsOnSuspend : Boolean : NO
    



    您应用的项目设置(功能)

      

    此部分已被删除,因为这可能导致您的应用被拒绝(正如@heypiotr在评论中所述)


    最后的想法

    最后的建议是尝试将[self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion]移到viewDidAppear

    这是我通常做的一个例子(对我来说效果很好)。

    -(void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
    
        [self initLocationManager];
        [self initBeaconRegion];
        [self startMonitoring];
    }
    
    -(void)initLocationManager {
    
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
    
        // Not necessary, but I like to do it.
        if( ![CLLocationManager locationServicesEnabled] ) {
            [self.locationManager startUpdatingLocation];
        }
    
        // Only necessary if you're in iOS 8.  Checking for existence though to support iOS 7
        if( ![CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized ) {
            if ([CLLocationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
                [self.locationManager performSelector:@selector( requestAlwaysAuthorization )];
            }
        }
    }
    
    -(void)initBeaconRegion {
    
        NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:kYOUR_UUID_HERE];
    
        self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:kYOUR_IDENTIFIER_HERE];
    
        // Change this to whatever you want....
        self.beaconRegion.notifyEntryStateOnDisplay = YES;
        self.beaconRegion.notifyOnEntry = NO;
        self.beaconRegion.notifyOnExit = YES;
    }
    
    
    # pragma mark -
    # pragma mark Monitoring Beacons
    # pragma mark -
    
    -(void)startMonitoring {
        // Monitor Beacon signals around me and report them back to me
        [self.locationManager startMonitoringForRegion:self.beaconRegion];
    }
    

    最后一部分(viewDidAppear中的位置)可能会有所帮助 - 也可能没有帮助 - 这完全取决于我想在stackoverflow响应中需要考虑的因素太多。

    希望有所帮助,祝你好运!

    最终编辑

    忘了一件可能有帮助的事情。您可以实现一些有用的方法,可以帮助您进一步调试问题。以下是其中一些例子:

    #pragma mark Authorization Status Changed
    -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    
        if( ![CLLocationManager locationServicesEnabled] ) {
            NSLog(@"Couldn't turn on ranging: Location services are not enabled.");
        } else {
            NSLog(@"Location services ARE enabled.");
        }
    
        if( [CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized ) {
            NSLog(@"Couldn't turn on monitoring: Location services not authorized.");
        } else {
            NSLog(@"Location services ARE authorized.");
        }
    }
    
    
    #pragma mark -
    #pragma mark CLLocationManager Errors
    #pragma mark -
    
    -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
        NSLog( @"FAIL ERROR: %@", [error description] );
    }
    
    -(void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion (CLBeaconRegion *)region withError:(NSError *)error {
        NSLog( @"RANGE BEACONS ERROR: %@", [error description] );
    }
    

答案 1 :(得分:1)

首先检查其他应用,例如。Locate app添加您的UDID并检查此应用是否显示您的iBeacon。如果没有那么苹果IOS有时会出现问题。然后删除该应用程序。重启应用。它会对你有用。

答案 2 :(得分:0)

我们之前遇到过类似的问题,请确保您的iBeacon设备响应来自iOS的扫描请求,但不包含制造商特定字段。

答案 3 :(得分:0)

请查看苹果的这个说明

在尝试监控任何区域之前,您的应用应检查当前设备是否支持区域监控。以下是可能无法进行区域监控的一些原因:

  1. 设备没有必要的硬件来支持区域 监控。
  2. 用户拒绝了应用授权使用区域监控。

  3. 用户在“设置”应用中停用了位置服务。

  4. 用户在设置应用中为设备或应用禁用了后台应用刷新。

  5. 5.设备处于飞行模式,无法为必要的硬件供电。

    在iOS 7.0及更高版本中,在尝试监控区域之前,始终调用isMonitoringAvailableForClass:的{​​{1}}和authorizationStatus类方法。 (在OS X v10.8及更高版本以及之前版本的iOS中,请改用CLLocationManager类。)regionMonitoringAvailable方法告诉您底层硬件是否支持指定类的区域监视。如果该方法返回NO,则您的应用无法在设备上使用区域监控。如果返回YES,则调用authorizationStatus方法以确定该应用程序当前是否有权使用位置服务。如果授权状态为isMonitoringAvailableForClass:,您的应用可以接收其注册的任何地区的过境通知。如果授权状态设置为任何其他值,则应用程序不会收到这些通知。 Apple link goes here