在我调用 requestWhenInUseAuthorization() 之前触发位置权限对话框
Posted
技术标签:
【中文标题】在我调用 requestWhenInUseAuthorization() 之前触发位置权限对话框【英文标题】:Location permission dialog fires before I call requestWhenInUseAuthorization() 【发布时间】:2020-09-09 08:55:40 【问题描述】:当我的视图出现时:
struct TurnOnLocation: View
var body: some View
ZStack
Color.orange
.edgesIgnoringSafeArea(.all)
VStack
Spacer()
Image(systemName: "globe")
.resizable()
.aspectRatio(contentMode: .fill)
.foregroundColor(.white)
Spacer()
Button(action:
let locationManager = LocationManager()
locationManager.locationManager.requestWhenInUseAuthorization()
locationManager.locationManager.startUpdatingLocation()
)
Text("Turn on location")
.foregroundColor(Color.black)
.font(Font.system(size:22))
.padding(20)
.background(
Rectangle()
.fill(Color.white)
.border(Color.white, width:1)
)
.cornerRadius(50)
.shadow(radius: 10)
.padding(50)
它会在点击Button
之前询问用户位置。为什么是这样?我在下面添加了我的模型,以便在初始化时触发(应该是在单击按钮时)。
class LocationManager: NSObject, ObservableObject
@Published var locationStatus: CLAuthorizationStatus? = CLAuthorizationStatus.notDetermined
@Published var locationPermissionStatus = PermissionStatus.unknown
@Published var location: CLLocation?
let locationManager = CLLocationManager()
override init()
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
enum PermissionStatus
case unknown
case authorizedWhenInUse
case authorizedAlways
case restricted
case denied
func getLocation() -> CLLocationCoordinate2D?
return self.location?.coordinate
知道如何确保对话框仅在单击按钮后显示吗?
编辑:
我已经更新了代码:
Button(action:
let locationManager = LocationManager()
locationManager.requestPermission()
)
型号
class LocationManager: NSObject, ObservableObject , CLLocationManagerDelegate
@Published var locationStatus: CLAuthorizationStatus? = CLAuthorizationStatus.notDetermined
@Published var locationPermissionStatus = PermissionStatus.unknown
@Published var location: CLLocation?
let locationManager = CLLocationManager()
override init()
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
func requestPermission()
self.locationManager.requestWhenInUseAuthorization()
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) switch status
case .restricted, .denied:
// Disable your app's location features
print("restricted")
break
case .authorizedWhenInUse:
// Enable your app's location features.
print("authorizedWhenInUse")
self.locationManager.startUpdatingLocation()
break
case .authorizedAlways:
// Enable or prepare your app's location features that can run any time.
print("authorizedAlways")
self.locationManager.startUpdatingLocation()
break
case .notDetermined:
print("notDetermined")
break
但是,当我单击按钮时,询问位置权限的对话框会在一秒钟后消失。知道为什么吗?
【问题讨论】:
【参考方案1】:有两件事需要解决:
您已经在init
中调用了requestWhenInUseAuthorization
,这就是您在构建按钮时看到警报的原因。您应该删除 init
中的 requestWhenInUseAuthorization
。
您应该在确定您获得授权后致电startUpdatingLocation
LocationManager
。
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) switch status case .authorizedAlways, .authorizedWhenInUse: manager.startUpdatingLocation() default: print("no auth")
【讨论】:
谢谢,我已经在我的编辑中更新了上面的代码。但是,由于某种原因,请求位置许可的对话框在一秒钟后消失了。知道为什么吗? 我最好的猜测是它与 SwiftUI 本身有关。您正在视图中创建一个经理,并且可以在完成其课程之前将其解除分配。您应该将按钮的操作定向到交互器(大概是@ObservableObject
)并在该交互器中分配 LocationManager,您确信它会一直保留到您认为不再需要它为止。您可以通过实现 LocationManager
的 'deinit' 方法来尝试它,或者在 Button 的操作中打印。【参考方案2】:
您在LocationManager
init 方法中请求授权。
您应该从 init 中删除该代码。
class LocationManager: NSObject, ObservableObject
@Published var locationStatus: CLAuthorizationStatus? = CLAuthorizationStatus.notDetermined
@Published var locationPermissionStatus = PermissionStatus.unknown
@Published var location: CLLocation?
let locationManager = CLLocationManager()
override init()
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
func requestAuthorization()
self.locationManager.requestWhenInUseAuthorization()
func startUpdate()
self.locationManager.startUpdatingLocation()
enum PermissionStatus
case unknown
case authorizedWhenInUse
case authorizedAlways
case restricted
case denied
func getLocation() -> CLLocationCoordinate2D?
return self.location?.coordinate
在你看来:
struct TurnOnLocation: View
var body: some View
ZStack
Color.orange
.edgesIgnoringSafeArea(.all)
VStack
Spacer()
Image(systemName: "globe")
.resizable()
.aspectRatio(contentMode: .fill)
.foregroundColor(.white)
Spacer()
Button(action:
let locationManager = LocationManager()
locationManager.requestAuthorization()
// you should check for authorization result first
locationManager.startUpdatingLocation()
)
Text("Turn on location")
.foregroundColor(Color.black)
.font(Font.system(size:22))
.padding(20)
.background(
Rectangle()
.fill(Color.white)
.border(Color.white, width:1)
)
.cornerRadius(50)
.shadow(radius: 10)
.padding(50)
【讨论】:
这行得通 - 但是在我单击按钮后,位置对话框会在 1 秒后消失。有什么想法吗?【参考方案3】:要修复 1 秒后消失的问题,请尝试像这里一样初始化位置管理:
struct TurnOnLocation: View
let locationManager = LocationManager() <- try to init location manager here
var body: some View
ZStack
Color.orange
.edgesIgnoringSafeArea(.all)
VStack
Spacer()
Image(systemName: "globe")
.resizable()
.aspectRatio(contentMode: .fill)
.foregroundColor(.white)
Spacer()
Button(action:
locationManager.locationManager.requestWhenInUseAuthorization()
locationManager.locationManager.startUpdatingLocation()
)
Text("Turn on location")
.foregroundColor(Color.black)
.font(Font.system(size:22))
.padding(20)
.background(
Rectangle()
.fill(Color.white)
.border(Color.white, width:1)
)
.cornerRadius(50)
.shadow(radius: 10)
.padding(50)
【讨论】:
以上是关于在我调用 requestWhenInUseAuthorization() 之前触发位置权限对话框的主要内容,如果未能解决你的问题,请参考以下文章
在我的 webview 上调用 didFinish 不起作用
在我调用 paypal 沙盒 api 的网页底部显示额外内容
为啥当我使用 presentModelViewController 时未在我的 UITabBArController 中调用 viewWillAppear?