Fix numerous concurrency warnings.

This commit is contained in:
Brent Simmons 2024-04-07 21:32:47 -07:00
parent 4b0e7addc9
commit d1dc4cceec
15 changed files with 98 additions and 74 deletions

View File

@ -22,8 +22,7 @@ public struct AccountSyncError {
init(account: Account, error: Error) {
self.account = account
self.error = error
os_log(.error, log: AccountSyncError.log, "%@", error.localizedDescription)
os_log(.error, log: Self.log, "%@", error.localizedDescription)
}
}

View File

@ -36,16 +36,16 @@ class CloudKitRemoteNotificationOperation: MainThreadOperation {
self.operationDelegate?.operationDidComplete(self)
return
}
os_log(.debug, log: log, "Processing remote notification...")
accountZone.receiveRemoteNotification(userInfo: userInfo) {
articlesZone.receiveRemoteNotification(userInfo: self.userInfo) {
os_log(.debug, log: self.log, "Done processing remote notification.")
self.operationDelegate?.operationDidComplete(self)
}
Task { @MainActor in
await accountZone.receiveRemoteNotification(userInfo: userInfo)
await articlesZone.receiveRemoteNotification(userInfo: self.userInfo)
os_log(.debug, log: self.log, "Done processing remote notification.")
self.operationDelegate?.operationDidComplete(self)
}
}
}

View File

@ -804,7 +804,7 @@ extension FeedlyAPICaller: FeedlyMarkArticlesService {
var entryIDs: [String]
}
func mark(_ articleIDs: Set<String>, as action: FeedlyMarkAction, completion: @escaping (Result<Void, Error>) -> ()) {
func mark(_ articleIDs: Set<String>, as action: FeedlyMarkAction, completion: @escaping @Sendable (Result<Void, Error>) -> ()) {
guard !isSuspended else {
return DispatchQueue.main.async {
completion(.failure(TransportError.suspended))

View File

@ -13,8 +13,9 @@ import Core
import Feedly
public protocol OAuthAccountAuthorizationOperationDelegate: AnyObject {
func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didCreate account: Account)
func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didFailWith error: Error)
@MainActor func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didCreate account: Account)
@MainActor func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didFailWith error: Error)
}
public enum OAuthAccountAuthorizationOperationError: LocalizedError {

View File

@ -98,7 +98,7 @@ public struct OAuthAuthorizationErrorResponse: Error {
/// Error values as enumerated in section 4.1.2.1 of the OAuth 2.0 Authorization Framework.
/// https://tools.ietf.org/html/rfc6749#section-4.1.2.1
public enum OAuthAuthorizationError: String {
public enum OAuthAuthorizationError: String, Sendable {
case invalidRequest = "invalid_request"
case unauthorizedClient = "unauthorized_client"
case accessDenied = "access_denied"

View File

@ -119,6 +119,15 @@ public extension CloudKitZone {
})
}
func receiveRemoteNotification(userInfo: [AnyHashable : Any]) async {
await withCheckedContinuation { continuation in
self.receiveRemoteNotification(userInfo: userInfo) {
continuation.resume()
}
}
}
func receiveRemoteNotification(userInfo: [AnyHashable : Any], completion: @escaping () -> Void) {
let note = CKRecordZoneNotification(fromRemoteNotificationDictionary: userInfo)
guard note?.recordZoneID?.zoneName == zoneID.zoneName else {

View File

@ -128,8 +128,11 @@ import AppKit
func relaunchFromURL(_ appURL: URL) {
// Relaunching is best achieved by requesting that the system launch the app
// at the given URL with the "new instance" option to prevent it simply reactivating us.
let _ = try? NSWorkspace.shared.launchApplication(at: appURL, options: .newInstance, configuration: [:])
NSApp.terminate(self)
let configuration = NSWorkspace.OpenConfiguration()
configuration.createsNewApplicationInstance = true
NSWorkspace.shared.openApplication(at: appURL, configuration: configuration) { _,_ in
NSApp.terminate(self)
}
}
func defaultHandler() {

View File

@ -32,5 +32,6 @@ public enum FeedlyMarkAction: String, Sendable {
}
public protocol FeedlyMarkArticlesService: AnyObject {
func mark(_ articleIDs: Set<String>, as action: FeedlyMarkAction, completion: @escaping (Result<Void, Error>) -> ())
func mark(_ articleIDs: Set<String>, as action: FeedlyMarkAction, completion: @escaping @Sendable (Result<Void, Error>) -> ())
}

View File

@ -54,10 +54,13 @@ struct Browser {
NSWorkspace.shared.open(preparedURL, configuration: configuration) { (runningApplication, error) in
guard error != nil else { return }
if let defaultBrowser = defaultBrowser {
defaultBrowser.openURL(url, inBackground: inBackground)
} else {
MacWebBrowser.openURL(url, inBackground: inBackground)
Task { @MainActor in
if let defaultBrowser = defaultBrowser {
defaultBrowser.openURL(url, inBackground: inBackground)
} else {
MacWebBrowser.openURL(url, inBackground: inBackground)
}
}
}
}

View File

@ -10,15 +10,15 @@ import Foundation
import WebKit
import Articles
class DetailIconSchemeHandler: NSObject, WKURLSchemeHandler {
final class DetailIconSchemeHandler: NSObject, WKURLSchemeHandler {
var currentArticle: Article?
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
Task { @MainActor in
guard let responseURL = urlSchemeTask.request.url, let iconImage = self.currentArticle?.iconImage() else {
guard let responseURL = urlSchemeTask.request.url, let iconImage = self.currentArticle?.iconImage() else {
urlSchemeTask.didFailWithError(URLError(.fileDoesNotExist))
return
}

View File

@ -168,29 +168,33 @@ extension Feed: PasteboardWriterOwner {
// MARK: - NSPasteboardWriting
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
nonisolated func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [FeedPasteboardWriter.feedUTIType, .URL, .string, FeedPasteboardWriter.feedUTIInternalType]
MainActor.assumeIsolated {
return [FeedPasteboardWriter.feedUTIType, .URL, .string, FeedPasteboardWriter.feedUTIInternalType]
}
}
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
nonisolated func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
let plist: Any?
switch type {
case .string:
plist = feed.nameForDisplay
case .URL:
plist = feed.url
case FeedPasteboardWriter.feedUTIType:
plist = exportDictionary
case FeedPasteboardWriter.feedUTIInternalType:
plist = internalDictionary
default:
plist = nil
MainActor.assumeIsolated {
let plist: Any?
switch type {
case .string:
plist = feed.nameForDisplay
case .URL:
plist = feed.url
case FeedPasteboardWriter.feedUTIType:
plist = exportDictionary
case FeedPasteboardWriter.feedUTIInternalType:
plist = internalDictionary
default:
plist = nil
}
return plist
}
return plist
}
}

View File

@ -104,25 +104,29 @@ extension Folder: PasteboardWriterOwner {
// MARK: - NSPasteboardWriting
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
nonisolated func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.string, FolderPasteboardWriter.folderUTIInternalType]
MainActor.assumeIsolated {
return [.string, FolderPasteboardWriter.folderUTIInternalType]
}
}
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
nonisolated func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
let plist: Any?
switch type {
case .string:
plist = folder.nameForDisplay
case FolderPasteboardWriter.folderUTIInternalType:
plist = internalDictionary
default:
plist = nil
MainActor.assumeIsolated {
let plist: Any?
switch type {
case .string:
plist = folder.nameForDisplay
case FolderPasteboardWriter.folderUTIInternalType:
plist = internalDictionary
default:
plist = nil
}
return plist
}
return plist
}
}

View File

@ -2350,8 +2350,8 @@
849C64611ED37A5D003D8FC0 /* Products */,
51C452B22265141B00C03939 /* Frameworks */,
84A699132BC34E8500605AB8 /* ArticleExtractor */,
51CD32C624D2DEF9009ABAEF /* Account */,
84FB9FAE2BC3494B00B7AFC3 /* FeedFinder */,
51CD32C624D2DEF9009ABAEF /* Account */,
84A699182BC3524C00605AB8 /* LocalAccount */,
84FB9FAD2BC344F800B7AFC3 /* Feedbin */,
84A699192BC36EDB00605AB8 /* Feedly */,

View File

@ -20,23 +20,25 @@ import Account
// MARK: - NSPasteboardWriting
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
nonisolated func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.string]
}
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
nonisolated func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
let plist: Any?
switch type {
case .string:
plist = smartFeed.nameForDisplay
default:
plist = nil
MainActor.assumeIsolated {
let plist: Any?
switch type {
case .string:
plist = smartFeed.nameForDisplay
default:
plist = nil
}
return plist
}
return plist
}
}

View File

@ -11,10 +11,9 @@ import Account
import Articles
import UserNotifications
final class UserNotificationManager: NSObject {
override init() {
super.init()
final class UserNotificationManager: Sendable {
init() {
NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(statusesDidChange(_:)), name: .StatusesDidChange, object: nil)
registerCategoriesAndActions()
@ -103,5 +102,4 @@ private extension UserNotificationManager {
UNUserNotificationCenter.current().setNotificationCategories([newArticleCategory])
}
}