SwiftUI中Swifter拉取Twitter列表仅获带媒体推文的问题解决
问题解决:兼容无媒体推文的解析与展示
问题描述
开发Twitter列表推文展示应用时,仅能加载带媒体链接的推文,纯文本推文被跳过,但API返回的JSON数据包含所有目标推文。需调整解析逻辑兼容无媒体推文,同时适配视图展示避免崩溃。
核心问题分析
原解析代码将media_url_https的字符串判断作为必须条件放入同一if语句,导致无媒体的推文无法满足条件被跳过;此外视图中对full_text和media_url_https使用强制解包(!),会引发纯文本推文的崩溃。
修改步骤
1. 调整推文解析逻辑
将媒体字段的判断从必须条件中分离,单独处理为可选值,确保无媒体时也能创建TweetData对象:
func listTweets(listTag: ListTag) { swifter.listTweets(for: ListTag.id("1580201555286192128"), count: 20, includeEntities: true, includeRTs: true, tweetMode: .extended) { JSON in switch JSON { case .array(let array): var tweets: [TweetData] = [] for json in array { // 先校验必须存在的字段 guard case let .string(id) = json["id_str"], case let .string(full_text) = json["full_text"], case let .string(screen_name) = json["user"]["screen_name"], case let .string(name) = json["user"]["name"], case let .string(profile_image_url_https) = json["user"]["profile_image_url_https"] else { continue // 必须字段缺失则跳过本条推文 } // 单独处理可选的媒体字段 let mediaUrl: String? if case let .string(url) = json["entities"]["media"][0]["media_url_https"] { mediaUrl = url } else { mediaUrl = nil } // 创建TweetData并加入数组 tweets.append(TweetData( id_str: id, full_text: full_text, screen_name: screen_name, name: name, profile_image_url_https: profile_image_url_https, media_url_https: mediaUrl )) } DispatchQueue.main.async { self.fantasyNews = tweets } default: print("无法处理对象: \(JSON)") } } }
2. 优化视图展示逻辑
移除强制解包,对可选字段做安全判断,仅当媒体链接存在时才显示图片组件:
// 替换原Text和AsyncImage代码 VStack(alignment: .leading) { // 安全展示推文内容,避免强制解包崩溃 if let text = tweet.full_text { Text(text) } // 仅当媒体链接有效时加载图片 if let mediaUrl = tweet.media_url_https, let url = URL(string: mediaUrl) { AsyncImage(url: url, placeholder: { Text("加载中...") }, image: { Image(uiImage: $0).resizable() }) .aspectRatio(contentMode: .fit) } } .onAppear() { networkManager.listTweets(listTag: .id("1580201555286192128")) }
3. 可选优化:结构体默认值
为结构体可选字段添加默认值,减少后续使用时的空值判断:
struct TweetData: Codable, Identifiable { var id: String { id_str } var id_str: String var full_text: String? = "" var screen_name: String? = "" var name: String? = "" var profile_image_url_https: String? = "" var media_url_https: String? = nil }
内容的提问来源于stack exchange,提问作者eazey12
相关产品推荐
相关产品推荐

