Swift调用Kakao Map关键词搜索API无报错但模拟器无内容
Swift调用Kakao Map关键词搜索无数据显示的问题修复
核心问题分析
- 未触发网络请求:
viewDidLoad中未调用keywordSearch方法,根本没发起API请求,自然无数据返回。 - 解码逻辑不匹配:Kakao关键词搜索API返回的是包含
documents数组的顶层对象,直接用responseDecodable(of: Place.self)解码单个Place会失败。 - 字段映射缺失:
Place结构体属性名与API返回的下划线格式字段(如place_name)不匹配,未添加CodingKeys映射,导致解码失败。 - Decodable与SwiftyJSON冗余混用:既实现了
Decodable协议,又转成SwiftyJSON解析,逻辑冗余且易出错。 - 参数硬编码:方法参数
page未被使用,硬写page:15可能导致请求无结果(若关键词对应结果不足15页)。 - 数组越界风险:直接访问
resultList[0]等下标,在数组为空时会崩溃。 - 无UI展示逻辑:代码中没有任何UI控件(如
UITableView)用于展示数据,即使请求成功也看不到内容。
修正后的代码示例
import UIKit import Alamofire // 匹配Kakao API返回的顶层结构 struct KeywordSearchResponse: Decodable { let documents: [Place] } // Place结构体添加字段映射,符合Decodable规范 struct Place: Decodable { let placeName: String let roadAddressName: String let longitudeX: String let latitudeY: String enum CodingKeys: String, CodingKey { case placeName = "place_name" case roadAddressName = "road_address_name" case longitudeX = "x" case latitudeY = "y" } } // 类名遵循Swift大驼峰命名规范 class DokseosilViewController: UIViewController, UITableViewDataSource { private var resultList = [Place]() // 添加TableView用于展示搜索结果 private let tableView = UITableView() override func viewDidLoad() { super.viewDidLoad() setupTableView() // 调用搜索方法,传入关键词和页码 keywordSearch(keyword: "咖啡馆", page: 1) } // 配置TableView布局与属性 private func setupTableView() { tableView.frame = view.bounds tableView.dataSource = self tableView.register(UITableViewCell.self, forCellReuseIdentifier: "PlaceCell") view.addSubview(tableView) } func keywordSearch(keyword: String, page: Int) { let headers: HTTPHeaders = [ "Authorization": "KakaoAK 你的API密钥" // 替换为实际的Kakao REST API密钥 ] let parameters: [String: Any] = [ "query": keyword, "page": page, // 使用传入的页码参数 "size": 10 ] AF.request("https://dapi.kakao.com/v2/local/search/keyword.json", method: .get, parameters: parameters, headers: headers) .responseDecodable(of: KeywordSearchResponse.self) { [weak self] response in guard let self = self else { return } switch response.result { case .success(let responseData): self.resultList = responseData.documents // 刷新TableView展示数据 self.tableView.reloadData() // 安全打印结果,避免数组越界 if self.resultList.count >= 3 { print(self.resultList[0].placeName) print(self.resultList[1].placeName) print(self.resultList[2].placeName) } else { print("搜索结果不足3条") } case .failure(let error): print("请求失败:\(error.localizedDescription)") } } } // UITableView数据源实现 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { resultList.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "PlaceCell", for: indexPath) let place = resultList[indexPath.row] cell.textLabel?.text = place.placeName cell.detailTextLabel?.text = place.roadAddressName return cell } }
关键修复说明
- 新增顶层响应结构体:
KeywordSearchResponse匹配API返回的documents数组结构,确保JSON解码成功。 - 添加字段映射:通过
CodingKeys将Swift驼峰属性名与API下划线字段名对应,解决解码失败问题。 - 触发网络请求:在
viewDidLoad中调用keywordSearch方法发起API请求。 - 添加UI展示:加入
UITableView并实现数据源方法,请求成功后刷新列表展示结果。 - 安全处理数组:先判断数组长度再访问元素,避免崩溃。
- 优化参数使用:使用传入的
page参数,避免硬编码导致的无结果问题。 - 移除冗余依赖:删除SwiftyJSON,统一用
Decodable处理JSON解码,简化逻辑。
内容的提问来源于stack exchange,提问作者Joy
相关产品推荐
相关产品推荐

