Swift项目集成RapidApi遇问题,求正确封装实现方案
Swift中封装RapidAPI请求的实现方案
封装前的核心修正
- 替换密钥占位符:将代码里的
[your rapidapi key]替换为你在RapidAPI平台获取的真实密钥 - 修复URL编码问题:原URL里的
London%252Cuk是双重编码,改为London,uk(后续用URLComponents自动编码更安全)
完整封装代码
我们可以把请求逻辑封装成可复用的工具类,同时完善错误处理和数据解析:
import Foundation // 定义天气数据模型(根据API返回结构调整) struct WeatherResponse: Codable { let name: String let main: MainWeather let weather: [WeatherDetail] } struct MainWeather: Codable { let temp: Double let humidity: Int } struct WeatherDetail: Codable { let description: String } // 封装RapidAPI请求工具类 class RapidWeatherAPI { // 配置API信息 private static let baseURL = "https://community-open-weather-map.p.rapidapi.com/weather" private static let headers = [ "x-rapidapi-host": "community-open-weather-map.p.rapidapi.com", "x-rapidapi-key": "你的真实RapidAPI密钥" // 替换为实际密钥 ] // 定义回调类型 typealias WeatherCompletion = (Result<WeatherResponse, Error>) -> Void // 静态方法:获取指定城市的天气 static func fetchWeather(for city: String, completion: @escaping WeatherCompletion) { // 使用URLComponents构建安全的URL guard var components = URLComponents(string: baseURL) else { completion(.failure(NSError(domain: "APIError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的基础URL"]))) return } components.queryItems = [URLQueryItem(name: "q", value: city)] guard let url = components.url else { completion(.failure(NSError(domain: "APIError", code: -2, userInfo: [NSLocalizedDescriptionKey: "无法构建请求URL"]))) return } var request = URLRequest(url: url) request.httpMethod = "GET" request.allHTTPHeaderFields = headers let task = URLSession.shared.dataTask(with: request) { data, response, error in // 处理网络错误 if let error = error { completion(.failure(error)) return } // 验证HTTP响应状态码 guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { completion(.failure(NSError(domain: "APIError", code: -3, userInfo: [NSLocalizedDescriptionKey: "请求失败,状态码异常"]))) return } // 解析返回的JSON数据 guard let data = data else { completion(.failure(NSError(domain: "APIError", code: -4, userInfo: [NSLocalizedDescriptionKey: "未获取到响应数据"]))) return } do { let weatherData = try JSONDecoder().decode(WeatherResponse.self, from: data) completion(.success(weatherData)) } catch { completion(.failure(error)) } } task.resume() } } // 调用示例 RapidWeatherAPI.fetchWeather(for: "London,uk") { result in switch result { case .success(let weather): print("城市:\(weather.name)") print("温度:\(weather.main.temp)K") print("湿度:\(weather.main.humidity)%") print("天气描述:\(weather.weather.first?.description ?? "无数据")") case .failure(let error): print("请求出错:\(error.localizedDescription)") } }
封装后的优势
- 可复用性:通过工具类可以在项目任意位置调用天气请求
- 安全性:避免强制解包,通过可选值处理和错误捕获防止崩溃
- 可读性:用Codable模型解析JSON,替代手动解析,代码更清晰
- 扩展性:后续新增其他RapidAPI接口时,只需在工具类中添加对应方法即可
内容的提问来源于stack exchange,提问作者treenera
相关产品推荐
相关产品推荐

