• 赚钱入口【需求资源】限时招募流量主、渠道主,站长合作;【合作模式】CPS长期分成,一次推广永久有收益。主动打款,不扣量;

RSS Widget在iOS 14上显示空白

iOS rin, seun 1个月前 (09-28) 58次浏览 0个评论

I use an XMLParser for my app written in Swift, and am trying to get a Widget set up for iOS 14 in which it will show the most recent article on the RSS. I see the placeholder just fine when I add it, but it stays empty with just a line where text should be and never seems to get the information from the timeline.

struct Provider: TimelineProvider {
    @State private var rssItems:[RSSItem]?
    let feedParser = FeedParser()
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), title:"News", description: "News article here", link: "Http://link", pubDate: "The day it posted")
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), title:"News", description: "News Article Here", link: "Http://link", pubDate: "The day it posted")
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> ()) {
        var entries: [SimpleEntry] = []
        feedParser.parseFeed(url: "http://fritchcoc.wordpress.com/feed") {(rssItems) in
            self.rssItems = rssItems
            let currentDate = Date()
                let entry = SimpleEntry(date: currentDate, title:rssItems[0].title, description: rssItems[0].description, link: rssItems[0].link, pubDate: rssItems[0].pubDate)
                entries.append(entry)
            
        
      
        }

        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
}

struct FritchNewsEntryView : View {
    var entry: SimpleEntry
    var body: some View {
            VStack(alignment: .leading, spacing: 4) {
                
                Text(entry.title)
               
                   
                
              
            }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .leading)
                .padding()
                .background(LinearGradient(gradient: Gradient(colors: [.orange, .yellow]), startPoint: .top, endPoint: .bottom))
        }
    
}

@main
struct FritchNews: Widget {
    let kind: String = "FritchNews"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            FritchNewsEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

解决

Apple does not allow HTTP connections by default, the easiest solution is to change the URL to https://fritchcoc.wordpress.com/feed

If you want to allow HTTP connections in your app (or widget) you can add exceptions (to one domain or all) in the Info.plist for the target, see NSAppTransportSecurity at Apple Docs

Edit:
After a better look and finding for the implementation of FeedParser online, I noticed that parseFeed() is asynchronous.

Thus the completion is called with an empty array, it should be called after the parsing is done:

struct Provider: TimelineProvider {
    ...

    func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> ()) {
        var entries: [SimpleEntry] = []
        feedParser.parseFeed(url: "http://fritchcoc.wordpress.com/feed") {(rssItems) in
            self.rssItems = rssItems
            let currentDate = Date()
            let entry = SimpleEntry(date: currentDate, title:rssItems[0].title, description: rssItems[0].description, link: rssItems[0].link, pubDate: rssItems[0].pubDate)
            entries.append(entry)
            
        
            let timeline = Timeline(entries: entries, policy: .atEnd)
            completion(timeline)
        }
    }
}
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址