2014-12-30 3 views
1

У меня случился сбой в моем приложении, когда locationManager.location еще не инициализирован, когда я делаю свой регион для увеличения.Проверка наличия CLLocationManager.location nil

override func viewDidLoad() { 
    ... 
    let regionToZoom = MKCoordinateRegionMake(locationManager.location.coordinate, MKCordinateSpanMake(0.01, 0.01)) 
    mkMapView.setRegion(regionToZoom, animated: true) 
} 

Изначально я просто хотел сделать простой бесконечное время цикла, как это:

override func viewDidLoad() { 
    ... 
    while (true) { 
     if locationManager.location != nil { 
      println("locationManager is ready, carrying on") 
      let regionToZoom = MKCoordinateRegionMake(locationManager.location.coordinate, MKCoordinateSpanMake(0.01, 0.01)) 
      var timer:NSTimer? = nil 
      break 
     } else { 
      println("locationManager is nil, waiting 2000ms") 
      sleep(2) 
    } 
    ... 
} 

Однако затем произошли две вещи. Предстоящий вызов mkMapView.setRegion() жаловался на то, что не смог увидеть regionToZoom, поэтому я не был уверен, как правильно сделать его видимым вне цикла, поэтому я просто поместил все внутри цикла while. Это сработало. Однако теперь я читаю, что если в любое время я хочу использовать сон в Swift, я, вероятно, должен использовать NSTimer. Поэтому я наигрывал этот:

var timer:NSTimer? = nil 

override func viewDidLoad() { 
    ... 
    self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkLOCMAN"), userInfo: nil, repeats: true) 

    let regionToZoom = MKCoordinateRegionMake(locationManager.location.coordinate, MKCoordinateSpanMake(0.01, 0.01)) 
    ... 
} 
// Function to check 
func checkLOCMAN() { 
     if locationManager.location != nil { 
      println("locationManager.location is set, carrying on") 
      self.timer?.invalidate() 
     } else { 
      println("locationManager.location is nil, waiting 2000ms") 
    } 
} 

Но это не решает проблему, если locationManager равна нулю она по-прежнему падает. Я думаю, что я слишком много подхожу к сценарию, потому что это не похоже на то, когда он запускает мой NSTimer, он ждет, но вместо этого продолжает выполнять строки кода после этого.

Есть ли способ, которым я могу заставить это работать? Я просто хочу, чтобы он продолжал проверять locationManager.location, пока он не будет инициализирован до запуска mkMapView.setRegion().

Я все еще новичок в Swift, поэтому я мог бы переусердствовать над этой проблемой.

ответ

4

Вы не хотите предполагать, что менеджер местоположения будет иметь действительный location. Вы также не хотите иметь петлю while или таймер, ожидающий ее.

То, что вы хотите сделать, это начать службы определения местоположения в viewDidLoad, запросить разрешение на месте службы с requestWhenInUseAuthorization или requestAlwaysAuthorization (гарантируя, что соответствующая PLIST строка для NSLocationWhenInUseUsageDescription или NSLocationAlwaysUsageDescription ключей были установлена), а затем ждать didUpdateLocations способа CLLocationManagerDelegate быть вызванным. Только тогда у вас будет действующее место.

+0

Обратите внимание, что если вы поддерживаете iOS7, вам также не нужно запрашивать авторизацию в этих более ранних версиях, но вам все равно нужно запустить службы определения местоположения и ждать события местоположения. – Rob

+0

Спасибо, Роб! Я следовал твоим советам, и это сработало. Я знал, что должен был быть лучший способ сделать то, что я делаю. – rusty

1

Ваш крах, вероятно, происходит из-за этой линии:

let regionToZoom = MKCoordinateRegionMake(locationManager.location.coordinate, MKCoordinateSpanMake(0.01, 0.01)) 

так locationManager.location.coordinate равна нулю.

Хотя я 100% согласен с ответом Роба с точки зрения стиля и думаю, что вы должны поставить regionToZoom линию в didUpdateLocations, если вы хотите сохранить ваш текущий код, избегая ошибок, вы могли бы технически сделать это:

if locationManager.location != nil { 
    let regionToZoom = MKCoordinateRegionMake(locationManager.location.coordinate, MKCoordinateSpanMake(0.01, 0.01)) 
} else { 
    self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkLOCMAN"), userInfo: nil, repeats: true) 
} 
+0

Спасибо, я знал, что что-то переусердствовал. Я переместил MKCoordinateRegionMake и последующие вызовы функций области на мои didUpdateLocations, и это исправлено! Благодаря! – rusty

Смежные вопросы