SwiftUI开发Twitter客户端:如何减少API调用关联用户与推文?
解决Twitter API v2获取时间线时重复请求用户信息的问题
我用SwiftUI开发简易Twitter客户端,目前在获取时间线阶段。查Twitter API v2文档发现,获取时间线的接口只返回推文ID、文本、创建时间(created_at)和作者ID。我尝试循环调用接口用作者ID拿用户信息,但同一用户多次发推会产生大量重复请求,很容易触发API调用限额,找不到更好的办法。我不是专业开发者,只是兴趣写代码,技术有限,求解决思路。
我的代码:
func getStream(client: TwitterAPIClient, id: String) async throws { let response = await client.v2.timeline.getUserReverseChronological(.init( id: id, expansions: TwitterTweetExpansionsV2.all, maxResults: 20, mediaFields: TwitterMediaFieldsV2.all, tweetFields: TwitterTweetFieldsV2.all.subtracting([.promotedMetrics, .nonPublicMetrics, .organicMetrics]), userFields: TwitterUserFieldsV2.all) ) .responseDecodable(type: TwitterDataResponseV2< [TwitterTimelineV2], TwitterTimelineV2.Include, TwitterTimelineV2.Meta>.self) if let error = response.error { print(error) throw error } else { print(response.success!) } print(response) let timeline = try response.map { $0.data }.result.get() for tweet in timeline { let response = try await getUserInfo(client: client, id: tweet.authorId).result.get() print(response) } }
注:TwitterAPIClient是第三方库的客户端。
解决思路
利用API的
expansions参数一次性获取关联数据
你已经在请求里加了expansions: TwitterTweetExpansionsV2.all,这个参数会让Twitter API在返回时间线的同时,自动附带所有推文作者的用户信息,不需要单独循环调用用户接口。这些用户数据会放在响应的includes.users字段里。缓存已获取的用户信息
后续如果再遇到相同的作者ID,可以直接从本地缓存读取,完全避免重复请求。
修改后的代码示例
func getStream(client: TwitterAPIClient, id: String) async throws { let response = await client.v2.timeline.getUserReverseChronological(.init( id: id, expansions: TwitterTweetExpansionsV2.all, maxResults: 20, mediaFields: TwitterMediaFieldsV2.all, tweetFields: TwitterTweetFieldsV2.all.subtracting([.promotedMetrics, .nonPublicMetrics, .organicMetrics]), userFields: TwitterUserFieldsV2.all) ) .responseDecodable(type: TwitterDataResponseV2< [TwitterTimelineV2], TwitterTimelineV2.Include, TwitterTimelineV2.Meta>.self) if let error = response.error { print(error) throw error } guard let successResponse = response.success else { // 处理响应为空的情况 return } let timeline = successResponse.data // 从includes里提取用户信息,转成字典方便通过ID查找 let userDictionary = Dictionary(uniqueKeysWithValues: successResponse.include?.users?.map { ($0.id, $0) } ?? []) for tweet in timeline { // 直接从字典里取用户信息,不用再调用接口 if let user = userDictionary[tweet.authorId] { print("推文作者: \(user.name) (@\(user.username))") } } }
说明
- 代码中通过
successResponse.include?.users拿到所有关联用户,转成[String: UserModel]的字典,这样可以通过推文的authorId直接查找对应用户,完全消除循环请求。 - 如果后续需要处理更多分页数据,建议把用户字典的内容缓存到本地(比如用
UserDefaults或者Realm),下次请求新的时间线时,先检查缓存里有没有对应的用户,没有再从新的响应includes里补充,进一步减少API调用。
内容的提问来源于stack exchange,提问作者steve kurogi
相关产品推荐
相关产品推荐

