XCode仿Yelp餐饮点评APP:地点搜索后无法加载商家问题求助
问题描述
我正在XCode中开发一款类似Yelp的餐厅点评APP,想要添加地点搜索功能。APP原本启动时会获取用户位置,并通过以下代码加载对应位置的商家:
locationService.newLocation = { [weak self] result in switch result { case .success(let location): self?.loadBusinesses(with: location.coordinate) case .failure(let error): print(error.localizedDescription) }
我添加了一个搜索栏,可搜索地点并输出坐标,这部分功能正常,代码如下:
let searchRequest = MKLocalSearch.Request() searchRequest.naturalLanguageQuery = searchBar.text let activeSearch = MKLocalSearch(request: searchRequest) activeSearch.start { (response, error) in if response == nil { print("Error") } else { let latitude = (response?.boundingRegion.center.latitude)! let longitude = (response?.boundingRegion.center.longitude)! print(latitude, longitude) let coords: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
现在我想使用搜索得到的坐标加载附近商家,但尝试了以下几种方式均未成功:
// FIRST ATTEMPT // let appdel = AppDelegate() // let searchbizz: () = appdel.loadBusinesses(with: coords) //SECOND ATTEMPT // func searchbiz() { // appdel.loadBusinesses(with: coords) // print("hello") // } //THIRD ATTEMPT func searchbizy() { print("hello there") self.locationService.newLocation = { [weak self] result in switch result { case .success(_): AppDelegate().loadBusinesses(with: coords) case .failure(let error): print(error.localizedDescription) } } } // searchbiz() // searchbizy() self.tableView.reloadData()
我的需求是调用AppDelegate中原先用于加载用户位置商家的loadBusinesses函数,替换为搜索得到的坐标,但目前实现失败,请问我哪里出错了或遗漏了什么?
问题分析与解决方案
你的尝试存在几个核心错误:
- 错误获取AppDelegate实例:每次
AppDelegate()都会创建一个全新的实例,而不是当前APP正在运行的那个。正确的做法是通过UIApplication.shared.delegate as? AppDelegate获取当前活跃的AppDelegate单例。 - 冗余的逻辑绕路:第三段代码中重新赋值
locationService.newLocation完全没必要,你已经拿到了目标坐标,直接调用loadBusinesses即可,不需要通过位置服务的回调触发。 - 混乱的代码结构:在闭包内部定义函数却未正确调用,逻辑链路断裂,导致方法无法执行。
正确实现代码
在搜索成功获取到coords后,直接调用目标方法即可:
activeSearch.start { (response, error) in guard let response = response else { print("搜索出错:\(error?.localizedDescription ?? "未知错误")") return } let center = response.boundingRegion.center let coords = CLLocationCoordinate2D(latitude: center.latitude, longitude: center.longitude) // 获取当前运行的AppDelegate实例并调用方法 if let appDelegate = UIApplication.shared.delegate as? AppDelegate { appDelegate.loadBusinesses(with: coords) // 若loadBusinesses是异步方法,建议在数据加载完成的回调中刷新表格,而非立即调用 DispatchQueue.main.async { self.tableView.reloadData() } } }
额外优化建议
- 避免使用强制解包
!,改用guard let或if let处理可选值,防止崩溃。 - 如果
loadBusinesses是异步请求数据的方法,务必在数据加载完成的回调内执行tableView.reloadData(),否则表格会显示旧数据。 - 注意原代码中
self?.loadBusinesses是当前ViewController的方法而非AppDelegate的,如果是这种情况,你完全不需要调用AppDelegate的方法,直接执行self.loadBusinesses(with: coords)即可——这可能是你最核心的误解点。
内容的提问来源于stack exchange,提问作者Aoun Hakim
相关产品推荐
相关产品推荐

