【问题标题】:iOS Swift: Request user locationiOS Swift:请求用户位置
【发布时间】:2015-04-02 05:03:32
【问题描述】:

我是 iOS Swift 的初学者,正在编写 iOS Swift 代码并使用 UIWebView 加载我的网页。

我的网页会要求用户启用用户位置

我想在 iOS Swift 代码中做类似的行为(弹出一个对话框并说“TestApp 想访问你的位置。你同意吗?”)

我在模拟器上运行,但在使用 CLLocationManager 时失败了

以下是我的 Swift 代码

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var customWebView: UIWebView!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    if let url = NSURL(string: "http://ctrlq.org/maps/where/") {
        let request = NSURLRequest(URL: url)
        customWebView.loadRequest(request)

        let locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()

    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

有人知道如何请求位置吗?

提前致谢。

埃里克

【问题讨论】:

  • 检查 NSHipster 以获得好的摘要(适用于 iOS 8,但仍然有效)。他们的文章讨论了在 info.plist 中设置密钥的要求:NSHipster - Core Location in i​OS 8 此外,用户提示包含来自应用程序 Info.plist 文件中 NSLocationWhenInUseUsageDescription 密钥的文本,并且该密钥的存在是必需的调用此方法时。来自CLLocationManager Class Reference

标签: ios swift uiwebview core-location


【解决方案1】:

请求和更新用户位置的正确方法是通过CLLocationManagerDelegate

虽然您的 View Controller 继承了 CLLocationManagerDelegate,但它似乎没有实现必要的委托功能。正如@Rob 所提到的,您应该将 locationManager 声明为类属性,而不是局部变量。

如果/当用户更改授权状态时,此委托函数允许您实现逻辑:

func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    if status == .AuthorizedWhenInUse {
        // authorized location status when app is in use; update current location
        locationManager.startUpdatingLocation()
        // implement additional logic if needed...
    }
    // implement logic for other status values if needed...
}

如果/当用户位置发生变化时,此委托函数允许您实现逻辑:

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    if let location = locations.first as? CLLocation {
        // implement logic upon location change and stop updating location until it is subsequently updated
        locationManager.stopUpdatingLocation()
    }
}

此外,locationServicesEnabled() 确定用户是否启用了定位服务。

【讨论】:

    【解决方案2】:

    你在 didFinishLaunchingWithOptions 中显示调用做这样的事情

    let status = CLLocationManager.authorizationStatus()
        if status == .NotDetermined || status == .Denied || status == .AuthorizedWhenInUse {
    
            // present an alert indicating location authorization required
            // and offer to take the user to Settings for the app via
            // UIApplication -openUrl: and UIApplicationOpenSettingsURLString
            dispatch_async(dispatch_get_main_queue(), {
                let alert = UIAlertController(title: "Error!", message: "GPS access is restricted. In order to use tracking, please enable GPS in the Settigs app under Privacy, Location Services.", preferredStyle: UIAlertControllerStyle.Alert)
                alert.addAction(UIAlertAction(title: "Go to Settings now", style: UIAlertActionStyle.Default, handler: { (alert: UIAlertAction!) in
                    print("")
                    UIApplication.sharedApplication().openURL(NSURL(string:UIApplicationOpenSettingsURLString)!)
                }))
                // self.presentViewController(alert, animated: true, completion: nil)
                self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
            })
    
            locationManager.requestAlwaysAuthorization()
            locationManager.requestWhenInUseAuthorization()
        }
    

    【讨论】:

      【解决方案3】:

      一些想法:

      1. 您已将 CLLocationManager 定义为局部变量,当它超出范围时将被释放。

        将此作为你的类的属性。

      2. 如果您确实需要requestAlwaysAuthorization,请不要忘记按照文档中的说明在 plist 中设置NSLocationAlwaysUsageDescription

        (如果您不需要总是授权,但可以使用“正在使用”授权,请致电requestWhenInUseAuthorization 并设置NSLocationWhenInUseUsageDescription 值。)

      【讨论】:

        【解决方案4】:

        您需要在您的 info.plist 文件中添加一个键 NSLocationWhenInUseUsageDescription 并在值中添加您想要在弹出对话框中向用户显示的内容。 您需要在真实设备上对其进行测试,因为模拟器只接受自定义位置。 选择模拟器 -> 调试 -> 位置 -> 自定义位置...

        【讨论】:

        • 虽然其他答案提供了与位置管理器合作的好技巧,但此答案提供了 OP 可能缺少的“关键”部分。需要在 info.plist 文件中提供适当的键值。不过,就模拟器而言 - 无论自定义位置设置如何,都可以测试 OP 希望使用模拟器看到的消息。
        【解决方案5】:
        import UIKit
        import CoreLocation
        
        class ViewController: UIViewController, CLLocationManagerDelegate {
        
        
            let locationManager = CLLocationManager()
        
            @IBOutlet weak var webview: UIWebView!
        
        
            override func viewDidLoad() {
                super.viewDidLoad()
        
                self.locationManager.delegate = self
                self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
                self.locationManager.requestWhenInUseAuthorization()
                self.locationManager.startUpdatingLocation()
        
        
                let url = NSURL (string: "http://www.your-url.com");
                let requestObj = NSURLRequest(URL: url!);
                webview.loadRequest(requestObj);
        
        
            }
        
            override func didReceiveMemoryWarning() {
                super.didReceiveMemoryWarning()
                // Dispose of any resources that can be recreated.
            }
        
            func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
                CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
        
                    if (error != nil) {
                        print("Error: " + error!.localizedDescription)
                        return
                    }
        
                    if placemarks!.count > 0 {
                        let pm = placemarks![0] as CLPlacemark
                        self.displayLocationInfo(pm)
                    } else {
                        print("Error with the data.")
                    }
                })
            }
        
            func displayLocationInfo(placemark: CLPlacemark) {
        
                self.locationManager.stopUpdatingLocation()
                print(placemark.locality)
                print(placemark.postalCode)
                print(placemark.administrativeArea)
                print(placemark.country)
        
            }
        
            func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
                print("Error: " + error.localizedDescription)
            }
        
        
        }
        

        【讨论】:

          【解决方案6】:

          试试这个

          import UIKit
          import CoreLocation
          
          class ViewController: UIViewController, CLLocationManagerDelegate {
          
          
          let locationManager = CLLocationManager()
          
          @IBOutlet weak var webview: UIWebView!
          
          
          override func viewDidLoad() {
              super.viewDidLoad()
          
              self.locationManager.delegate = self
              self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
              self.locationManager.requestWhenInUseAuthorization()
              self.locationManager.startUpdatingLocation()
          
          
              let url = NSURL (string: "http://www.your-url.com");
              let requestObj = NSURLRequest(URL: url!);
              webview.loadRequest(requestObj);
          
          
          }
          
          override func didReceiveMemoryWarning() {
              super.didReceiveMemoryWarning()
              // Dispose of any resources that can be recreated.
          }
          
          func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
          
              CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
          
                  if (error != nil) {
                      print("Error: " + error!.localizedDescription)
                      return
                  }
          
                  if placemarks!.count > 0 {
                      let pm = placemarks![0] as CLPlacemark
                      self.displayLocationInfo(pm)
                  } else {
                      print("Error with the data.")
                  }
              })
          }
          
          func displayLocationInfo(placemark: CLPlacemark) {
          
              self.locationManager.stopUpdatingLocation()
              print(placemark.locality)
              print(placemark.postalCode)
              print(placemark.administrativeArea)
              print(placemark.country)
          
          }
          
          func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
              print("Error: " + error.localizedDescription)
          }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-06-28
            • 2015-09-23
            • 1970-01-01
            • 2016-06-14
            • 2017-07-06
            • 1970-01-01
            • 2015-12-07
            • 2014-11-17
            相关资源
            最近更新 更多