diff --git a/Account/Sources/Account/AccountManager.swift b/Account/Sources/Account/AccountManager.swift
index 0989691cc..abdf4d154 100644
--- a/Account/Sources/Account/AccountManager.swift
+++ b/Account/Sources/Account/AccountManager.swift
@@ -246,7 +246,7 @@ public final class AccountManager: UnreadCountProvider {
}
}
- public func refreshAll(errorHandler: @escaping (Error) -> Void, completion: (() -> Void)? = nil) {
+ public func refreshAll(errorHandler: @escaping @MainActor (Error) -> Void, completion: (() -> Void)? = nil) {
guard let reachability = try? Reachability(hostname: "apple.com"), reachability.connection != .unavailable else { return }
let group = DispatchGroup()
@@ -259,7 +259,9 @@ public final class AccountManager: UnreadCountProvider {
case .success:
break
case .failure(let error):
- errorHandler(error)
+ Task { @MainActor in
+ errorHandler(error)
+ }
}
}
}
diff --git a/Appcasts/netnewswire-beta.xml b/Appcasts/netnewswire-beta.xml
index c4699ebef..6db0df038 100755
--- a/Appcasts/netnewswire-beta.xml
+++ b/Appcasts/netnewswire-beta.xml
@@ -5,8 +5,26 @@
https://ranchero.com/downloads/netnewswire-beta.xml
Most recent NetNewsWire changes with links to updates.
en
-
+
-
+
NetNewsWire 6.1.2
+ Twitter integration has been removed: Twitter has suspended NetNewsWire, and Twitter is removing free access to the Twitter API
+ Since Twitter does not provide RSS feeds, we’ve had to use the Twitter API. Without free access to that API, we can’t read feeds from Twitter.
+ We’ve left your Twitter feeds intact. If you have any starred items from those feeds, they will remain as long as you don’t delete those feeds.
+ You can still read whatever you have already downloaded. However, those feeds will no longer update.
+ Other changes…
+ Fixed a crashing bug that could happen in the sidebar
+ Fixed a bug that could prevent users from accessing BazQux if an article was missing a field
+ Fixed an issue that could prevent Feedly users from syncing if they tried to mark too many articles as read at the same time
+ Updated the Safari extension icon (credit to Louie Mantia for the new icon)
+ ]]>
+ Sat, 08 Apr 2023 10:30:00 -0800
+
+ 10.15.0
+
+
+ -
NetNewsWire 6.1.1b1
Fixed a bug that could prevent users from accessing BazQux if an article was missing a field
@@ -17,172 +35,5 @@
10.15.0
- -
-
NetNewsWire 6.1
- Article themes. Several themes ship with the app, and you can create your own. You can change the theme in Preferences or by adding the theme switcher to the toolbar
- Copy URLs using repaired, rather than raw, feed links
- Restore article scroll position on relaunching app
- Added Copy Article URL and Copy External URL commands to the Edit menu
- Fixed a bug where using cmd-Q wouldn’t always quit the app as quickly as one might prefer
- Disallow creation of iCloud account in the app if iCloud and iCloud Drive aren’t both enabled
- Fixed bug showing quote tweets that only included an image
- Added a hidden pref to suppress downloading/syncing on start: `defaults write com.ranchero.NetNewsWire-Evergreen DevroeSuppressSyncOnLaunch -bool true`
- Video autoplay is now disallowed
- Article view now supports RTL layout
- Fixed a few font and sizing issues
- Updated built-in feeds
- Better alignment for items in General Preferences pane
- ]]>
- Thu, 07 Apr 2022 10:05:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.1b5
- Updated built-in feeds
- Building on a new Apple Silicon Mac — testing to make sure all’s well
- ]]>
- Mon, 04 Apr 2022 22:10:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.1b4
- Fixed a few font and sizing issues.
- ]]>
- Sun, 27 Feb 2022 21:50:00 -0800
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.1b3
- Two new themes: Hyperlegible and NewsFax
-Change in how built-in themes work: they’re part of the app bundle and they’re not copied into the Themes folder. When a built-in theme changes in a new app release, anyone using that new version gets the changes to the built-in theme
- ]]>
- Thu, 10 Feb 2022 21:35:00 -0800
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.1b2
- Article themes. Several themes ship with the app, and you can create your own. You can change the theme in Preferences or by adding the theme switcher to the toolbar.
-Copy URLs using repaired, rather than raw, feed links.
-Restore article scroll position on relaunching app.
-Added Copy Article URL and Copy External URL commands to the Edit menu.
-Fixed a bug where using cmd-Q wouldn’t always quit the app as quickly as one might prefer.
-Disallow creation of iCloud account in the app if iCloud and iCloud Drive aren’t both enabled.
-Fixed bug showing quote tweets that only included an image.
-Added a hidden pref to suppress downloading/syncing on start: `defaults write com.ranchero.NetNewsWire-Evergreen DevroeSuppressSyncOnLaunch -bool true`
-Video autoplay is now disallowed.
-Article view now supports RTL layout.
- ]]>
- Mon, 17 Jan 2022 17:45:00 -0800
-
- 10.15.0
-
-
-
- -
-
NetNewsWire 6.0.3
- Same as 6.0.3b2 except for the version number.
- ]]>
- Sun, 05 Sep 2021 12:20:00 -0700
-
- 10.15.0
-
-
-
- -
-
NetNewsWire 6.0.3b2
- Feedly: preserve custom feed names with Feedly when moving them between folders
-Preferences: use full-width row style in accounts and extensions panes
-Fixed a crashing bug triggered by running some UI code outside of main thread
-Fixed a crashing bug that could happen when the app tries to find a feed for a website
-Fixed a crashing bug that could happen when rendering tweets
-Changed how images are placed in Twitter articles so that you can better see who Tweeted the image
-Fixed bug where iCloud syncing could stop prematurely when the sync database has records not in the local database
-Fixed bug where favicons wouldn’t be found when a home page URL has non-ASCII characters
-Fixed bug where external URLs in Feedbin feeds might be lost
-Fixed bug where words prepended with $ wouldn’t appear in Twitter feeds
-Fixed bug where newlines would be just a space in Twitter feeds
-Fixed bug where BazQux-synced feeds might stop updating
- ]]>
- Sun, 29 Aug 2021 15:25:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.0.3b1
- Feedly: handle API change with deleting and don’t show a spurious error
-NewsBlur: don’t fetch articles marked hidden by NewsBlur
-FreshRSS: add API endpoint URL example in setup form
-iCloud: fixed bug not retaining feeds in a folder where the folder hasn’t been synced yet
-Feeds list: smart feeds remain visible despite Hide Read Feeds setting
-Keyboard shortcuts: fixed regression where L key wouldn’t go to next unread when feed is all read
-Twitter extension: fixed weird bug where an extra https:/ could appear in tweet text
- ]]>
- Thu, 20 May 2021 20:00:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.0.2
- Same as 6.0.2b1 — no changes other than version
- ]]>
- Tue, 20 Apr 2021 17:40:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.0.2b1
- Inoreader sync: fixed (hopefully) cause of rate limit errors — now doing background sync of statuses much less often - note that this fix needs to be rolled out across all NetNewsWire users in order for it to have full effect
-Fixed regression with the L key — now works properly again
- ]]>
- Thu, 15 Apr 2021 19:15:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.0.1
- Adjusted layout of the add account sheet so that it fits on smaller monitors
-Sidebar: properly scale the smart feed icons when sidebar is set to large size in System Preferences
- ]]>
- Thu, 01 Apr 2021 20:22:00 -0700
-
- 10.15.0
-
-
- -
-
NetNewsWire 6.0.1b2
- Twitter: fixed a date parsing bug that could affect people in some locales, which would prevent Twitter feeds from working for them
-Feeds list: fixed bug where newly added feed would be called Untitled past the time when the app actually knows its name
-Fixed bug where next-unread command wouldn’t wrap around when you got to the bottom of the Feeds list
- ]]>
- Mon, 29 Mar 2021 20:55:00 -0700
-
- 10.15.0
-
-
-
diff --git a/Appcasts/netnewswire-release.xml b/Appcasts/netnewswire-release.xml
index 7c9cc240e..5475e3878 100755
--- a/Appcasts/netnewswire-release.xml
+++ b/Appcasts/netnewswire-release.xml
@@ -6,6 +6,24 @@
Most recent NetNewsWire releases (not test builds).
en
+ -
+
NetNewsWire 6.1.2
+ Twitter integration has been removed: Twitter has suspended NetNewsWire, and Twitter is removing free access to the Twitter API
+ Since Twitter does not provide RSS feeds, we’ve had to use the Twitter API. Without free access to that API, we can’t read feeds from Twitter.
+ We’ve left your Twitter feeds intact. If you have any starred items from those feeds, they will remain as long as you don’t delete those feeds.
+ You can still read whatever you have already downloaded. However, those feeds will no longer update.
+ Other changes…
+ Fixed a crashing bug that could happen in the sidebar
+ Fixed a bug that could prevent users from accessing BazQux if an article was missing a field
+ Fixed an issue that could prevent Feedly users from syncing if they tried to mark too many articles as read at the same time
+ Updated the Safari extension icon (credit to Louie Mantia for the new icon)
+ ]]>
+ Sat, 08 Apr 2023 10:30:00 -0800
+
+ 10.15.0
+
+
-
NetNewsWire 6.1
Void) -> Bool {
+ @MainActor func application(_ application: NSApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([NSUserActivityRestoring]) -> Void) -> Bool {
guard let mainWindowController = mainWindowController else {
return false
}
@@ -300,7 +300,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return true
}
- func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
+ @MainActor func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
// https://github.com/brentsimmons/NetNewsWire/issues/522
// I couldn’t reproduce the crashing bug, but it appears to happen on creating a main window
// and its views and view controllers. The check below is so that the app does nothing
@@ -314,26 +314,26 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return false
}
- func applicationDidBecomeActive(_ notification: Notification) {
+ @MainActor func applicationDidBecomeActive(_ notification: Notification) {
fireOldTimers()
}
- func applicationDidResignActive(_ notification: Notification) {
+ @MainActor func applicationDidResignActive(_ notification: Notification) {
ArticleStringFormatter.emptyCaches()
saveState()
}
- func application(_ application: NSApplication, didReceiveRemoteNotification userInfo: [String : Any]) {
+ @MainActor func application(_ application: NSApplication, didReceiveRemoteNotification userInfo: [String : Any]) {
AccountManager.shared.receiveRemoteNotification(userInfo: userInfo)
}
- func application(_ sender: NSApplication, openFile filename: String) -> Bool {
+ @MainActor func application(_ sender: NSApplication, openFile filename: String) -> Bool {
guard filename.hasSuffix(ArticleTheme.nnwThemeSuffix) else { return false }
importTheme(filename: filename)
return true
}
- func applicationWillTerminate(_ notification: Notification) {
+ @MainActor func applicationWillTerminate(_ notification: Notification) {
shuttingDown = true
saveState()
@@ -347,7 +347,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
while !isShutDownSyncDone && RunLoop.current.run(mode: .default, before: timeout) && timeout > Date() { }
}
- func presentThemeImportError(_ error: Error) {
+ @MainActor func presentThemeImportError(_ error: Error) {
var informativeText: String = ""
if let decodingError = error as? DecodingError {
@@ -392,13 +392,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: Notifications
- @objc func unreadCountDidChange(_ note: Notification) {
+ @MainActor @objc func unreadCountDidChange(_ note: Notification) {
if note.object is AccountManager {
unreadCount = AccountManager.shared.unreadCount
}
}
- @objc func webFeedSettingDidChange(_ note: Notification) {
+ @MainActor @objc func webFeedSettingDidChange(_ note: Notification) {
guard let feed = note.object as? WebFeed, let key = note.userInfo?[WebFeed.WebFeedSettingUserInfoKey] as? String else {
return
}
@@ -407,14 +407,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
}
- @objc func inspectableObjectsDidChange(_ note: Notification) {
+ @MainActor @objc func inspectableObjectsDidChange(_ note: Notification) {
guard let inspectorWindowController = inspectorWindowController, inspectorWindowController.isOpen else {
return
}
inspectorWindowController.objects = objectsForInspector()
}
- @objc func userDefaultsDidChange(_ note: Notification) {
+ @MainActor @objc func userDefaultsDidChange(_ note: Notification) {
updateSortMenuItems()
updateGroupByFeedMenuItem()
@@ -426,11 +426,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
updateDockBadge()
}
- @objc func didWakeNotification(_ note: Notification) {
+ @MainActor @objc func didWakeNotification(_ note: Notification) {
fireOldTimers()
}
- @objc func importDownloadedTheme(_ note: Notification) {
+ @MainActor @objc func importDownloadedTheme(_ note: Notification) {
guard let userInfo = note.userInfo,
let url = userInfo["url"] as? URL else {
return
@@ -442,7 +442,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: Main Window
- func createMainWindowController() -> MainWindowController {
+ @MainActor func createMainWindowController() -> MainWindowController {
let controller: MainWindowController
controller = windowControllerWithName("MainWindow") as! MainWindowController
@@ -453,13 +453,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return controller
}
- func windowControllerWithName(_ storyboardName: String) -> NSWindowController {
+ @MainActor func windowControllerWithName(_ storyboardName: String) -> NSWindowController {
let storyboard = NSStoryboard(name: NSStoryboard.Name(storyboardName), bundle: nil)
return storyboard.instantiateInitialController()! as! NSWindowController
}
@discardableResult
- func createAndShowMainWindow() -> MainWindowController {
+ @MainActor func createAndShowMainWindow() -> MainWindowController {
let controller = createMainWindowController()
controller.showWindow(self)
@@ -471,7 +471,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return controller
}
- func createAndShowMainWindowIfNecessary() {
+ @MainActor func createAndShowMainWindowIfNecessary() {
if mainWindowController == nil {
createAndShowMainWindow()
} else {
@@ -479,7 +479,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
}
- func removeMainWindow(_ windowController: MainWindowController) {
+ @MainActor func removeMainWindow(_ windowController: MainWindowController) {
guard mainWindowControllers.count > 1 else { return }
if let index = mainWindowControllers.firstIndex(of: windowController) {
mainWindowControllers.remove(at: index)
@@ -487,7 +487,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: NSUserInterfaceValidations
- func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
+ @MainActor func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
if shuttingDown {
return false
}
@@ -533,11 +533,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: UNUserNotificationCenterDelegate
- func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
+ @MainActor func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .badge, .sound])
}
- func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
+ @MainActor func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
@@ -553,7 +553,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: Add Feed
- func addWebFeed(_ urlString: String?, name: String? = nil, account: Account? = nil, folder: Folder? = nil) {
+ @MainActor func addWebFeed(_ urlString: String?, name: String? = nil, account: Account? = nil, folder: Folder? = nil) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
@@ -564,13 +564,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: - Dock Badge
- @objc func updateDockBadge() {
+ @MainActor @objc func updateDockBadge() {
let label = unreadCount > 0 ? "\(unreadCount)" : ""
NSApplication.shared.dockTile.badgeLabel = label
}
// MARK: - Actions
- @IBAction func showPreferences(_ sender: Any?) {
+ @MainActor @IBAction func showPreferences(_ sender: Any?) {
if preferencesWindowController == nil {
preferencesWindowController = windowControllerWithName("Preferences")
}
@@ -578,35 +578,35 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
preferencesWindowController!.showWindow(self)
}
- @IBAction func newMainWindow(_ sender: Any?) {
+ @MainActor @IBAction func newMainWindow(_ sender: Any?) {
createAndShowMainWindow()
}
- @IBAction func showMainWindow(_ sender: Any?) {
+ @MainActor @IBAction func showMainWindow(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
mainWindowController?.window?.makeKey()
}
- @IBAction func refreshAll(_ sender: Any?) {
+ @MainActor @IBAction func refreshAll(_ sender: Any?) {
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present)
}
- @IBAction func showAddWebFeedWindow(_ sender: Any?) {
+ @MainActor @IBAction func showAddWebFeedWindow(_ sender: Any?) {
addWebFeed(nil)
}
- @IBAction func showAddRedditFeedWindow(_ sender: Any?) {
+ @MainActor @IBAction func showAddRedditFeedWindow(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
addFeedController = AddFeedController(hostWindow: mainWindowController!.window!)
addFeedController?.showAddFeedSheet(.redditFeed)
}
- @IBAction func showAddFolderWindow(_ sender: Any?) {
+ @MainActor @IBAction func showAddFolderWindow(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
showAddFolderSheetOnWindow(mainWindowController!.window!)
}
- @IBAction func showKeyboardShortcutsWindow(_ sender: Any?) {
+ @MainActor @IBAction func showKeyboardShortcutsWindow(_ sender: Any?) {
if keyboardShortcutsWindowController == nil {
keyboardShortcutsWindowController = WebViewWindowController(title: NSLocalizedString("Keyboard Shortcuts", comment: "window title"))
@@ -625,7 +625,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
keyboardShortcutsWindowController!.showWindow(self)
}
- @IBAction func toggleInspectorWindow(_ sender: Any?) {
+ @MainActor @IBAction func toggleInspectorWindow(_ sender: Any?) {
if inspectorWindowController == nil {
inspectorWindowController = (windowControllerWithName("Inspector") as! InspectorWindowController)
}
@@ -639,7 +639,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
}
- @IBAction func importOPMLFromFile(_ sender: Any?) {
+ @MainActor @IBAction func importOPMLFromFile(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
return
@@ -649,7 +649,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
importOPMLController?.runSheetOnWindow(mainWindowController!.window!)
}
- @IBAction func importNNW3FromFile(_ sender: Any?) {
+ @MainActor @IBAction func importNNW3FromFile(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
return
@@ -657,7 +657,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
NNW3ImportController.askUserToImportNNW3Subscriptions(window: mainWindowController!.window!)
}
- @IBAction func exportOPML(_ sender: Any?) {
+ @MainActor @IBAction func exportOPML(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
return
@@ -667,30 +667,30 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
exportOPMLController?.runSheetOnWindow(mainWindowController!.window!)
}
- @IBAction func addAppNews(_ sender: Any?) {
+ @MainActor @IBAction func addAppNews(_ sender: Any?) {
if AccountManager.shared.anyAccountHasNetNewsWireNewsSubscription() {
return
}
addWebFeed(AccountManager.netNewsWireNewsURL, name: "NetNewsWire News")
}
- @IBAction func openWebsite(_ sender: Any?) {
+ @MainActor @IBAction func openWebsite(_ sender: Any?) {
Browser.open("https://netnewswire.com/", inBackground: false)
}
- @IBAction func showHelp(_ sender: Any?) {
+ @MainActor @IBAction func showHelp(_ sender: Any?) {
Browser.open("https://netnewswire.com/help/mac/6.1/en/", inBackground: false)
}
- @IBAction func gotoToday(_ sender: Any?) {
+ @MainActor @IBAction func gotoToday(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
mainWindowController!.gotoToday(sender)
}
- @IBAction func gotoAllUnread(_ sender: Any?) {
+ @MainActor @IBAction func gotoAllUnread(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
mainWindowController!.gotoAllUnread(sender)
@@ -702,27 +702,27 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
mainWindowController!.gotoStarred(sender)
}
- @IBAction func sortByOldestArticleOnTop(_ sender: Any?) {
+ @MainActor @IBAction func sortByOldestArticleOnTop(_ sender: Any?) {
AppDefaults.shared.timelineSortDirection = .orderedAscending
}
- @IBAction func sortByNewestArticleOnTop(_ sender: Any?) {
+ @MainActor @IBAction func sortByNewestArticleOnTop(_ sender: Any?) {
AppDefaults.shared.timelineSortDirection = .orderedDescending
}
- @IBAction func groupByFeedToggled(_ sender: NSMenuItem) {
+ @MainActor @IBAction func groupByFeedToggled(_ sender: NSMenuItem) {
AppDefaults.shared.timelineGroupByFeed.toggle()
}
- @IBAction func checkForUpdates(_ sender: Any?) {
+ @MainActor @IBAction func checkForUpdates(_ sender: Any?) {
#if !MAC_APP_STORE && !TEST
self.softwareUpdater.checkForUpdates()
#endif
}
- @IBAction func showAbout(_ sender: Any?) {
+ @MainActor @IBAction func showAbout(_ sender: Any?) {
if #available(macOS 12, *) {
for window in NSApplication.shared.windows {
if window.identifier == .aboutNetNewsWire {
@@ -741,7 +741,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: - NSMenuDelegate
-extension AppDelegate: NSMenuDelegate {
+@MainActor extension AppDelegate: NSMenuDelegate {
public func menuNeedsUpdate(_ menu: NSMenu) {
let newShareMenu = mainWindowController?.shareMenu
@@ -760,7 +760,7 @@ extension AppDelegate: NSMenuDelegate {
}
// MARK: - Debug Menu
-extension AppDelegate {
+@MainActor extension AppDelegate {
@IBAction func debugSearch(_ sender: Any?) {
AccountManager.shared.defaultAccount.debugRunSearch()
@@ -832,7 +832,7 @@ extension AppDelegate {
}
-internal extension AppDelegate {
+@MainActor internal extension AppDelegate {
func fireOldTimers() {
// It’s possible there’s a refresh timer set to go off in the past.
@@ -1007,7 +1007,7 @@ extension AppDelegate : ScriptingAppDelegate {
}
}
-extension AppDelegate: NSWindowRestoration {
+@MainActor extension AppDelegate: NSWindowRestoration {
@objc static func restoreWindow(withIdentifier identifier: NSUserInterfaceItemIdentifier, state: NSCoder, completionHandler: @escaping (NSWindow?, Error?) -> Void) {
var mainWindow: NSWindow? = nil
@@ -1021,7 +1021,7 @@ extension AppDelegate: NSWindowRestoration {
// Handle Notification Actions
-private extension AppDelegate {
+@MainActor private extension AppDelegate {
func handleMarkAsRead(userInfo: [AnyHashable: Any]) {
markArticle(userInfo: userInfo, statusKey: .read)
diff --git a/Mac/Browser.swift b/Mac/Browser.swift
index 7b47dad85..7b0ad4d3f 100644
--- a/Mac/Browser.swift
+++ b/Mac/Browser.swift
@@ -9,7 +9,7 @@
import Foundation
import RSWeb
-struct Browser {
+@MainActor struct Browser {
/// The user-specified default browser for opening web pages.
///
diff --git a/Mac/ErrorHandler.swift b/Mac/ErrorHandler.swift
index 4ec6f59be..1d332359c 100644
--- a/Mac/ErrorHandler.swift
+++ b/Mac/ErrorHandler.swift
@@ -10,16 +10,13 @@ import AppKit
import Account
import RSCore
-struct ErrorHandler: Logging {
+@MainActor struct ErrorHandler: Logging {
-
-
public static func present(_ error: Error) {
NSApplication.shared.presentError(error)
}
-
+
public static func log(_ error: Error) {
ErrorHandler.logger.error("\(error.localizedDescription, privacy: .public)")
}
-
}
diff --git a/Mac/Inspector/BuiltinSmartFeedInspectorViewController.swift b/Mac/Inspector/BuiltinSmartFeedInspectorViewController.swift
index 3c6c7b908..72bca9099 100644
--- a/Mac/Inspector/BuiltinSmartFeedInspectorViewController.swift
+++ b/Mac/Inspector/BuiltinSmartFeedInspectorViewController.swift
@@ -8,7 +8,7 @@
import AppKit
-final class BuiltinSmartFeedInspectorViewController: NSViewController, Inspector {
+@MainActor final class BuiltinSmartFeedInspectorViewController: NSViewController, Inspector {
@IBOutlet var nameTextField: NSTextField?
@IBOutlet weak var smartFeedImageView: NSImageView!
diff --git a/Mac/Inspector/FolderInspectorViewController.swift b/Mac/Inspector/FolderInspectorViewController.swift
index 63f76b0d7..6e12f248d 100644
--- a/Mac/Inspector/FolderInspectorViewController.swift
+++ b/Mac/Inspector/FolderInspectorViewController.swift
@@ -10,7 +10,7 @@ import AppKit
import Account
import RSCore
-final class FolderInspectorViewController: NSViewController, Inspector {
+@MainActor final class FolderInspectorViewController: NSViewController, Inspector {
@IBOutlet var nameTextField: NSTextField?
@IBOutlet weak var folderImageView: NSImageView!
diff --git a/Mac/Inspector/InspectorWindowController.swift b/Mac/Inspector/InspectorWindowController.swift
index 2686f86c4..078de1439 100644
--- a/Mac/Inspector/InspectorWindowController.swift
+++ b/Mac/Inspector/InspectorWindowController.swift
@@ -8,7 +8,7 @@
import AppKit
-protocol Inspector: AnyObject {
+@MainActor protocol Inspector: AnyObject {
var objects: [Any]? { get set }
var isFallbackInspector: Bool { get } // Can handle nothing-to-inspect or unexpected type of objects.
@@ -20,7 +20,7 @@ protocol Inspector: AnyObject {
typealias InspectorViewController = Inspector & NSViewController
-final class InspectorWindowController: NSWindowController {
+@MainActor final class InspectorWindowController: NSWindowController {
class var shouldOpenAtStartup: Bool {
return UserDefaults.standard.bool(forKey: DefaultsKey.windowIsOpen)
diff --git a/Mac/Inspector/NothingInspectorViewController.swift b/Mac/Inspector/NothingInspectorViewController.swift
index 376e6a594..168513e5e 100644
--- a/Mac/Inspector/NothingInspectorViewController.swift
+++ b/Mac/Inspector/NothingInspectorViewController.swift
@@ -8,7 +8,7 @@
import AppKit
-final class NothingInspectorViewController: NSViewController, Inspector {
+@MainActor final class NothingInspectorViewController: NSViewController, Inspector {
@IBOutlet var nothingTextField: NSTextField?
@IBOutlet var multipleTextField: NSTextField?
diff --git a/Mac/Inspector/WebFeedInspectorViewController.swift b/Mac/Inspector/WebFeedInspectorViewController.swift
index 58c24b254..123961828 100644
--- a/Mac/Inspector/WebFeedInspectorViewController.swift
+++ b/Mac/Inspector/WebFeedInspectorViewController.swift
@@ -11,7 +11,7 @@ import Articles
import Account
import UserNotifications
-final class WebFeedInspectorViewController: NSViewController, Inspector {
+@MainActor final class WebFeedInspectorViewController: NSViewController, Inspector {
@IBOutlet weak var iconView: IconView!
@IBOutlet weak var nameTextField: NSTextField?
diff --git a/Mac/MainWindow/About/CreditsNetNewsWireView.swift b/Mac/MainWindow/About/CreditsNetNewsWireView.swift
index 88a63fe75..f72318696 100644
--- a/Mac/MainWindow/About/CreditsNetNewsWireView.swift
+++ b/Mac/MainWindow/About/CreditsNetNewsWireView.swift
@@ -66,7 +66,9 @@ struct CreditsNetNewsWireView: View, LoadableAboutData {
.onTapGesture {
guard let url = appCredit.url else { return }
if let _ = URL(string: url) {
- Browser.open(url, inBackground: false)
+ Task { @MainActor in
+ Browser.open(url, inBackground: false)
+ }
}
}
}
diff --git a/Mac/MainWindow/AddFeed/AddFeedController.swift b/Mac/MainWindow/AddFeed/AddFeedController.swift
index 941fca98b..38c27414b 100644
--- a/Mac/MainWindow/AddFeed/AddFeedController.swift
+++ b/Mac/MainWindow/AddFeed/AddFeedController.swift
@@ -22,7 +22,7 @@ import RSParser
// Else,
// display error sheet.
-class AddFeedController: AddFeedWindowControllerDelegate {
+@MainActor final class AddFeedController: AddFeedWindowControllerDelegate {
private let hostWindow: NSWindow
private var addFeedWindowController: AddFeedWindowController?
diff --git a/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift b/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift
index e574d7fa5..50ad03701 100644
--- a/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift
+++ b/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift
@@ -14,7 +14,7 @@ enum AddFeedWindowControllerType {
case redditFeed
}
-protocol AddFeedWindowControllerDelegate: AnyObject {
+@MainActor protocol AddFeedWindowControllerDelegate: AnyObject {
// userEnteredURL will have already been validated and normalized.
func addFeedWindowController(_: AddFeedWindowController, userEnteredURL: URL, userEnteredTitle: String?, container: Container)
@@ -22,7 +22,7 @@ protocol AddFeedWindowControllerDelegate: AnyObject {
}
-protocol AddFeedWindowController {
+@MainActor protocol AddFeedWindowController {
var window: NSWindow? { get }
func runSheetOnWindow(_ hostWindow: NSWindow)
diff --git a/Mac/MainWindow/AddFeed/AddWebFeedWindowController.swift b/Mac/MainWindow/AddFeed/AddWebFeedWindowController.swift
index 16c8a4d72..40b6f6301 100644
--- a/Mac/MainWindow/AddFeed/AddWebFeedWindowController.swift
+++ b/Mac/MainWindow/AddFeed/AddWebFeedWindowController.swift
@@ -12,7 +12,7 @@ import RSTree
import Articles
import Account
-class AddWebFeedWindowController : NSWindowController, AddFeedWindowController {
+@MainActor final class AddWebFeedWindowController : NSWindowController, AddFeedWindowController {
@IBOutlet var urlTextField: NSTextField!
@IBOutlet var nameTextField: NSTextField!
diff --git a/Mac/MainWindow/AddFeed/FolderTreeMenu.swift b/Mac/MainWindow/AddFeed/FolderTreeMenu.swift
index 87250dd6b..1c696f0dc 100644
--- a/Mac/MainWindow/AddFeed/FolderTreeMenu.swift
+++ b/Mac/MainWindow/AddFeed/FolderTreeMenu.swift
@@ -11,7 +11,7 @@ import RSCore
import RSTree
import Account
-class FolderTreeMenu {
+@MainActor final class FolderTreeMenu {
static func createFolderPopupMenu(with rootNode: Node, restrictToSpecialAccounts: Bool = false) -> NSMenu {
diff --git a/Mac/MainWindow/AddFolder/AddFolderWindowController.swift b/Mac/MainWindow/AddFolder/AddFolderWindowController.swift
index 84053ee20..08cc50310 100644
--- a/Mac/MainWindow/AddFolder/AddFolderWindowController.swift
+++ b/Mac/MainWindow/AddFolder/AddFolderWindowController.swift
@@ -10,7 +10,7 @@ import AppKit
import Articles
import Account
-class AddFolderWindowController : NSWindowController {
+@MainActor final class AddFolderWindowController : NSWindowController {
@IBOutlet var folderNameTextField: NSTextField!
@IBOutlet var accountPopupButton: NSPopUpButton!
diff --git a/Mac/MainWindow/AddRedditFeedWindowController.swift b/Mac/MainWindow/AddRedditFeedWindowController.swift
index 55056ad34..0d07abccb 100644
--- a/Mac/MainWindow/AddRedditFeedWindowController.swift
+++ b/Mac/MainWindow/AddRedditFeedWindowController.swift
@@ -12,7 +12,7 @@ import RSTree
import Articles
import Account
-class AddRedditFeedWindowController : NSWindowController, AddFeedWindowController {
+@MainActor final class AddRedditFeedWindowController : NSWindowController, AddFeedWindowController {
@IBOutlet weak var typePopupButton: NSPopUpButton!
@IBOutlet weak var typeDescriptionLabel: NSTextField!
diff --git a/Mac/MainWindow/ArticleExtractorButton.swift b/Mac/MainWindow/ArticleExtractorButton.swift
index d5d30ccf8..1ea097769 100644
--- a/Mac/MainWindow/ArticleExtractorButton.swift
+++ b/Mac/MainWindow/ArticleExtractorButton.swift
@@ -15,7 +15,7 @@ enum ArticleExtractorButtonState {
case off
}
-class ArticleExtractorButton: NSButton {
+@MainActor final class ArticleExtractorButton: NSButton {
public var rightClickAction: Selector?
diff --git a/Mac/MainWindow/Detail/DetailIconSchemeHandler.swift b/Mac/MainWindow/Detail/DetailIconSchemeHandler.swift
index 4aee30c11..334605cbe 100644
--- a/Mac/MainWindow/Detail/DetailIconSchemeHandler.swift
+++ b/Mac/MainWindow/Detail/DetailIconSchemeHandler.swift
@@ -10,7 +10,7 @@ import Foundation
import WebKit
import Articles
-class DetailIconSchemeHandler: NSObject, WKURLSchemeHandler {
+final class DetailIconSchemeHandler: NSObject, WKURLSchemeHandler {
var currentArticle: Article?
diff --git a/Mac/MainWindow/Detail/DetailStatusBarView.swift b/Mac/MainWindow/Detail/DetailStatusBarView.swift
index eea5f72d2..119f5b112 100644
--- a/Mac/MainWindow/Detail/DetailStatusBarView.swift
+++ b/Mac/MainWindow/Detail/DetailStatusBarView.swift
@@ -9,7 +9,7 @@
import AppKit
import Articles
-final class DetailStatusBarView: NSView {
+@MainActor final class DetailStatusBarView: NSView {
@IBOutlet var urlLabel: NSTextField!
diff --git a/Mac/MainWindow/Detail/DetailViewController.swift b/Mac/MainWindow/Detail/DetailViewController.swift
index bcfd2533a..e4b099bf4 100644
--- a/Mac/MainWindow/Detail/DetailViewController.swift
+++ b/Mac/MainWindow/Detail/DetailViewController.swift
@@ -20,7 +20,7 @@ enum DetailState: Equatable {
case extracted(Article, ExtractedArticle, CGFloat?)
}
-final class DetailViewController: NSViewController, WKUIDelegate {
+@MainActor final class DetailViewController: NSViewController, WKUIDelegate {
@IBOutlet var containerView: DetailContainerView!
@IBOutlet var statusBarView: DetailStatusBarView!
diff --git a/Mac/MainWindow/Detail/DetailWebView.swift b/Mac/MainWindow/Detail/DetailWebView.swift
index 56f5d7812..5bdf0cbfc 100644
--- a/Mac/MainWindow/Detail/DetailWebView.swift
+++ b/Mac/MainWindow/Detail/DetailWebView.swift
@@ -10,7 +10,7 @@ import AppKit
import WebKit
import RSCore
-final class DetailWebView: WKWebView {
+@MainActor final class DetailWebView: WKWebView {
weak var keyboardDelegate: KeyboardDelegate?
diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift
index f1e5b2afe..e6c1ab126 100644
--- a/Mac/MainWindow/Detail/DetailWebViewController.swift
+++ b/Mac/MainWindow/Detail/DetailWebViewController.swift
@@ -17,7 +17,7 @@ protocol DetailWebViewControllerDelegate: AnyObject {
func mouseDidExit(_: DetailWebViewController)
}
-final class DetailWebViewController: NSViewController {
+@MainActor final class DetailWebViewController: NSViewController {
weak var delegate: DetailWebViewControllerDelegate?
var webView: DetailWebView!
diff --git a/Mac/MainWindow/MainWindow.swift b/Mac/MainWindow/MainWindow.swift
index 4fe147deb..18409f76a 100644
--- a/Mac/MainWindow/MainWindow.swift
+++ b/Mac/MainWindow/MainWindow.swift
@@ -8,7 +8,7 @@
import Foundation
-class MainWindow: NSWindow {
+@MainActor class MainWindow: NSWindow {
override func sendEvent(_ event: NSEvent) {
diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift
index 9e7e485e4..514ad4040 100644
--- a/Mac/MainWindow/MainWindowController.swift
+++ b/Mac/MainWindow/MainWindowController.swift
@@ -16,7 +16,7 @@ enum TimelineSourceMode {
case regular, search
}
-class MainWindowController : NSWindowController, NSUserInterfaceValidations {
+@MainActor final class MainWindowController : NSWindowController, NSUserInterfaceValidations {
@IBOutlet weak var articleThemePopUpButton: NSPopUpButton?
diff --git a/Mac/MainWindow/NNW3/NNW3ImportController.swift b/Mac/MainWindow/NNW3/NNW3ImportController.swift
index 32084490e..b36c1e7ee 100644
--- a/Mac/MainWindow/NNW3/NNW3ImportController.swift
+++ b/Mac/MainWindow/NNW3/NNW3ImportController.swift
@@ -9,7 +9,7 @@
import AppKit
import Account
-struct NNW3ImportController {
+@MainActor struct NNW3ImportController {
/// Import NNW3 subscriptions if they exist.
/// Return true if Subscriptions.plist was found and subscriptions were imported.
diff --git a/Mac/MainWindow/NNW3/NNW3OpenPanelAccessoryViewController.swift b/Mac/MainWindow/NNW3/NNW3OpenPanelAccessoryViewController.swift
index 110377b11..a8c2484c2 100644
--- a/Mac/MainWindow/NNW3/NNW3OpenPanelAccessoryViewController.swift
+++ b/Mac/MainWindow/NNW3/NNW3OpenPanelAccessoryViewController.swift
@@ -9,7 +9,7 @@
import AppKit
import Account
-final class NNW3OpenPanelAccessoryViewController: NSViewController {
+@MainActor final class NNW3OpenPanelAccessoryViewController: NSViewController {
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
diff --git a/Mac/MainWindow/OPML/ExportOPMLWindowController.swift b/Mac/MainWindow/OPML/ExportOPMLWindowController.swift
index 4b2ce20a6..0ff8284e0 100644
--- a/Mac/MainWindow/OPML/ExportOPMLWindowController.swift
+++ b/Mac/MainWindow/OPML/ExportOPMLWindowController.swift
@@ -9,7 +9,7 @@
import AppKit
import Account
-class ExportOPMLWindowController: NSWindowController {
+@MainActor final class ExportOPMLWindowController: NSWindowController {
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
private weak var hostWindow: NSWindow?
diff --git a/Mac/MainWindow/OPML/ImportOPMLWindowController.swift b/Mac/MainWindow/OPML/ImportOPMLWindowController.swift
index f0737fe93..3a53c3de3 100644
--- a/Mac/MainWindow/OPML/ImportOPMLWindowController.swift
+++ b/Mac/MainWindow/OPML/ImportOPMLWindowController.swift
@@ -9,7 +9,7 @@
import AppKit
import Account
-class ImportOPMLWindowController: NSWindowController {
+@MainActor final class ImportOPMLWindowController: NSWindowController {
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
private weak var hostWindow: NSWindow?
diff --git a/Mac/MainWindow/Sidebar/Cell/SidebarCell.swift b/Mac/MainWindow/Sidebar/Cell/SidebarCell.swift
index 0ec462a19..ffc1162be 100644
--- a/Mac/MainWindow/Sidebar/Cell/SidebarCell.swift
+++ b/Mac/MainWindow/Sidebar/Cell/SidebarCell.swift
@@ -11,7 +11,7 @@ import RSCore
import Account
import RSTree
-class SidebarCell : NSTableCellView {
+@MainActor final class SidebarCell : NSTableCellView {
var iconImage: IconImage? {
didSet {
diff --git a/Mac/MainWindow/Sidebar/Cell/SidebarCellAppearance.swift b/Mac/MainWindow/Sidebar/Cell/SidebarCellAppearance.swift
index c13996732..e5824ba6a 100644
--- a/Mac/MainWindow/Sidebar/Cell/SidebarCellAppearance.swift
+++ b/Mac/MainWindow/Sidebar/Cell/SidebarCellAppearance.swift
@@ -8,7 +8,7 @@
import AppKit
-struct SidebarCellAppearance: Equatable {
+@MainActor struct SidebarCellAppearance: Equatable {
let imageSize: CGSize
let imageMarginRight: CGFloat = 4.0
diff --git a/Mac/MainWindow/Sidebar/Cell/SidebarCellLayout.swift b/Mac/MainWindow/Sidebar/Cell/SidebarCellLayout.swift
index e054b924a..ed9e91a94 100644
--- a/Mac/MainWindow/Sidebar/Cell/SidebarCellLayout.swift
+++ b/Mac/MainWindow/Sidebar/Cell/SidebarCellLayout.swift
@@ -11,7 +11,7 @@ import RSCore
// image - title - unreadCount
-struct SidebarCellLayout {
+@MainActor struct SidebarCellLayout {
let faviconRect: CGRect
let titleRect: CGRect
diff --git a/Mac/MainWindow/Sidebar/Renaming/RenameWindowController.swift b/Mac/MainWindow/Sidebar/Renaming/RenameWindowController.swift
index 5cb8b6309..41d1dd07b 100644
--- a/Mac/MainWindow/Sidebar/Renaming/RenameWindowController.swift
+++ b/Mac/MainWindow/Sidebar/Renaming/RenameWindowController.swift
@@ -13,7 +13,7 @@ protocol RenameWindowControllerDelegate {
func renameWindowController(_ windowController: RenameWindowController, didRenameObject: Any, withNewName: String)
}
-final class RenameWindowController: NSWindowController {
+@MainActor final class RenameWindowController: NSWindowController {
@IBOutlet var renamePrompt: NSTextField!
@IBOutlet var newTitleTextField: NSTextField!
diff --git a/Mac/MainWindow/Sidebar/SidebarDeleteItemsAlert.swift b/Mac/MainWindow/Sidebar/SidebarDeleteItemsAlert.swift
index 899c29cf1..571137231 100644
--- a/Mac/MainWindow/Sidebar/SidebarDeleteItemsAlert.swift
+++ b/Mac/MainWindow/Sidebar/SidebarDeleteItemsAlert.swift
@@ -10,7 +10,7 @@ import AppKit
import RSTree
import Account
-enum SidebarDeleteItemsAlert {
+@MainActor enum SidebarDeleteItemsAlert {
/// Builds a delete confirmation dialog for the supplied nodes
static func build(_ nodes: [Node]) -> NSAlert {
diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift
index 7e0478d5f..a4fb7b5e9 100644
--- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift
+++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift
@@ -492,7 +492,7 @@ private extension SidebarOutlineDataSource {
return true
}
- func acceptSingleNonLocalFeedDrop(_ outlineView: NSOutlineView, _ draggedFeed: PasteboardWebFeed, _ parentNode: Node, _ index: Int) -> Bool {
+ @MainActor func acceptSingleNonLocalFeedDrop(_ outlineView: NSOutlineView, _ draggedFeed: PasteboardWebFeed, _ parentNode: Node, _ index: Int) -> Bool {
guard nodeIsDropTarget(parentNode), index == NSOutlineViewDropOnItemIndex else {
return false
}
diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineView.swift b/Mac/MainWindow/Sidebar/SidebarOutlineView.swift
index 2be34e87c..eefc29a63 100644
--- a/Mac/MainWindow/Sidebar/SidebarOutlineView.swift
+++ b/Mac/MainWindow/Sidebar/SidebarOutlineView.swift
@@ -10,7 +10,7 @@ import AppKit
import RSCore
import RSTree
-class SidebarOutlineView : NSOutlineView {
+@MainActor class SidebarOutlineView : NSOutlineView {
@IBOutlet var keyboardDelegate: KeyboardDelegate!
diff --git a/Mac/MainWindow/Sidebar/SidebarStatusBarView.swift b/Mac/MainWindow/Sidebar/SidebarStatusBarView.swift
index 315ea4ae3..6a85a6f9f 100644
--- a/Mac/MainWindow/Sidebar/SidebarStatusBarView.swift
+++ b/Mac/MainWindow/Sidebar/SidebarStatusBarView.swift
@@ -12,7 +12,7 @@ import Articles
import RSWeb
import Account
-final class SidebarStatusBarView: NSView {
+@MainActor final class SidebarStatusBarView: NSView {
@IBOutlet var progressIndicator: NSProgressIndicator!
@IBOutlet var progressLabel: NSTextField!
diff --git a/Mac/MainWindow/Timeline/TimelineContainerView.swift b/Mac/MainWindow/Timeline/TimelineContainerView.swift
index e75475405..6a8b42298 100644
--- a/Mac/MainWindow/Timeline/TimelineContainerView.swift
+++ b/Mac/MainWindow/Timeline/TimelineContainerView.swift
@@ -8,7 +8,7 @@
import AppKit
-final class TimelineContainerView: NSView {
+@MainActor final class TimelineContainerView: NSView {
private var contentViewConstraints: [NSLayoutConstraint]?
diff --git a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift
index c697a1a0c..81ec39b30 100644
--- a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift
+++ b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift
@@ -17,7 +17,7 @@ protocol TimelineContainerViewControllerDelegate: AnyObject {
}
-final class TimelineContainerViewController: NSViewController {
+@MainActor final class TimelineContainerViewController: NSViewController {
@IBOutlet weak var viewOptionsPopUpButton: NSPopUpButton!
@IBOutlet weak var newestToOldestMenuItem: NSMenuItem!
diff --git a/Mac/MainWindow/Timeline/TimelineTableRowView.swift b/Mac/MainWindow/Timeline/TimelineTableRowView.swift
index 54d87479c..d4598ef1e 100644
--- a/Mac/MainWindow/Timeline/TimelineTableRowView.swift
+++ b/Mac/MainWindow/Timeline/TimelineTableRowView.swift
@@ -8,7 +8,7 @@
import AppKit
-class TimelineTableRowView : NSTableRowView {
+@MainActor final class TimelineTableRowView : NSTableRowView {
private var separator: NSView?
diff --git a/Mac/MainWindow/Timeline/TimelineTableView.swift b/Mac/MainWindow/Timeline/TimelineTableView.swift
index e70bbed17..f5d8a9469 100644
--- a/Mac/MainWindow/Timeline/TimelineTableView.swift
+++ b/Mac/MainWindow/Timeline/TimelineTableView.swift
@@ -9,7 +9,7 @@
import AppKit
import RSCore
-class TimelineTableView: NSTableView {
+@MainActor final class TimelineTableView: NSTableView {
weak var keyboardDelegate: KeyboardDelegate?
diff --git a/Mac/MainWindow/URLPasteboardWriter+NetNewsWire.swift b/Mac/MainWindow/URLPasteboardWriter+NetNewsWire.swift
index 81c3e3ce4..0d3a9488e 100644
--- a/Mac/MainWindow/URLPasteboardWriter+NetNewsWire.swift
+++ b/Mac/MainWindow/URLPasteboardWriter+NetNewsWire.swift
@@ -8,7 +8,7 @@
import RSCore
-extension URLPasteboardWriter {
+@MainActor extension URLPasteboardWriter {
/// Copy URL strings, alerting the user the first time the array of URL strings contains `nil`.
/// - Parameters:
diff --git a/Mac/Scriptability/AppDelegate+Scriptability.swift b/Mac/Scriptability/AppDelegate+Scriptability.swift
index 07f3057c2..a16334eaf 100644
--- a/Mac/Scriptability/AppDelegate+Scriptability.swift
+++ b/Mac/Scriptability/AppDelegate+Scriptability.swift
@@ -39,7 +39,7 @@ extension AppDelegate : AppDelegateAppleEvents {
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(AppDelegate.getURL(_:_:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
- @objc func getURL(_ event: NSAppleEventDescriptor, _ withReplyEvent: NSAppleEventDescriptor) {
+ @MainActor @objc func getURL(_ event: NSAppleEventDescriptor, _ withReplyEvent: NSAppleEventDescriptor) {
guard var urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue else {
return
@@ -63,7 +63,9 @@ extension AppDelegate : AppDelegateAppleEvents {
do {
try ArticleThemeDownloader.shared.handleFile(at: location)
} catch {
- self.presentThemeImportError(error)
+ Task { @MainActor in
+ self.presentThemeImportError(error)
+ }
}
}
task.resume()
diff --git a/Shared/ArticleStyles/ArticleThemesManager.swift b/Shared/ArticleStyles/ArticleThemesManager.swift
index 2ac447450..5a3aaded4 100644
--- a/Shared/ArticleStyles/ArticleThemesManager.swift
+++ b/Shared/ArticleStyles/ArticleThemesManager.swift
@@ -86,11 +86,15 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging {
}
func presentedSubitemDidChange(at url: URL) {
- themeNames = buildThemeNames()
- do {
- currentTheme = try articleThemeWithThemeName(currentThemeName)
- } catch {
- appDelegate.presentThemeImportError(error)
+ if url.lastPathComponent.localizedCaseInsensitiveContains("nnwtheme") {
+ themeNames = buildThemeNames()
+ do {
+ currentTheme = try articleThemeWithThemeName(currentThemeName)
+ } catch {
+ Task { @MainActor in
+ appDelegate.presentThemeImportError(error)
+ }
+ }
}
}
diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift
index bf145a3b0..7592430f0 100644
--- a/iOS/AppDelegate.swift
+++ b/iOS/AppDelegate.swift
@@ -57,7 +57,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
var isSyncArticleStatusRunning = false
var isWaitingForSyncTasks = false
- override init() {
+ @MainActor override init() {
super.init()
appDelegate = self
@@ -76,7 +76,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
}
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ @MainActor func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AppDefaults.registerDefaults()
let isFirstRun = AppDefaults.shared.isFirstRun
@@ -124,7 +124,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
- func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
+ @MainActor func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
DispatchQueue.main.async {
self.resumeDatabaseProcessingIfNecessary()
AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) {
@@ -134,17 +134,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
}
- func applicationWillTerminate(_ application: UIApplication) {
+ @MainActor func applicationWillTerminate(_ application: UIApplication) {
shuttingDown = true
}
- func applicationDidEnterBackground(_ application: UIApplication) {
+ @MainActor func applicationDidEnterBackground(_ application: UIApplication) {
IconImageCache.shared.emptyCache()
}
// MARK: Notifications
- @objc func unreadCountDidChange(_ note: Notification) {
+ @MainActor @objc func unreadCountDidChange(_ note: Notification) {
if note.object is AccountManager {
unreadCount = AccountManager.shared.unreadCount
}
@@ -152,21 +152,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// MARK: - API
- func manualRefresh(errorHandler: @escaping (Error) -> ()) {
+ @MainActor func manualRefresh(errorHandler: @escaping (Error) -> ()) {
UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate } ).forEach {
$0.cleanUp(conditional: true)
}
AccountManager.shared.refreshAll(errorHandler: errorHandler)
}
- func resumeDatabaseProcessingIfNecessary() {
+ @MainActor func resumeDatabaseProcessingIfNecessary() {
if AccountManager.shared.isSuspended {
AccountManager.shared.resumeAll()
logger.info("Application processing resumed.")
}
}
- func prepareAccountsForBackground() {
+ @MainActor func prepareAccountsForBackground() {
extensionFeedAddRequestFile.suspend()
syncTimer?.invalidate()
scheduleBackgroundFeedRefresh()
@@ -175,7 +175,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
waitForSyncTasksToFinish()
}
- func prepareAccountsForForeground() {
+ @MainActor func prepareAccountsForForeground() {
extensionFeedAddRequestFile.resume()
syncTimer?.update()
@@ -215,7 +215,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
- func presentThemeImportError(_ error: Error) {
+ @MainActor func presentThemeImportError(_ error: Error) {
let windowScene = {
let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
return scenes.filter { $0.activationState == .foregroundActive }.first ?? scenes.first
@@ -228,7 +228,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// MARK: App Initialization
-private extension AppDelegate {
+@MainActor private extension AppDelegate {
private func initializeDownloaders() {
let tempDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
diff --git a/iOS/Article/ArticleExtractorButton.swift b/iOS/Article/ArticleExtractorButton.swift
index cc1087888..517c7ec00 100644
--- a/iOS/Article/ArticleExtractorButton.swift
+++ b/iOS/Article/ArticleExtractorButton.swift
@@ -15,7 +15,7 @@ enum ArticleExtractorButtonState {
case off
}
-class ArticleExtractorButton: UIButton {
+@MainActor class ArticleExtractorButton: UIButton {
private var animatedLayer: CALayer?
diff --git a/iOS/Article/ContextMenuPreviewViewController.swift b/iOS/Article/ContextMenuPreviewViewController.swift
index 3b7e18219..2d6e3e961 100644
--- a/iOS/Article/ContextMenuPreviewViewController.swift
+++ b/iOS/Article/ContextMenuPreviewViewController.swift
@@ -9,7 +9,7 @@
import UIKit
import Articles
-class ContextMenuPreviewViewController: UIViewController {
+@MainActor class ContextMenuPreviewViewController: UIViewController {
@IBOutlet weak var blogNameLabel: UILabel!
@IBOutlet weak var blogAuthorLabel: UILabel!
diff --git a/iOS/Article/ImageTransition.swift b/iOS/Article/ImageTransition.swift
index 25951b301..dc4a66d6d 100644
--- a/iOS/Article/ImageTransition.swift
+++ b/iOS/Article/ImageTransition.swift
@@ -8,7 +8,7 @@
import UIKit
-class ImageTransition: NSObject, UIViewControllerAnimatedTransitioning {
+@MainActor final class ImageTransition: NSObject, UIViewControllerAnimatedTransitioning {
private weak var webViewController: WebViewController?
private let duration = 0.4
diff --git a/iOS/KeyboardManager.swift b/iOS/KeyboardManager.swift
index 981fa5eb4..0c3788be7 100644
--- a/iOS/KeyboardManager.swift
+++ b/iOS/KeyboardManager.swift
@@ -15,7 +15,7 @@ enum KeyboardType: String {
case detail = "DetailKeyboardShortcuts"
}
-class KeyboardManager {
+@MainActor final class KeyboardManager {
private(set) var _keyCommands: [UIKeyCommand]
var keyCommands: [UIKeyCommand] {
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
index c2e84c7c0..13eeac341 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
@@ -15,7 +15,7 @@ protocol MasterFeedTableViewCellDelegate: AnyObject {
func masterFeedTableViewCellDisclosureDidToggle(_ sender: MasterFeedTableViewCell, expanding: Bool)
}
-class MasterFeedTableViewCell : VibrantTableViewCell {
+@MainActor final class MasterFeedTableViewCell : VibrantTableViewCell {
weak var delegate: MasterFeedTableViewCellDelegate?
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift
index d4c7338bb..1f1e266fb 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift
@@ -9,7 +9,7 @@
import UIKit
import RSCore
-struct MasterFeedTableViewCellLayout {
+@MainActor struct MasterFeedTableViewCellLayout {
private static let indentWidth = CGFloat(integerLiteral: 15)
private static let editingControlIndent = CGFloat(integerLiteral: 40)
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift
index 9451a3539..9bfe0e3e4 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift
@@ -12,7 +12,7 @@ protocol MasterFeedTableViewSectionHeaderDelegate {
func masterFeedTableViewSectionHeaderDisclosureDidToggle(_ sender: MasterFeedTableViewSectionHeader)
}
-class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
+@MainActor class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
var delegate: MasterFeedTableViewSectionHeaderDelegate?
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift
index 73dce3f69..eeacff01f 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift
@@ -9,7 +9,7 @@
import UIKit
import RSCore
-struct MasterFeedTableViewSectionHeaderLayout {
+@MainActor struct MasterFeedTableViewSectionHeaderLayout {
private static let labelMarginRight = CGFloat(integerLiteral: 8)
private static let disclosureButtonSize = CGSize(width: 44, height: 44)
diff --git a/iOS/MasterFeed/Cell/MasterFeedUnreadCountView.swift b/iOS/MasterFeed/Cell/MasterFeedUnreadCountView.swift
index 17db54492..ce2b7d912 100644
--- a/iOS/MasterFeed/Cell/MasterFeedUnreadCountView.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedUnreadCountView.swift
@@ -8,7 +8,7 @@
import UIKit
-class MasterFeedUnreadCountView : UIView {
+@MainActor class MasterFeedUnreadCountView : UIView {
var padding: UIEdgeInsets {
return UIEdgeInsets(top: 1.0, left: 9.0, bottom: 1.0, right: 9.0)
diff --git a/iOS/MasterFeed/RefreshProgressView.swift b/iOS/MasterFeed/RefreshProgressView.swift
index 5ecd13e1e..0e72d7738 100644
--- a/iOS/MasterFeed/RefreshProgressView.swift
+++ b/iOS/MasterFeed/RefreshProgressView.swift
@@ -10,7 +10,7 @@
import SwiftUI
import Account
-struct RefreshProgressView: View {
+@MainActor struct RefreshProgressView: View {
static let width: CGFloat = 100
static let height: CGFloat = 5
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineAccessibilityCellLayout.swift b/iOS/MasterTimeline/Cell/MasterTimelineAccessibilityCellLayout.swift
index 7441e5ae8..6c5390ec3 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineAccessibilityCellLayout.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineAccessibilityCellLayout.swift
@@ -9,7 +9,7 @@
import UIKit
import RSCore
-struct MasterTimelineAccessibilityCellLayout: MasterTimelineCellLayout {
+@MainActor struct MasterTimelineAccessibilityCellLayout: MasterTimelineCellLayout {
let height: CGFloat
let unreadIndicatorRect: CGRect
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineCellData.swift b/iOS/MasterTimeline/Cell/MasterTimelineCellData.swift
index fa06cdadc..c016d0523 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineCellData.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineCellData.swift
@@ -9,7 +9,7 @@
import UIKit
import Articles
-struct MasterTimelineCellData {
+@MainActor struct MasterTimelineCellData {
private static let noText = NSLocalizedString("(No Text)", comment: "No Text")
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift b/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift
index 6913a3989..44191a49d 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift
@@ -21,7 +21,7 @@ protocol MasterTimelineCellLayout {
}
-extension MasterTimelineCellLayout {
+@MainActor extension MasterTimelineCellLayout {
static func rectForUnreadIndicator(_ point: CGPoint) -> CGRect {
var r = CGRect.zero
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift b/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift
index 6b2ce58ad..85cf66048 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift
@@ -9,7 +9,7 @@
import UIKit
import RSCore
-struct MasterTimelineDefaultCellLayout: MasterTimelineCellLayout {
+@MainActor struct MasterTimelineDefaultCellLayout: MasterTimelineCellLayout {
static let cellPadding = UIEdgeInsets(top: 12, left: 8, bottom: 12, right: 20)
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
index 88c9fd782..eb628a9ed 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
@@ -9,7 +9,7 @@
import UIKit
import RSCore
-class MasterTimelineTableViewCell: VibrantTableViewCell {
+@MainActor class MasterTimelineTableViewCell: VibrantTableViewCell {
private let titleView = MasterTimelineTableViewCell.multiLineUILabel()
private let summaryView = MasterTimelineTableViewCell.multiLineUILabel()
diff --git a/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift b/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift
index 32205f0f9..748bdb5cd 100644
--- a/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift
+++ b/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift
@@ -8,7 +8,7 @@
import UIKit
-class MasterUnreadIndicatorView: UIView {
+@MainActor class MasterUnreadIndicatorView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
diff --git a/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift b/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift
index c5859ba42..4764629ff 100644
--- a/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift
+++ b/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift
@@ -26,7 +26,7 @@ struct TextFieldSizeInfo {
let numberOfLinesUsed: Int // A two-line text field may only use one line, for instance. This would equal 1, then.
}
-final class MultilineUILabelSizer {
+@MainActor final class MultilineUILabelSizer {
private let numberOfLines: Int
private let font: UIFont
diff --git a/iOS/MasterTimeline/Cell/SingleLineUILabelSizer.swift b/iOS/MasterTimeline/Cell/SingleLineUILabelSizer.swift
index 901df9a77..0af756044 100644
--- a/iOS/MasterTimeline/Cell/SingleLineUILabelSizer.swift
+++ b/iOS/MasterTimeline/Cell/SingleLineUILabelSizer.swift
@@ -12,7 +12,7 @@ import UIKit
// Uses a cache.
// Main thready only.
-final class SingleLineUILabelSizer {
+@MainActor final class SingleLineUILabelSizer {
let font: UIFont
private var cache = [String: CGSize]()
diff --git a/iOS/MasterTimeline/MarkAsReadAlertController.swift b/iOS/MasterTimeline/MarkAsReadAlertController.swift
index 5bbce1406..a0fb3a27a 100644
--- a/iOS/MasterTimeline/MarkAsReadAlertController.swift
+++ b/iOS/MasterTimeline/MarkAsReadAlertController.swift
@@ -15,7 +15,7 @@ extension UIView: MarkAsReadAlertControllerSourceType {}
extension UIBarButtonItem: MarkAsReadAlertControllerSourceType {}
-struct MarkAsReadAlertController {
+@MainActor struct MarkAsReadAlertController {
static func confirm(_ controller: UIViewController?,
coordinator: SceneCoordinator?,
diff --git a/iOS/MasterTimeline/MasterTimelineDataSource.swift b/iOS/MasterTimeline/MasterTimelineDataSource.swift
index 3647a93ae..156b04f28 100644
--- a/iOS/MasterTimeline/MasterTimelineDataSource.swift
+++ b/iOS/MasterTimeline/MasterTimelineDataSource.swift
@@ -8,7 +8,7 @@
import UIKit
-class MasterTimelineDataSource: UITableViewDiffableDataSource where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable {
+@MainActor final class MasterTimelineDataSource: UITableViewDiffableDataSource where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
diff --git a/iOS/MasterTimeline/MasterTimelineTitleView.swift b/iOS/MasterTimeline/MasterTimelineTitleView.swift
index ae1c31423..4b3c4f52e 100644
--- a/iOS/MasterTimeline/MasterTimelineTitleView.swift
+++ b/iOS/MasterTimeline/MasterTimelineTitleView.swift
@@ -8,7 +8,7 @@
import UIKit
-class MasterTimelineTitleView: UIView {
+@MainActor final class MasterTimelineTitleView: UIView {
@IBOutlet weak var iconView: IconView!
@IBOutlet weak var label: UILabel!
diff --git a/iOS/MasterTimeline/MasterTimelineUnreadCountView.swift b/iOS/MasterTimeline/MasterTimelineUnreadCountView.swift
index 66a7a4b26..a89b37fd7 100644
--- a/iOS/MasterTimeline/MasterTimelineUnreadCountView.swift
+++ b/iOS/MasterTimeline/MasterTimelineUnreadCountView.swift
@@ -8,7 +8,7 @@
import UIKit
-class MasterTimelineUnreadCountView: MasterFeedUnreadCountView {
+@MainActor final class MasterTimelineUnreadCountView: MasterFeedUnreadCountView {
override var padding: UIEdgeInsets {
return UIEdgeInsets(top: 2.0, left: 9.0, bottom: 2.0, right: 9.0)
diff --git a/iOS/RootSplitViewController.swift b/iOS/RootSplitViewController.swift
index 7b8c9d0c0..2c1075634 100644
--- a/iOS/RootSplitViewController.swift
+++ b/iOS/RootSplitViewController.swift
@@ -9,7 +9,7 @@
import UIKit
import Account
-class RootSplitViewController: UISplitViewController {
+final class RootSplitViewController: UISplitViewController {
var coordinator: SceneCoordinator!
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index 85f4febc5..6aa712981 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -52,7 +52,7 @@ struct FeedNode: Hashable {
}
}
-class SceneCoordinator: NSObject, UndoableCommandRunner, Logging {
+final class SceneCoordinator: NSObject, UndoableCommandRunner, Logging {
var undoableCommands = [UndoableCommand]()
var undoManager: UndoManager? {
diff --git a/iOS/SceneDelegate.swift b/iOS/SceneDelegate.swift
index 4c2fc6966..81947ebac 100644
--- a/iOS/SceneDelegate.swift
+++ b/iOS/SceneDelegate.swift
@@ -12,7 +12,7 @@ import Account
import Zip
import RSCore
-class SceneDelegate: UIResponder, UIWindowSceneDelegate, Logging {
+@MainActor final class SceneDelegate: UIResponder, UIWindowSceneDelegate, Logging {
var window: UIWindow?
var coordinator: SceneCoordinator!
@@ -195,7 +195,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, Logging {
do {
try ArticleThemeDownloader.shared.handleFile(at: location)
} catch {
- self.presentError(error)
+ Task { @MainActor in
+ self.presentError(error)
+ }
}
}
task.resume()
diff --git a/iOS/Settings/ArticleThemesTableViewController.swift b/iOS/Settings/ArticleThemesTableViewController.swift
index deefb41e9..3ab6d9557 100644
--- a/iOS/Settings/ArticleThemesTableViewController.swift
+++ b/iOS/Settings/ArticleThemesTableViewController.swift
@@ -114,7 +114,7 @@ extension ArticleThemesTableViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else { return }
- try ArticleThemeImporter.importTheme(controller: self, filename: url.standardizedFileURL.path)
+ ArticleThemeImporter.importTheme(controller: self, filename: url.standardizedFileURL.path)
}
}
diff --git a/iOS/TitleActivityItemSource.swift b/iOS/TitleActivityItemSource.swift
index fff0609aa..ef5d9c3cc 100644
--- a/iOS/TitleActivityItemSource.swift
+++ b/iOS/TitleActivityItemSource.swift
@@ -29,8 +29,6 @@ class TitleActivityItemSource: NSObject, UIActivityItemSource {
switch activityType.rawValue {
case "com.omnigroup.OmniFocus3.iOS.QuickEntry",
"com.culturedcode.ThingsiPhone.ShareExtension",
- "com.tapbots.Tweetbot4.shareextension",
- "com.tapbots.Tweetbot6.shareextension",
"com.buffer.buffer.Buffer":
return title
default: