Я использую CLLocation для определения места пользователя в PageViewController и вам нужно использовать возвращаемое местоположение от locationManager(_:didUpdateLocations:)
, записывая в базу данных Realm, а затем используя Realm в моей функции на странице контента PageViewController. Страница содержимого реализована в отдельный исходный файл (контроллер просмотра). так:Как использовать делегаты CLLocation в NSOperation с Realm in swift?
первых, размещение успех,
второй, напишите место в области,
треть, после второго этапа успеха, вызовите функцию содержимого страницы.
И я использую NSOperationQueue с зависимостями для контроля над шагами, но функция делегат locationManager(_:didUpdateLocations:)
кажется, никогда не называет, и вызвать сбой приложения, когда код хочет прочитать данные области действия:
Pls увидеть следующий мой код:
PageViewController
class PageViewController: UIPageViewController {
static var isFirstLaunch: Bool = true
let locationManager: CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 3000
launchQueue = OperationQueue()
let locationOperation = BlockOperation {
OperationQueue.main.addOperation {
self.locationManager.requestLocation()
}
}
locationOperation.completionBlock = {
print("locationOperation finished, finished:\(locationOperation.isFinished)") //"locationOperation finished, finished:true" in console
}
let firstLaunchOperation = BlockOperation {
PageViewController.isFirstLaunch = false
}
firstLaunchOperation.completionBlock = {
print("firstLaunchOperation finished, finished:\(firstLaunchOperation.isFinished)") //"firstLaunchOperation finished, finished:true" in console
}
firstLaunchOperation.addDependency(locationOperation)
launchQueue.addOperation(locationOperation)
launchQueue.addOperation(firstLaunchOperation)
}
ContentViewController (в отдельном исходном файле)
class ContentViewController: UIViewController {
let defaultRealm = try! Realm()
let config = Realm.Configuration(fileURL: Bundle.main.url(forResource: "areaID", withExtension: "realm"), readOnly: true)
override func viewDidLoad() {
super.viewDidLoad()
UISetup()
autolayoutView()
if !PageViewController.isFirstLaunch {
upateWeather()
}
}
func upateWeather() {
let userArea = defaultRealm.objects(UserArea.self)
let place = userArea.first?.areas
let locality = place?[currentPage].locality
let subLocality = place?[currentPage].subLocality
let areaIDRealm = try! Realm(configuration: config)
let results = areaIDRealm.objects(RealmObject.self).filter("locality = '\(locality!)' AND subLocality = '\(subLocality!)'")
//Crashed here! fatal error: unexpectedly found nil while unwrapping an Optional value. I opened the realm, and no locality and subLocality write in the Realm.
}
}
CLLocationManagerDelegate
extension PageViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let currentLocation: CLLocation = locations[0]
let geocoder: CLGeocoder = CLGeocoder()
if currentLocation.horizontalAccuracy > 0 {
geocoder.reverseGeocodeLocation(currentLocation, completionHandler: {(placeMarks, error) in
if error == nil {
guard let placemark = placeMarks!.first else { return }
let userArea = self.defaultRealm.objects(UserArea.self)
func locationToRealm(place: String, subPlace: String) {
if let gpsLocation = userArea.first?.areas.first {
self.defaultRealm.beginWrite()
gpsLocation.locality = place
gpsLocation.subLocality = subPlace
try! self.defaultRealm.commitWrite()
} else {
try! self.defaultRealm.write {
self.defaultRealm.create(UserArea.self, value: [[["locality": place, "subLocality": subPlace]]])
}
}
}
if let place: String = placemark.locality {
if let subPlace: String = placemark.subLocality {
locationToRealm(place: place, subPlace: subPlace)
} else {
locationToRealm(place: place, subPlace: "---")
}
} else {
if let subPlace: String = placemark.subLocality {
locationToRealm(place: "---", subPlace: subPlace)
}
}
}
})
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {......}
}
Как я могу использовать NSOperationQueue контролировать код, сделать их шаг за шагом! Огромное спасибо за помощь!
Я не вижу никакого кода для фактической записи данных в Царство. Когда и как вы это делаете? Что касается сбоя, это звучит как переменная, которую вы предполагаете не-'nil' (я предполагаю, что« locality »или' subLocality') на самом деле является «nil», вызывая и разворачивая исключение. Это может означать, что вам нужно вернуться назад и изучить свою логику более подробно. – TiM
Извините, записи данных в Realm находятся в 'locationManager (_: didUpdateLocations:)' (PLS см. Обновленное описание). Я также думаю, что причина, по которой приложение разбилась, состоит в том, что «locality» и «subLocality» являются «nil». Но как я могу контролировать свой код, чтобы сначала вызывать 'locationManager (_: didUpdateLocations:)', а затем записывать данные в Realm, а затем, наконец, вызвать метод «updateWether» в contentViewController? – stephen
@TiM даже я могу управлять 'self.locationManager.requestLocation()' в Operationqueue, чтобы заставить его вызываться первым, но, похоже, делегат не закончен или даже не вызван. Можно ли управлять 'locationManager (_: didUpdateLocations:)' в зависимости от операции? Очень ценю вашу помощь! – stephen