Делегат должен ответить на locationManager:didUpdateLocations swift eroor
Привет, ребята, я делаю приложение в Swift 3.0, но довольно скоро столкнулся с проблемой. Я настроил необходимые функции, чтобы запросить разрешение на использование местоположения, но каждый раз, когда я запускаю приложение, я получаю ту же ошибку...
Viewcontroller.h
import UIKit
import MapKit
class ViewController: UIViewController {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController : CLLocationManagerDelegate {
private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
locationManager.requestLocation()
}
}
private func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.first != nil {
print("location:: (location)")
}
}
private func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("error:: (error)")
}
}
Ошибка:
2016-10-31 16:12:11.436192 Assemble[57741:2743477] bundleid: com.AssembleTm.Assemble, enable_level: 0, persist_level: 0, propagate_with_activity: 0
2016-10-31 16:12:11.437006 Assemble[57741:2743477] subsystem: com.apple.siri, category: Intents, enable_level: 1, persist_level: 1, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0, enable_private_data: 0
2016-10-31 16:12:11.524494 Assemble[57741:2743668] subsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0
2016-10-31 16:12:11.526709 Assemble[57741:2743668] subsystem: com.apple.UIKit, category: HIDEventIncoming, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0
2016-10-31 16:12:11.561488 Assemble[57741:2743658] subsystem: com.apple.BaseBoard, category: MachPort, enable_level: 1, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0, enable_private_data: 0
2016-10-31 16:12:11.638717 Assemble[57741:2743477] subsystem: com.apple.UIKit, category: StatusBar, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0
2016-10-31 16:12:11.744 Assemble[57741:2743477] *** Assertion failure in -[CLLocationManager requestLocation], /BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreLocationFramework_Sim/CoreLocation-2100.0.12/Framework/CoreLocation/CLLocationManager.m:865
2016-10-31 16:12:11.855 Assemble[57741:2743477] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Delegate must respond to locationManager:didUpdateLocations:'
*** First throw call stack:
(
0 CoreFoundation 0x000000010a58d34b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010873b21e objc_exception_throw + 48
2 CoreFoundation 0x000000010a591442 +[NSException raise:format:arguments:] + 98
3 Foundation 0x0000000106799edd -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 CoreLocation 0x0000000106291523 CLClientGetCapabilities + 13233
5 Assemble 0x00000001061e1976 _TFC8Assemble14ViewController11viewDidLoadfT_T_ + 294
6 Assemble 0x00000001061e19e2 _TToFC8Assemble14ViewController11viewDidLoadfT_T_ + 34
7 UIKit 0x000000010708f06d -[UIViewController loadViewIfRequired] + 1258
8 UIKit 0x000000010708f4a0 -[UIViewController view] + 27
9 UIKit 0x0000000106f59045 -[UIWindow addRootViewControllerViewIfPossible] + 71
10 UIKit 0x0000000106f59796 -[UIWindow _setHidden:forced:] + 293
11 UIKit 0x0000000106f6d0a9 -[UIWindow makeKeyAndVisible] + 42
12 UIKit 0x0000000106ee6259 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4818
13 UIKit 0x0000000106eec3b9 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1731
14 UIKit 0x0000000106ee9539 -[UIApplication workspaceDidEndTransaction:] + 188
15 FrontBoardServices 0x000000010e1cf76b __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
16 FrontBoardServices 0x000000010e1cf5e4 -[FBSSerialQueue _performNext] + 189
17 FrontBoardServices 0x000000010e1cf96d -[FBSSerialQueue _performNextFromRunLoopSource] + 45
18 CoreFoundation 0x000000010a532311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
19 CoreFoundation 0x000000010a51759c __CFRunLoopDoSources0 + 556
20 CoreFoundation 0x000000010a516a86 __CFRunLoopRun + 918
21 CoreFoundation 0x000000010a516494 CFRunLoopRunSpecific + 420
22 UIKit 0x0000000106ee7db6 -[UIApplication _run] + 434
23 UIKit 0x0000000106eedf34 UIApplicationMain + 159
24 Assemble 0x00000001061e3fcf main + 111
25 libdyld.dylib 0x000000010af5b68d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Я новичок в Swift 3.0, но я не смог найти ничего, как решить эту проблему (я уже посмотрел его на stackru, но ответ, который они дали, не помог мне...)
7 ответов
Вы используете xcode8 и swift3, но ваши методы делегата копируются из swift 2. Измените методы делегата, как показано ниже.
extension ViewController : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error:: \(error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
locationManager.requestLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.first != nil {
print("location:: (location)")
}
}
}
Эту ошибку можно получить, если вы запрашиваете местоположение у менеджера местоположений, и его делегат равен нулю. Убедитесь, что вы всегда устанавливаете делегата перед вызовом любого запроса местоположения.
import UIKit
import CoreLocation
class ViewController: UIViewController {
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
}
}
extension ViewController : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
print("Location data received.")
print(location)
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Failed to get users location.")
}
}
Делегат должен быть назначен перед вызовом функции requestLocation(), потому что после завершения requestLocation() он вызовет didUpdateLocations, но для вызова didUpdateLocations он должен знать, какой объект didUpdateLocations вызывается. Чтобы уточнить, что для компилятора используется
locationManager.delegate = self до вызова locationManager.requestLocation().
В расширении протокола CLLocationManagerDelegate реализуйте didUpdateLocations и didFailWithError.
Другая возможная причина ошибки заключается в том, что у вас есть только метод для
locationManager(_:didUpdateLocations:)
и вам не хватает метода для
locationManager(_:didFailWithError:)
Согласно документации requestLocation()
:
При использовании этого метода связанный делегат должен реализовать методы locationManager (: didUpdateLocations:) и locationManager (: didFailWithError:). Невыполнение этого требования - ошибка программиста.
Это сработало для меня
import UIKit
import CoreLocation
class WeatherViewController: UIViewController {
@IBOutlet weak var conditionImageView: UIImageView!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var cityLabel: UILabel!
@IBOutlet weak var searchInputField: UITextField!
var weatherManager = WeatherManager()
var locationManager=CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.searchInputField.delegate=self
weatherManager.delegate=self
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
// Do any additional setup after loading the view.
}
}
extension WeatherViewController : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error:: \(error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
locationManager.requestLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.first != nil {
print("location:: \(locations[0])")
}
}
}
Как упоминалось в этом ответе , ваша проблема может быть похожа на мою, имея свой собственный
Error
класс, который конфликтует с
Swift.Error
func locationManager(_ manager: CLLocationManager, didFailWithError error: Swift.Error) {
Перепробовал все способы выше. И обнаружил, что для этого необходимы следующие 2 шага.
Установка свойства делегата на себя
locationManager.delegate = self
Добавление метода делегата DidFailWithError, даже если не требуется конкретной реализации.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Failed") }