2015-07-10 35 views
8

iOS ve iBeacon ile çalışırken gerçekten garip bir hata yaşıyorum. Belirli UUID, büyük ve küçük değerler ile işaretçileri sıralayan ve onları bulduğunda bazı eylemler gerçekleştiren gerçekten basit bir BeaconManager var. Uygulamam sürekli olarak Bluetooth durumunu değiştirip işini yapmayı bırakana kadar düzgün çalışıyor gibi görünüyor. Görülebilen tek sonuç, Bluetooth'un durması ve yeniden başlatılması nedeniyle durum çubuğundaki Bluetooth simgesinin yanıp sönmesidir.Neden fenerler Bluetooth'un sürekli olarak değişmesine neden oluyor?

Dikkat nereye odaklanır?

Bu

benim sınıf tanımı şöyledir:

#import "BeaconManager.h" 

@implementation BeaconManager 

- (instancetype)init { 
    self = [super init]; 
    if (self) { 
     NSURL *beep = [[NSBundle mainBundle] URLForResource:@"beep" withExtension:@"aiff"]; 
     soundFileURLRef = (CFURLRef) CFBridgingRetain(beep); 
     AudioServicesCreateSystemSoundID(soundFileURLRef, &soundFileObject); 

     // Initializes properties 
     beacon = [CLBeacon new]; 
     foundBeacons = [NSMutableArray new]; 
     _lastBeaconActionTimes = [[NSMutableDictionary alloc] init]; 
    } 
    return self; 
} 

- (void)initRegion { 
    // Initializes the beacon region by giving it an UUID and an identifier 
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACON]; 
    beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"beacon.region"]; 
    // Starts looking for beacon within the region 
    [self.locationManager startMonitoringForRegion:beaconRegion]; 
} 

- (void)checkBeacon { 
    if (!self.locationManager) { 
     self.locationManager = [[CLLocationManager alloc] init]; 
     self.locationManager.delegate = self; 

     if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) 
      [self.locationManager requestWhenInUseAuthorization]; 
    } 
    [self initRegion]; 
    [self locationManager:self.locationManager didStartMonitoringForRegion:beaconRegion]; 
} 

#pragma mark - CLLocationManagerDelegate 

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

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

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

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error { 
    NSLog(@"Failed monitoring region: %@", error); 
} 

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

- (void)locationManager:(CLLocationManager *)manager 
     didRangeBeacons:(NSArray *)beacons 
       inRegion:(CLBeaconRegion *)region { 

    if (foundBeacons.count == 0) { 
     for (CLBeacon *filterBeacon in beacons) { 
      // If a beacon is located near the device and its major value is equal to 1000 (MAJOR constant) 
      if (((filterBeacon.proximity == CLProximityImmediate) || (filterBeacon.proximity == CLProximityNear))) 
       // Registers the beacon to the list of found beacons 
       [foundBeacons addObject:filterBeacon]; 
     } 
    } 
    // Did some beacon get found? 
    if (foundBeacons.count > 0) { 
     // Takes first beacon of the list 
     beacon = [foundBeacons firstObject]; 

     if (([beacon.major isEqualToNumber:[NSNumber numberWithInt:MAJOR]]) && ([beacon.minor isEqualToNumber:[NSNumber numberWithInt:MINOR]])) { 
      // Takes the actual date and time 
      NSDate *now = [[NSDate alloc] init]; 
      NSString *key = [NSString stringWithFormat:@"%@ %@ %@", [beacon.proximityUUID UUIDString], beacon.major, beacon.minor]; 
      NSDate *lastBeaconActionTime = [_lastBeaconActionTimes objectForKey:key]; 
      if ((lastBeaconActionTime == nil) || ([now timeIntervalSinceDate:lastBeaconActionTime] > MINIMUM_ACTION_INTERVAL_SECONDS)) { 
       [_lastBeaconActionTimes setObject:now forKey:key]; 
       // Plays beep sound 
       AudioServicesPlaySystemSound(soundFileObject); 

       if (self.delegate) { 
        // Performs actions related to the beacon (i.e. delivers a coupon) 
        [self.delegate didFoundBeacon:self]; 
       } 
       self.locationManager = nil; 
      } 
      // else [self.locationManager stopMonitoringForRegion:region]; 
     } 
     [foundBeacons removeObjectAtIndex:0]; 
     beacon = nil; 
    } 
} 
@end 
+0

Bu hangi bir cihazdır? Herhangi bir Bluetooth çevre birimine (örn. Akıllı saat veya Bluetooth kulaklık) bağlı mısınız? Simgesinin titrek olduğunu söylediğinizde, bunun rengi değiştirdiğini mi, yoksa görünmeye ve kaybolmaya devam ettiğini mi kastediyorsunuz? – heypiotr

+0

@heypiotr iOS 8.3 ile bir iPhone 6 ve başka bir Bluetooth cihazına bağlı değil. Ayrıca, müdahaleleri önlemek için uygulamanın temiz bir yapısını yapıyorum. Bluetooth simgesi görünmeye ve çok hızlı kaybolan tutar. – Dree

+0

Uygulamanızı başka bir cihazda test edip aynı olup olmadığını görme şansınız var mı? Bu, olası bir donanım sorunu gibi görünüyor. Core Location veya başka bir beacon SDK kullanıyor musunuz? – heypiotr

cevap

1

Bluetooth geçiş tutar, ancak bu kısım kesinlikle şüpheli neden nedeni budur kesin diyemeyiz:

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

Bu temelde bir olduğunu sonsuz döngü. Bir kez başladığında izlenmesi, iOS iOS tekrar didStartMonitoring yöntemi çağırmak yapar aynı bölgede, için izlenmesi başlar didStartMonitoring yöntemi ... ... çağırır

Ben senin bu kod bölümünden startMonitoringForRegion hattını çıkarmadan başlardım .

+0

Tamam, şimdi bir ahmak davranışı var gibi görünüyor. Her neyse, Bluetooth, "didFoundBeacon:" yöntemiyle ilişkili görüntü denetleyicisini hemen reddetmezse yine de hızlı bir şekilde bir kez değişiyor. Görünüm denetleyicisi, bir modal segue ve görüntü denetleyicisini kapatan bir düğme içeren bir etiketi gösterir. Test amacıyla, uyarı her 60 saniyede bir gösterilir, bu yüzden zamanlayıcı bitmeden önce reddetmezsem, görüntüleme denetleyicileri yığılır. Gerçek kullanım için zamanlayıcı uzunluğu daha büyük olmalıdır (yaklaşık 30 dakika). İlgili bir sorun olabilir mi? – Dree

+0

Yardımlarınız için teşekkür ederim, minnettarım. – Dree