【发布时间】:2021-01-08 23:25:54
【问题描述】:
我在我的应用程序中使用 Swift 设置了 XMLParser,并且希望能够在小部件扩展中解析 RSS 提要,并在小部件中返回该数据。但是,我在让两个 Swift 文件相互通信时遇到了一些问题。在解析器中,我有:
struct RSSItem {
var title: String
var description: String
var link: String
var pubDate: String
}
// download xml from the internet
class FeedParser: NSObject, XMLParserDelegate
{
private var rssItems: [RSSItem] = []
private var currentElement = ""
private var currentTitle: String = ""
private var currentDescription: String = ""
private var currentPubDate: String = ""
private var currentLink: String = ""
private var parserCompletionHandler: (([RSSItem]) -> Void)?
func parseFeed(url: String, completionHandler: (([RSSItem]) -> Void)?)
{
self.parserCompletionHandler = completionHandler
let request = URLRequest(url: URL(string: url)!)
let urlSession = URLSession.shared
let task = urlSession.dataTask(with: request) { (data, response, error) in
guard let data = data else {
if let error = error {
print(error.localizedDescription)
}
return
}
/// parse our xml data
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
}
task.resume()
}
// MARK: - XML Parser Delegate
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
if currentElement == "item" {
currentTitle = ""
currentDescription = ""
currentPubDate = ""
currentLink = ""
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
switch currentElement {
case "title": currentTitle += string
case "description": currentDescription += string
case "pubDate" : currentPubDate += string
case "link" : currentLink += string
default: break
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "item" {
let rssItem = RSSItem(title: currentTitle, description: currentDescription, link: currentLink, pubDate: currentPubDate)
self.rssItems.append(rssItem)
}
}
func parserDidEndDocument(_ parser: XMLParser) {
parserCompletionHandler?(rssItems)
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print(parseError.localizedDescription)
}
}
在小部件中,我有:
struct Provider: TimelineProvider {
@State private var rssItems:[RSSItem]?
let feedParser = FeedParser()
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), title:"News", description: "Stuff happened", link: "Http://link", pubDate: "The day it posted")
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), title:"News", description: "Stuff happened", link: "Http://link", pubDate: "The day it posted")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
feedParser.parseFeed(url: "") {(rssItems) in
self.rssItems = rssItems
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, title:rssItems.title, description: rssItems.description, link: rssItems.link, pubDate: rssItems.pubDate)
entries.append(entry)
}
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let title: String
let description: String
let link: String
let pubDate: String
}
但是,在 TimelineProvider 部分,它告诉我 rssItems 没有名为 title、description、pubDate 或 link 的成员
【问题讨论】:
-
这可能对你有帮助:How to refresh Widget data?
-
@pawello2222 感谢您的链接,但我可能太深入了,因为每一点都在我的脑海中。第一次使用 Swift 而不是 Obj-C,这一切都让我失望。
-
这个答案可以很容易地应用于您的案例 - 您只需使用 FeedParser 而不是 NetworkManager。但如果这是您第一次使用 Swift,我不建议您创建小部件 - 从 standard 应用程序开始,然后先习惯 Swift 和 SwiftUI。
-
@pawello2222 相信我,我完全明白,但唉,这就是我所在的地方。我已经构建了解析器,但是在尝试将其数据传递到 Widget 文件时遇到了很多问题。我更新了小部件中的 SimpleEntry 以包含 XML 所需的值,但在尝试让解析器运行时仍然遇到问题。在 TimelineProvider 的结构中,我是否应该运行提要解析器,因为当我尝试这样做时它会引发很多错误。
-
@pawello2222 了解,我更新了 OP 以包含 Widget 文件中的相关代码,显示问题所在。我认为(?)那是我调用代码来解析 xml 的地方,但你会看到它没有看到 rssItems 中标题链接发布日期或描述的任何成员
标签: swift xml-parsing widget ios14 widgetkit