Swift中Alamofire GET请求仅首次安装后生效问题求助
问题分析与解决方案
Hey,我帮你梳理下这个问题的可能原因和解决办法——这种首次安装正常、重启后失效的情况,大概率和token有效性、请求缓存或者方法调用时机有关,咱们一步步来排查:
1. 先排查Token是否过期或读取异常
Reddit的OAuth Token是有过期时间的,首次安装后获取的token可能在你重启App时已经失效了。而且你的代码里只在failure分支打印了错误,但没输出响应状态码,很可能重启后请求返回了401(Token过期),但你没注意到。
排查&修复:
- 在请求的
failure分支里添加状态码打印,确认是否是Token过期:case .failure(let error): print("Request failed: \(error)") if let statusCode = response.response?.statusCode { print("Status Code: \(statusCode)") // 如果是401,就是Token过期了 } - 如果确实是401,你需要实现Token刷新逻辑:用之前保存的Refresh Token去Reddit接口获取新的Access Token,更新Keychain里的
oauthToken后重新发起请求。 - 另外,确认KeychainWrapper在App重启后能正常读取token:可以在
getSubreddits()开头加个判断,如果token为空,直接触发登录/Token刷新流程。
2. 检查是否是GET请求缓存导致的
iOS默认会对GET请求做缓存,可能重启后App直接读取了本地缓存的旧响应,没有发起新的网络请求。
修复:
强制禁用该请求的缓存,有两种方式:
- 方式一:在请求头里添加
Cache-Control字段:let headers = [ "User-Agent" : "ios:com.GK.voyager:v1.0 (by /u/ZypherXX)", "Content-Type" : "application/x-www-form-urlencoded", "Authorization" : "bearer \(token)", "Cache-Control": "no-cache" // 禁用缓存 ] - 方式二:创建URLRequest时指定缓存策略:
let urlRequest = URLRequest(url: requestURL, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 15) Alamofire.request(urlRequest, method: .get, parameters: [:], encoding: JSONEncoding.default, headers: headers).responseJSON { ... }
3. 确认getSubreddits()的调用时机
重启App后,你要确保getSubreddits()确实被执行了。比如是不是只在viewDidLoad里调用,但某些场景下控制器没有触发viewDidLoad?可以在方法开头加个打印:
func getSubreddits() { print("getSubreddits method called") // 确认重启后是否有这个输出 // 原代码... }
4. 优化你的解析与UI刷新逻辑
另外,你的parse方法还有两个小问题,也可能导致你误以为请求没执行:
- 每次解析前没有清空
subreddits数组,会导致重复添加数据; - 刷新TableView要确保在主线程(Alamofire的回调是在后台线程)。
修改后的parse方法:
func parse(json: JSON) { subreddits.removeAll() // 先清空旧数据 for result in json["data"]["children"].arrayValue { let subreddit = result["data"]["subreddit"].stringValue let description = result["data"]["description"].stringValue let name = result["data"]["display_name"].stringValue let subscribers = result["data"]["subscribers"].intValue let subObject = Subreddit(subreddit: subreddit, name: name, description: description, subscribers: subscribers) subreddits.append(subObject) } print("Loaded \(subreddits.count) subreddits") // 主线程刷新UI DispatchQueue.main.async { self.tableView.reloadData() } }
先按上面的步骤排查,大概率能解决问题~
内容的提问来源于stack exchange,提问作者Garret Koontz
相关产品推荐
相关产品推荐

