谷歌地点API不如预期工作

3

我正在跟随 Google Places API for IOS 教程来查看用户当前位置。

我在教程中使用了相同的代码,如下所示:

var placesClient: GMSPlacesClient!

// Add a pair of UILabels in Interface Builder, and connect the outlets to these variables.
@IBOutlet weak var nameLabel: UILabel!

@IBOutlet weak var addressLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    placesClient = GMSPlacesClient.shared()
}

// Add a UIButton in Interface Builder, and connect the action to this function.
@IBAction func getCurrentPlace(_ sender: UIButton) {

placesClient.currentPlace(callback: { (placeLikelihoodList, error) -> Void in
    if let error = error {
        print("Pick Place error: \(error.localizedDescription)")
        return
    }

    self.nameLabel.text = "No current place"
    self.addressLabel.text = ""

    if let placeLikelihoodList = placeLikelihoodList {
        let place = placeLikelihoodList.likelihoods.first?.place
        if let place = place {
            self.nameLabel.text = place.name
            self.addressLabel.text = place.formattedAddress?.components(separatedBy: ", ")
                .joined(separator: "\n")
        }
    }
})
}

但是我在控制台中收到以下错误:

选择位置错误:无法完成操作。地点 API 无法找到用户的位置。这可能是因为用户未允许应用程序访问位置信息。

注意:我已经在 info.plist 文件中设置了 NSLocationWhenInUseUsageDescription 键(隐私 - 使用时位置描述)。

这很令人困惑,因为我按照教程逐步进行操作,并使用启用了“位置服务”的物理设备测试应用程序。

有任何想法我可能做错了什么吗?

还是因为文档不是最新的?


你已经提示用户授权使用位置了吗? - PGDev
@PGDev 我应该将这段代码 let locationManager = CLLocationManager(); locationManager.requestWhenInUseAuthorization(); 放在哪里?我尝试放在viewDidLoad里,但什么也没出现。我尝试在按钮按下时放置,它出现了不到一秒钟,没有任何操作就消失了。 - Behrouz Riahi
我已经更新了答案。 - PGDev
你用什么设备来测试你的代码? - Deepraj Chowrasia
2个回答

6
这可能是因为用户未允许应用程序访问位置信息。要使Google Places正常工作,您需要调用requestWhenInUseAuthorization()请求使用位置服务。这将提示用户授权应用程序使用位置服务。请参考Apple Docs获取更多信息。
编辑:您应该保留对创建的CLLocationManager实例的强引用,以防止函数退出时被释放。从CLLocationManager Docs中获取的语句:“创建CLLocationManager类的实例并在应用程序中存储一个强引用。直到涉及该对象的所有任务完成为止,保留位置管理器对象的强引用是必需的。由于大多数位置管理器任务都是异步运行的,因此在本地变量中存储位置管理器是不足够的。”
示例:
class LocationViewController: UIViewController, CLLocationManagerDelegate { 
  let locationManager = CLLocationManager()

  override func viewDidLoad()
  {
    super.viewDidLoad()

    locationManager.delegate = self
    if CLLocationManager.authorizationStatus() == .notDetermined
    {
       locationManager.requestWhenInUseAuthorization()
    }
  }
}

我应该把代码 let locationManager = CLLocationManager(); locationManager.requestWhenInUseAuthorization(); 放在哪里?我尝试放在 viewDidLoad 里面,但是没有任何显示。我还尝试将其放在按钮按下时的方法里面,它会出现不到一秒钟,然后就消失了,而且我并没有按下任何东西。 - Behrouz Riahi
你必须存储一个强引用到你的位置管理器,这样它在 viewDidLoad 方法结束时不会被释放。我已经更新了我的回答。 - Rhuari Glen
@BehrouzRiahi 没问题! - Rhuari Glen

0

1. 请求用户授权位置使用

根据您的需求,使用requestWhenInUseAuthorization()requestAlwaysAuthorization()

2.Info.plist中添加以下键:

a. NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription

b. NSLocationAlwaysAndWhenInUseUsageDescription

示例:

class ViewController: UIViewController, CLLocationManagerDelegate
{
    let locationManager = CLLocationManager()

    override func viewDidLoad()
    {
        super.viewDidLoad()
        locationManager.requestWhenInUseAuthorization()
        locationManager.delegate = self
        locationManager.startUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)
    {

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接