Пытаюсь сделать Geofence в Swift 4, но у меня проблема, у меня ошибка при вызове locationManager, не понимаю почему выдает эту ошибку
это ошибка:
Ambiguous use of locationManager
Я пытался исправить это, поместив self.locationManager.startUpdatingLocation() и другие разные методы, но ни один из них не работал
Здесь я объявляю свою переменную locationManager:
var locationManager = CLLocationManager()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate{
locationManager = appDelegate.locationManager
locationManager.delegate = self
}
Это блок кода, где я получаю сообщение об ошибке:
if let locationManager = self.locationManager{
let region = self.regionToMonitor()
if (locationManager.monitoredRegions.count > 0){
self.geofencesLabel.text = "Geofences OFF"
locationManager.stopMonitoring(for: region)
mapView.removeOverlays(mapView.overlays)
}else{
self.geofencesLabel.text = "Geofences ON"
locationManager.startMonitoring(for: region)
mapView.add(MKCircle(center: region.center, radius: region.radius))
nombreU.isHidden = true
empresaU.isHidden = true
correoElectronicoU.isHidden = true
telefonoU.isHidden = true
//Generamos el registro en la base de datos local en el servidor
let nombreEvento = self.nombreE
let nombreOficial = self.nombreO
let fechaEvento = self.fechaE
let fechaFormato = self.fechaF
let lugarEvento = self.lugarE
let descripcionEvento = self.descripcionE
let imagenEvento = self.imagenE
let latitudEvento = self.latitudE
let longitudEvento = self.longitudE
let empresaEvento = self.empresaE
let rolEvento = self.rolE
//Recuperamos el contenido de las cajas de texto para validarlo
let nombreC = self.nombreU.text!
let empresaC = self.empresaU.text!
let correoC = self.correoElectronicoU.text!
let telefonoC = self.telefonoU.text!
//Validamos que no este vacio ninguna de los datos recibidos del servidor y ninguna de las cajas de texto
if (nombreC.isEmpty || empresaC.isEmpty || correoC.isEmpty || telefonoC.isEmpty){
displayMyAlertMessage(userMessage: "Todos los campos deben ser llenados")
return
}
if (nombreEvento.isEmpty || nombreOficial.isEmpty || fechaEvento.isEmpty || fechaFormato.isEmpty || lugarEvento.isEmpty || descripcionEvento.isEmpty){
displayMyAlertMessage(userMessage: "Ocurrio un error al cargar los eventos")
dismiss(animated: true, completion: nil)
return
}
//Ingresamos los valores a la base de datos local
let newEvento = NSEntityDescription.insertNewObject(forEntityName: "Eventos", into: context)
newEvento.setValue(nombreEvento, forKey: "nombreE")
newEvento.setValue(nombreOficial, forKey: "nombreO")
newEvento.setValue(fechaEvento, forKey: "fechaE")
newEvento.setValue(fechaFormato, forKey: "fechaF")
newEvento.setValue(lugarEvento, forKey: "lugarE")
newEvento.setValue(descripcionEvento, forKey: "descripcionE")
newEvento.setValue(imagenEvento, forKey: "imagenE")
newEvento.setValue(latitudEvento, forKey: "latitudE")
newEvento.setValue(longitudEvento, forKey: "longitudE")
newEvento.setValue(empresaEvento, forKey: "empresaE")
newEvento.setValue(rolEvento, forKey: "rolE")
nombreU.isHidden = true
empresaU.isHidden = true
correoElectronicoU.isHidden = true
telefonoU.isHidden = true
//Mostramos mensaje de que ya estas registrado
mensajeRegistro.text = "Gracias por registrarte a nuestro evento"
mensajeRegistro.isHidden = false
do{
try context.save()
print("El registro al evento se realizo de forma correcta")
}catch{
print(error)
}
//Ejecutamos el codigo del WebService
guard let url = URL(string: "http://www.sitioweb.mx/webservice/registro.php?nombre=\(nom)&empresa=\(empresaC)&correo=\(corC)&telefono=\(telC)") else { return }
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
if let response = response {
print(response)
}else{
print(error!)
}
}
}
}else{
notify(msg: "El geofence no esta disponible")
}
Мой класс имеет это расширение:
// MARK: - Location Manager Delegate
extension RegistroViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
mapView.showsUserLocation = status == .authorizedAlways
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
print("Monitoring failed for region with identifier: \(region!.identifier)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location Manager failed with the following error: \(error)")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Location update")
}
}
Я не понимаю, что не так или на какой метод я должен ссылаться при вызове self.locationManager
Это мой Appdelegate:
import UIKit
import CoreData
import CoreLocation
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
static var menu_bool = true
static var menu_boolS = true
let locationManager = CLLocationManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
locationManager.delegate = self as? CLLocationManagerDelegate
locationManager.requestAlwaysAuthorization()
let options: UNAuthorizationOptions = [.badge, .sound, .alert]
UNUserNotificationCenter.current().requestAuthorization(options: options){ success, error in
if let error = error{
print("Error: \(error)")
}
}
return true
}
Просто только в этом
И создается ли этот контроллер представления при запуске приложения?
Вы имеете в виду, находитесь ли вы в Appdelegate?
Настройка менеджера местоположений должна быть одной из самых первых вещей, которые делает приложение, потому что получение точного местоположения — это асинхронное событие (и это может занять некоторое время). Поэтому, если этот контроллер представления запускается при запуске приложения, и только этому контроллеру представления требуется местоположение устройства, то я думаю, что можно обрабатывать местоположение в этом контроллере представления. Однако, если оба из них неверны, я бы настроил местоположение в делегате приложения.
locationManager.delegate = self as? CLLocationManagerDelegate
неверно. Делегат приложения должен соответствовать этому протоколу; вы не должны кастовать делегата as? CLLocationManagerDelegate
. Удалите расширение делегата CLLocationManagerDelegate
в RegistroViewController
и обработайте все делегирование местоположения в делегате приложения.
Если locationManager
является свойством экземпляра, используйте его напрямую
let locationManager = CLLocationManager()
let region = self.regionToMonitor()
if (locationManager.monitoredRegions.count > 0){
self.geofencesLabel.text = "Geofences OFF"
locationManager.stopMonitoring(for: region)
mapView.removeOverlays(mapView.overlays)
}else{
self.geofencesLabel.text = "Geofences ON"
locationManager.startMonitoring(for: region)
mapView.add(MKCircle(center: region.center, radius: region.radius))
Без
if let locationManager = self.locationManager{
Если я удалю if, теперь мне будет выдана ошибка в следующей строке: locationManager.monitoredRegions.count, теперь ошибка «Неоднозначная ссылка на член« locationManager (_: didenterRegion :) »»
Вы добавляете закрытие }
к if let locationManager = self.locationManager{
Да, если это locationManager = self.locationManager {, у него было закрытие, но и его убрать, у меня нет ошибок в ключах открытия или закрытия
можете ли вы поделиться той соответствующей частью vc, где вы объявляете ясли и устанавливаете вышеуказанный блок
почему у вас все еще есть if let locationManager = self.locationManager{
это self.locationManager{
необязательно, удалите его вместе с другим, скомпилируйте и запустите
где ты делаешь let locationManager = CLLocationManager()
??
Вот на мой взглядDidLoad(), добавьте его в начало вопроса
выньте его из функции, это должна быть переменная экземпляра
Также почему вы добавляете экземпляр внутри appdelegate? вам это нужно где-то еще, где или внутри этого vc, только если последний объявит его непосредственно внутри этого vc
вы можете сказать self
здесь self.locationManager
только если это переменная экземпляра, а не локальная
У меня в AppDelegate есть возможность выбирать разрешения на местоположение, а также иметь возможность отправлять уведомления, я добавляю блок кода, который я использую в AppDelegate, это единственный VC, который использует местоположение
пытались вывести var locationManager = CLLocationManager()
из функции?
Я уже работал, просто объявите let locationManager = CLLocationManager () и удалите, если вы упомянули
Огромное спасибо за помощь
Требуется ли местоположение устройства для нескольких контроллеров представления или только для этого?