iOS 定位 location heading beacon 初步定位

本文介绍了iOS设备如何使用location和heading服务进行初步定位,并探讨了Beacon技术在室内导航中的应用,为开发者提供实现精准定位的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<p>
         iOS 8 之后定位需要加字段在info.plst里面,NSLocationAlwaysUsageDescription  一直定位、NSLocationWhenInUseUsageDescription 使用时定位</p><p><span style="white-space: pre;">	</span>苹果目前允许beacon在后台一直搜寻,但是传统的定位会以损耗电池为由拒绝通过。(未验证beacon后台可以上线)</p><p><span style="white-space: pre;">	</span>定位的heading,即方向是不需要用户同意的,判断设备可用即可。</p><p><span style="white-space: pre;">	</span>接下来附demo</p>
#define myUUID  @"AB8190D5-D11E-4941-ACC4-42F30510B408"

- (void)viewDidLoad {
    [super viewDidLoad];
    NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:myUUID];
    _myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"test"];
    _myBeaconRegion.notifyOnEntry = YES;
    _myBeaconRegion.notifyOnExit = YES;
    _myBeaconRegion.notifyEntryStateOnDisplay = YES;
    [self createLocationManager];
    self.countryLabel.text = @"正在检测";
    self.cityLabel.text = @"正在检测";
    _mutArray = [NSMutableArray array];
}
#pragma mark - createLocationManager
-(void)createLocationManager{
    _manager = [MyCLLocationManager sharedManager];
    _manager.delegate = self;
    _manager.desiredAccuracy = kCLLocationAccuracyKilometer;
    //ignore filter  default kCLDistanceFilterNone will report any change
    _manager.distanceFilter = 500;
    _bluetoothManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
    //request device location available
    if ([CLLocationManager locationServicesEnabled]) {
        //request location available
        int status = [CLLocationManager authorizationStatus];
        //status == 0 neverSet
        if (status == 0) {
            [_manager requestAlwaysAuthorization];
        }
        if ([CLLocationManager headingAvailable]) {
            [_manager startUpdatingHeading];
        }else{
            [_manager stopUpdatingHeading];
        }
        /*
         status == 3 alwaysLocation
         status == 4 WhenInUseLocation
         */
        if (status >= 3) {
            [_manager startRangingBeaconsInRegion:_myBeaconRegion];
            _myGeocoder = [[CLGeocoder alloc]init];
            
        }else{
            [_manager stopUpdatingLocation];
        }
    }
}

#pragma mark - CLLocationDelegate
//start Location
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
//    CLGeocoder
    CLLocation *currentLocation = [locations lastObject];
    if (currentLocation.horizontalAccuracy > 0) {
        float longitude = currentLocation.coordinate.longitude;
        float latitude = currentLocation.coordinate.latitude;
        NSString *longitudeStr = [NSString stringWithFormat:@"东经%.2f",currentLocation.coordinate.longitude];
        NSString *latitudeStr = [NSString stringWithFormat:@"北纬%.2f",currentLocation.coordinate.latitude];
        if (!longitude > 0) {
            longitudeStr = [NSString stringWithFormat:@"西经%.2f",currentLocation.coordinate.longitude];
        }
        if (!latitude > 0) {
            latitudeStr = [NSString stringWithFormat:@"南纬%.2f",currentLocation.coordinate.latitude];
        }
        [self reverseGeocodeLocation:currentLocation];
    }
    if (currentLocation.verticalAccuracy > 0) {
        NSString *elevationStr = [NSString stringWithFormat:@"海拔%.1f米",currentLocation.altitude];
    }
}
//start heading
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
    if (newHeading.headingAccuracy >= 0) {
        float magneticHeading = newHeading.magneticHeading;
        NSString *direction = [NSString string];
        if (magneticHeading < 90) {
            direction = @"北";
        }else if (magneticHeading > 90 && magneticHeading < 180){
            direction = @"东";
            magneticHeading = magneticHeading - 90;
        }else if (magneticHeading > 180 && magneticHeading < 270){
            direction = @"南";
        }else if (magneticHeading > 270){
            direction = @"西";
            magneticHeading = magneticHeading - 270;
        }
    }
}
//
-(BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager{
    return NO ;
}

#pragma mark - CLGeocoder
-(void)reverseGeocodeLocation:(CLLocation *)CLLocation{
    [_myGeocoder reverseGeocodeLocation:CLLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (error == nil && [placemarks count] > 0) {
            CLPlacemark *placekmark = [placemarks objectAtIndex:0];
//            NSLog(@"%@",placekmark);
            self.countryLabel.text = placekmark.locality;
            self.cityLabel.text = placekmark.subLocality;
            self.nameLabel.text = placekmark.name;
        }
        else if(error == nil && [placemarks count] == 0){
            NSLog(@"No resulte were returned");
        }
        else if(error != nil){
            NSLog(@"error:%@",error);
        }
    }];
}

#pragma mark - CLLocationStatus
//changeStatus
-(void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    if (status >= 3) {
        [_manager startUpdatingLocation];
        [_manager startMonitoringForRegion:_myBeaconRegion];
    }else{
        //兼容ios8以下
//        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"打开定位" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
//        [alertView show];
        [_manager stopUpdatingLocation];
    }
    NSLog(@"%d",status);
}
#pragma mark - beaconDelegate
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
    NSLog(@"\nEnter BeaconRegion\n");
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region{
    NSMutableArray *array = [NSMutableArray array];
    for (CLBeacon *item in beacons) {
        BeaconItem *oneItem = [[BeaconItem alloc]init];
        oneItem.uuid = [NSString stringWithFormat:@"%@",item.proximityUUID];
        oneItem.major = [item.major stringValue];
        oneItem.minor = [item.minor stringValue];
        oneItem.rssi = item.rssi;
        [array addObject:oneItem];
    }
    _mutArray = array;
//    [self registerLocalNotification];
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
    NSLog(@"\nExit BeaconRegion\n");
}

//failLocation
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    NSLog(@"%@",error);
}


#pragma mark - bluetoothManagerDelegate
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    switch (peripheral.state) {
        case CBPeripheralManagerStatePoweredOn:
        {
            NSLog(@"蓝牙打开可用");
        }
            break;
        case CBPeripheralManagerStatePoweredOff:
            NSLog(@"蓝牙关闭");
            break;
        default:
            NSLog(@"蓝牙不可用");
            break;
    }
}


#pragma mark - memoryWarning
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

有一些属性是在storyboard上创建的label拖过来的,没有意义,可以打印替换。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值