From 93e76f617be7cadaa6ce2da3724b0baa82420dd0 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 08:46:34 -0700 Subject: [PATCH 1/9] Fix several warnings. --- Mac/MainWindow/Detail/DetailWebViewController.swift | 2 +- Mac/MainWindow/NNW3/NNW3ImportController.swift | 2 +- Mac/MainWindow/OPML/ExportOPMLWindowController.swift | 3 ++- Mac/MainWindow/OPML/ImportOPMLWindowController.swift | 3 ++- Mac/MainWindow/Sidebar/PasteboardFolder.swift | 2 +- Mac/MainWindow/Sidebar/PasteboardWebFeed.swift | 2 +- Mac/MainWindow/Timeline/Cell/TimelineCellAppearance.swift | 2 +- Modules/RSTree/Sources/RSTree/TreeController.swift | 4 ++-- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index cc2585691..c4ca44916 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -7,7 +7,7 @@ // import AppKit -import WebKit +@preconcurrency import WebKit import RSCore import RSWeb import Articles diff --git a/Mac/MainWindow/NNW3/NNW3ImportController.swift b/Mac/MainWindow/NNW3/NNW3ImportController.swift index 32084490e..c54a77c76 100644 --- a/Mac/MainWindow/NNW3/NNW3ImportController.swift +++ b/Mac/MainWindow/NNW3/NNW3ImportController.swift @@ -69,7 +69,7 @@ private extension NNW3ImportController { panel.canChooseDirectories = false panel.resolvesAliases = true panel.directoryURL = NNW3ImportController.defaultFileURL - panel.allowedFileTypes = ["plist"] + panel.allowedContentTypes = [.propertyList] panel.allowsOtherFileTypes = false panel.accessoryView = accessoryViewController.view panel.isAccessoryViewDisclosed = true diff --git a/Mac/MainWindow/OPML/ExportOPMLWindowController.swift b/Mac/MainWindow/OPML/ExportOPMLWindowController.swift index 4b2ce20a6..2d2ac30cf 100644 --- a/Mac/MainWindow/OPML/ExportOPMLWindowController.swift +++ b/Mac/MainWindow/OPML/ExportOPMLWindowController.swift @@ -8,6 +8,7 @@ import AppKit import Account +import UniformTypeIdentifiers class ExportOPMLWindowController: NSWindowController { @@ -75,7 +76,7 @@ class ExportOPMLWindowController: NSWindowController { func exportOPML(account: Account) { let panel = NSSavePanel() - panel.allowedFileTypes = ["opml"] + panel.allowedContentTypes = [UTType.opml] panel.allowsOtherFileTypes = false panel.prompt = NSLocalizedString("Export OPML", comment: "Export OPML") panel.title = NSLocalizedString("Export OPML", comment: "Export OPML") diff --git a/Mac/MainWindow/OPML/ImportOPMLWindowController.swift b/Mac/MainWindow/OPML/ImportOPMLWindowController.swift index f0737fe93..1db6ca6d2 100644 --- a/Mac/MainWindow/OPML/ImportOPMLWindowController.swift +++ b/Mac/MainWindow/OPML/ImportOPMLWindowController.swift @@ -8,6 +8,7 @@ import AppKit import Account +import UniformTypeIdentifiers class ImportOPMLWindowController: NSWindowController { @@ -85,7 +86,7 @@ class ImportOPMLWindowController: NSWindowController { panel.allowsMultipleSelection = false panel.canChooseDirectories = false panel.resolvesAliases = true - panel.allowedFileTypes = ["opml", "xml"] + panel.allowedContentTypes = [UTType.opml, UTType.xml] panel.allowsOtherFileTypes = false panel.beginSheetModal(for: hostWindow!) { modalResult in diff --git a/Mac/MainWindow/Sidebar/PasteboardFolder.swift b/Mac/MainWindow/Sidebar/PasteboardFolder.swift index 60c42154c..0ffd6c08b 100644 --- a/Mac/MainWindow/Sidebar/PasteboardFolder.swift +++ b/Mac/MainWindow/Sidebar/PasteboardFolder.swift @@ -84,7 +84,7 @@ struct PasteboardFolder: Hashable { } } -extension Folder: PasteboardWriterOwner { +extension Folder: @retroactive PasteboardWriterOwner { public var pasteboardWriter: NSPasteboardWriting { return FolderPasteboardWriter(folder: self) diff --git a/Mac/MainWindow/Sidebar/PasteboardWebFeed.swift b/Mac/MainWindow/Sidebar/PasteboardWebFeed.swift index 31612ded9..f0c838c47 100644 --- a/Mac/MainWindow/Sidebar/PasteboardWebFeed.swift +++ b/Mac/MainWindow/Sidebar/PasteboardWebFeed.swift @@ -146,7 +146,7 @@ struct PasteboardWebFeed: Hashable { } } -extension WebFeed: PasteboardWriterOwner { +extension WebFeed: @retroactive PasteboardWriterOwner { public var pasteboardWriter: NSPasteboardWriting { return WebFeedPasteboardWriter(webFeed: self) diff --git a/Mac/MainWindow/Timeline/Cell/TimelineCellAppearance.swift b/Mac/MainWindow/Timeline/Cell/TimelineCellAppearance.swift index b288ff911..dbfdf045b 100644 --- a/Mac/MainWindow/Timeline/Cell/TimelineCellAppearance.swift +++ b/Mac/MainWindow/Timeline/Cell/TimelineCellAppearance.swift @@ -67,7 +67,7 @@ struct TimelineCellAppearance: Equatable { } } -extension NSEdgeInsets: Equatable { +extension NSEdgeInsets: @retroactive Equatable { public static func ==(lhs: NSEdgeInsets, rhs: NSEdgeInsets) -> Bool { return lhs.left == rhs.left && lhs.top == rhs.top && lhs.right == rhs.right && lhs.bottom == rhs.bottom diff --git a/Modules/RSTree/Sources/RSTree/TreeController.swift b/Modules/RSTree/Sources/RSTree/TreeController.swift index 6475f9a60..84178243e 100644 --- a/Modules/RSTree/Sources/RSTree/TreeController.swift +++ b/Modules/RSTree/Sources/RSTree/TreeController.swift @@ -8,8 +8,8 @@ import Foundation -public protocol TreeControllerDelegate: class { - +public protocol TreeControllerDelegate: AnyObject { + func treeController(treeController: TreeController, childNodesFor: Node) -> [Node]? } From c43776ae3609d00aa708451cf6977fb474c6adae Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 08:55:50 -0700 Subject: [PATCH 2/9] Fix several warnings. --- Mac/MainWindow/Timeline/ArticlePasteboardWriter.swift | 2 +- Mac/Preferences/Accounts/AddAccountsView.swift | 2 +- Mac/Preferences/General/GeneralPrefencesViewController.swift | 3 ++- .../Sources/RSCore/AppKit/KeyboardDelegateProtocol.swift | 2 +- .../RSCore/Sources/RSCore/Shared/MainThreadOperation.swift | 2 +- .../Sources/RSCore/Shared/MainThreadOperationQueue.swift | 2 +- Modules/RSCore/Sources/RSCore/Shared/UndoableCommand.swift | 4 ++-- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Mac/MainWindow/Timeline/ArticlePasteboardWriter.swift b/Mac/MainWindow/Timeline/ArticlePasteboardWriter.swift index 4dd5b80d5..29be01571 100644 --- a/Mac/MainWindow/Timeline/ArticlePasteboardWriter.swift +++ b/Mac/MainWindow/Timeline/ArticlePasteboardWriter.swift @@ -10,7 +10,7 @@ import AppKit import Articles import RSCore -extension Article: PasteboardWriterOwner { +extension Article: @retroactive PasteboardWriterOwner { public var pasteboardWriter: NSPasteboardWriting { return ArticlePasteboardWriter(article: self) } diff --git a/Mac/Preferences/Accounts/AddAccountsView.swift b/Mac/Preferences/Accounts/AddAccountsView.swift index 6fc31957d..c8a496ad2 100644 --- a/Mac/Preferences/Accounts/AddAccountsView.swift +++ b/Mac/Preferences/Accounts/AddAccountsView.swift @@ -222,7 +222,7 @@ struct AddAccountsView: View { .padding(.top, 8) HStack { - ForEach(0.. Bool diff --git a/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperation.swift b/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperation.swift index 5f6fd5d0c..92a4f97c3 100644 --- a/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperation.swift +++ b/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperation.swift @@ -15,7 +15,7 @@ import Foundation /// When it’s canceled, it should do its best to stop /// doing whatever it’s doing. However, it should not /// leave data in an inconsistent state. -public protocol MainThreadOperation: class { +public protocol MainThreadOperation: AnyObject { // These three properties are set by MainThreadOperationQueue. Don’t set them. var isCanceled: Bool { get set } // Check this at appropriate times in case the operation has been canceled. diff --git a/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift b/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift index 36455586e..be7d225dd 100644 --- a/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift +++ b/Modules/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift @@ -8,7 +8,7 @@ import Foundation -public protocol MainThreadOperationDelegate: class { +public protocol MainThreadOperationDelegate: AnyObject { func operationDidComplete(_ operation: MainThreadOperation) func cancelOperation(_ operation: MainThreadOperation) func make(_ childOperation: MainThreadOperation, dependOn parentOperation: MainThreadOperation) diff --git a/Modules/RSCore/Sources/RSCore/Shared/UndoableCommand.swift b/Modules/RSCore/Sources/RSCore/Shared/UndoableCommand.swift index 1a79051b5..5594151ff 100644 --- a/Modules/RSCore/Sources/RSCore/Shared/UndoableCommand.swift +++ b/Modules/RSCore/Sources/RSCore/Shared/UndoableCommand.swift @@ -8,7 +8,7 @@ import Foundation -public protocol UndoableCommand: class { +public protocol UndoableCommand: AnyObject { var undoActionName: String { get } var redoActionName: String { get } @@ -39,7 +39,7 @@ extension UndoableCommand { // Useful for view controllers. -public protocol UndoableCommandRunner: class { +public protocol UndoableCommandRunner: AnyObject { var undoableCommands: [UndoableCommand] { get set } var undoManager: UndoManager? { get } From 14861e98d6c906d109d82464ac6f08ac22b8138b Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:04:59 -0700 Subject: [PATCH 3/9] Fix warnings in MacWebBrowser. Turn on warnings-as-errors for RSWeb. --- Modules/RSWeb/Package.swift | 4 +- .../RSWeb/Sources/RSWeb/MacWebBrowser.swift | 49 ++++++++++--------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Modules/RSWeb/Package.swift b/Modules/RSWeb/Package.swift index 71a511d0e..4b021105e 100644 --- a/Modules/RSWeb/Package.swift +++ b/Modules/RSWeb/Package.swift @@ -20,8 +20,8 @@ let package = Package( dependencies: [ "RSParser", "RSCore" - ] - //swiftSettings: [.unsafeFlags(["-warnings-as-errors"])] + ], + swiftSettings: [.unsafeFlags(["-warnings-as-errors"])] ), .testTarget( name: "RSWebTests", diff --git a/Modules/RSWeb/Sources/RSWeb/MacWebBrowser.swift b/Modules/RSWeb/Sources/RSWeb/MacWebBrowser.swift index 74c784169..1e8a1298f 100755 --- a/Modules/RSWeb/Sources/RSWeb/MacWebBrowser.swift +++ b/Modules/RSWeb/Sources/RSWeb/MacWebBrowser.swift @@ -8,6 +8,7 @@ #if os(macOS) import AppKit +import UniformTypeIdentifiers public class MacWebBrowser { @@ -18,34 +19,28 @@ public class MacWebBrowser { return false } - if (inBackground) { - do { - try NSWorkspace.shared.open(preparedURL, options: [.withoutActivation], configuration: [:]) - return true - } - catch { - return false - } + if inBackground { + + let configuration = NSWorkspace.OpenConfiguration() + configuration.activates = false + NSWorkspace.shared.open(url, configuration: configuration, completionHandler: nil) + + return true } - + return NSWorkspace.shared.open(preparedURL) } /// Returns an array of the browsers installed on the system, sorted by name. /// /// "Browsers" are applications that can both handle `https` URLs, and display HTML documents. - public class func sortedBrowsers() -> [MacWebBrowser] { - guard let httpsIDs = LSCopyAllHandlersForURLScheme("https" as CFString)?.takeRetainedValue() as? [String] else { - return [] - } + public static func sortedBrowsers() -> [MacWebBrowser] { - guard let htmlIDs = LSCopyAllRoleHandlersForContentType(kUTTypeHTML, .viewer)?.takeRetainedValue() as? [String] else { - return [] - } + let httpsAppURLs = NSWorkspace.shared.urlsForApplications(toOpen: URL(string: "https://apple.com/")!) + let htmlAppURLs = NSWorkspace.shared.urlsForApplications(toOpen: UTType.html) + let browserAppURLs = Set(httpsAppURLs).intersection(Set(htmlAppURLs)) - let browserIDs = Set(httpsIDs).intersection(Set(htmlIDs)) - - return browserIDs.compactMap { MacWebBrowser(bundleIdentifier: $0) }.sorted { + return browserAppURLs.compactMap { MacWebBrowser(url: $0) }.sorted { if let leftName = $0.name, let rightName = $1.name { return leftName < rightName } @@ -127,15 +122,25 @@ public class MacWebBrowser { /// - url: The URL to open. /// - inBackground: If `true`, attempt to load the URL without bringing the browser to the foreground. @discardableResult public func openURL(_ url: URL, inBackground: Bool = false) -> Bool { + + // TODO: make this function async. + guard let preparedURL = url.preparedForOpeningInBrowser() else { return false } - let options: NSWorkspace.LaunchOptions = inBackground ? [.withoutActivation] : [] + Task { @MainActor in - return NSWorkspace.shared.open([preparedURL], withAppBundleIdentifier: self.bundleIdentifier, options: options, additionalEventParamDescriptor: nil, launchIdentifiers: nil) + let configuration = NSWorkspace.OpenConfiguration() + if inBackground { + configuration.activates = false + } + + NSWorkspace.shared.open([preparedURL], withApplicationAt: self.url, configuration: configuration, completionHandler: nil) + } + + return true } - } extension MacWebBrowser: CustomDebugStringConvertible { From 7d801713a688b76726c32a2110b3a9d69aa246b3 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:06:04 -0700 Subject: [PATCH 4/9] Fix two minor, non-code-affecting warnings in CloudKitZone. --- Modules/RSCore/Sources/RSCore/CloudKit/CloudKitZone.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/RSCore/Sources/RSCore/CloudKit/CloudKitZone.swift b/Modules/RSCore/Sources/RSCore/CloudKit/CloudKitZone.swift index 10479231d..94dddb695 100644 --- a/Modules/RSCore/Sources/RSCore/CloudKit/CloudKitZone.swift +++ b/Modules/RSCore/Sources/RSCore/CloudKit/CloudKitZone.swift @@ -26,13 +26,13 @@ public enum CloudKitZoneError: LocalizedError { } } -public protocol CloudKitZoneDelegate: class { +public protocol CloudKitZoneDelegate: AnyObject { func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result) -> Void); } public typealias CloudKitRecordKey = (recordType: CKRecord.RecordType, recordID: CKRecord.ID) -public protocol CloudKitZone: class { +public protocol CloudKitZone: AnyObject { static var qualityOfService: QualityOfService { get } From a91fb73c76eb207ccc9b8cc7aa78ebb32056d6af Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:09:38 -0700 Subject: [PATCH 5/9] Fix warning in RSAppMovementMonitor.swift. --- .../Sources/RSCore/AppKit/RSAppMovementMonitor.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/RSCore/Sources/RSCore/AppKit/RSAppMovementMonitor.swift b/Modules/RSCore/Sources/RSCore/AppKit/RSAppMovementMonitor.swift index 83c1d49fb..7225937a1 100644 --- a/Modules/RSCore/Sources/RSCore/AppKit/RSAppMovementMonitor.swift +++ b/Modules/RSCore/Sources/RSCore/AppKit/RSAppMovementMonitor.swift @@ -128,8 +128,11 @@ public class RSAppMovementMonitor: NSObject { 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() { From 87421140157b41f782172da88819982a328b31a3 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:12:38 -0700 Subject: [PATCH 6/9] Fix warnings in UserApp.swift. --- .../Sources/RSCore/AppKit/UserApp.swift | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/Modules/RSCore/Sources/RSCore/AppKit/UserApp.swift b/Modules/RSCore/Sources/RSCore/AppKit/UserApp.swift index 974f82875..eb79a04d6 100644 --- a/Modules/RSCore/Sources/RSCore/AppKit/UserApp.swift +++ b/Modules/RSCore/Sources/RSCore/AppKit/UserApp.swift @@ -63,7 +63,7 @@ public final class UserApp { path = bundleURL.path } else { - path = NSWorkspace.shared.absolutePathForApplication(withBundleIdentifier: bundleID) + path = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID)?.path } if icon == nil, let path = path { icon = NSWorkspace.shared.icon(forFile: path) @@ -71,7 +71,7 @@ public final class UserApp { return } - path = NSWorkspace.shared.absolutePathForApplication(withBundleIdentifier: bundleID) + path = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID)?.path if let path = path { if icon == nil { icon = NSWorkspace.shared.icon(forFile: path) @@ -84,7 +84,7 @@ public final class UserApp { } } - public func launchIfNeeded() -> Bool { + public func launchIfNeeded() async -> Bool { // Return true if already running. // Return true if not running and successfully gets launched. @@ -99,20 +99,29 @@ public final class UserApp { } let url = URL(fileURLWithPath: path) - if let app = try? NSWorkspace.shared.launchApplication(at: url, options: [.withErrorPresentation], configuration: [:]) { - runningApplication = app - if app.isFinishedLaunching { - return true - } - Thread.sleep(forTimeInterval: 1.0) // Give the app time to launch. This is ugly. - if app.isFinishedLaunching { - return true - } - Thread.sleep(forTimeInterval: 1.0) // Give it some *more* time. - return true - } - return false + do { + let configuration = NSWorkspace.OpenConfiguration() + configuration.promptsUserIfNeeded = true + + let app = try await NSWorkspace.shared.openApplication(at: url, configuration: configuration) + runningApplication = app + + if app.isFinishedLaunching { + return true + } + + try? await Task.sleep(for: .seconds(1)) // Give the app time to launch. This is ugly. + if app.isFinishedLaunching { + return true + } + + try? await Task.sleep(for: .seconds(1)) // Give it some *more* time. + return true + + } catch { + return false + } } public func bringToFront() -> Bool { From db3cbaa8a3148adc0cad2bd0a7e08802810540ac Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:16:00 -0700 Subject: [PATCH 7/9] Deal with impact of async changes to UserApp. --- .../SendToMarsEditCommand.swift | 10 ++++- .../SendToMicroBlogCommand.swift | 37 ++++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/Shared/ExtensionPoints/SendToMarsEditCommand.swift b/Shared/ExtensionPoints/SendToMarsEditCommand.swift index 500df72fe..484398a87 100644 --- a/Shared/ExtensionPoints/SendToMarsEditCommand.swift +++ b/Shared/ExtensionPoints/SendToMarsEditCommand.swift @@ -29,11 +29,17 @@ final class SendToMarsEditCommand: SendToCommand { guard let article = (object as? ArticlePasteboardWriter)?.article else { return } - guard let app = appToUse(), app.launchIfNeeded(), app.bringToFront() else { + guard let app = appToUse() else { return } - send(article, to: app) + Task { + guard await app.launchIfNeeded(), app.bringToFront() else { + return + } + + send(article, to: app) + } } } diff --git a/Shared/ExtensionPoints/SendToMicroBlogCommand.swift b/Shared/ExtensionPoints/SendToMicroBlogCommand.swift index bd5d000d2..4d6fe3bd7 100644 --- a/Shared/ExtensionPoints/SendToMicroBlogCommand.swift +++ b/Shared/ExtensionPoints/SendToMicroBlogCommand.swift @@ -37,24 +37,27 @@ final class SendToMicroBlogCommand: SendToCommand { guard let article = (object as? ArticlePasteboardWriter)?.article else { return } - guard microBlogApp.launchIfNeeded(), microBlogApp.bringToFront() else { - return + + Task { + guard await microBlogApp.launchIfNeeded(), microBlogApp.bringToFront() else { + return + } + + // TODO: get text from contentHTML or contentText if no title and no selectedText. + // TODO: consider selectedText. + + let s = article.attributionString + article.linkString + + let urlQueryDictionary = ["text": s] + guard let urlQueryString = urlQueryDictionary.urlQueryString else { + return + } + guard let url = URL(string: "microblog://post?" + urlQueryString) else { + return + } + + NSWorkspace.shared.open(url) } - - // TODO: get text from contentHTML or contentText if no title and no selectedText. - // TODO: consider selectedText. - - let s = article.attributionString + article.linkString - - let urlQueryDictionary = ["text": s] - guard let urlQueryString = urlQueryDictionary.urlQueryString else { - return - } - guard let url = URL(string: "microblog://post?" + urlQueryString) else { - return - } - - NSWorkspace.shared.open(url) } } From 6ad239fb39f607a8b1d1dfa1e9bc8744714e93c1 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:30:25 -0700 Subject: [PATCH 8/9] =?UTF-8?q?Add=20sharingServicesForItems=5FnoDeprecati?= =?UTF-8?q?onWarning=20to=20silence=20deprecation=20that=20we=E2=80=99re?= =?UTF-8?q?=20accepting.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Timeline/NSSharingService+Extension.h | 23 +++++++++++++++++++ .../Timeline/NSSharingService+Extension.m | 22 ++++++++++++++++++ ...melineViewController+ContextualMenus.swift | 2 +- Mac/NetNewsWire-Bridging-Header.h | 1 + 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 Mac/MainWindow/Timeline/NSSharingService+Extension.h create mode 100644 Mac/MainWindow/Timeline/NSSharingService+Extension.m diff --git a/Mac/MainWindow/Timeline/NSSharingService+Extension.h b/Mac/MainWindow/Timeline/NSSharingService+Extension.h new file mode 100644 index 000000000..389a58161 --- /dev/null +++ b/Mac/MainWindow/Timeline/NSSharingService+Extension.h @@ -0,0 +1,23 @@ +// +// NSObject+NSSharingService_RSCore.h +// RSCore +// +// Created by Brent Simmons on 11/3/24. +// + +@import AppKit; + +@interface NSSharingService (NoDeprecationWarning) + +// The only way to create custom UI — a Share menu, for instance — +// is to use the unfortunately deprecated +// +[NSSharingService sharingServicesForItems:]. +// This cover method allows us to not generate a warning. +// +// We know it’s deprecated, and we don’t want to be bugged +// about it every time we build. (If anyone from Apple +// is reading this — a replacement would be very welcome!) + ++ (NSArray *)sharingServicesForItems_noDeprecationWarning:(NSArray *)items; + +@end diff --git a/Mac/MainWindow/Timeline/NSSharingService+Extension.m b/Mac/MainWindow/Timeline/NSSharingService+Extension.m new file mode 100644 index 000000000..cf2e71e26 --- /dev/null +++ b/Mac/MainWindow/Timeline/NSSharingService+Extension.m @@ -0,0 +1,22 @@ +// +// NSSharingService+Extension.m +// RSCore +// +// Created by Brent Simmons on 11/3/24. +// + +#import "NSSharingService+Extension.h" + +@implementation NSSharingService (NoDeprecationWarning) + ++ (NSArray *)sharingServicesForItems_noDeprecationWarning:(NSArray *)items { + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + + return [NSSharingService sharingServicesForItems:items]; + +#pragma clang diagnostic pop +} + +@end diff --git a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift index dd83afdcb..1cc5d6e3e 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift @@ -200,7 +200,7 @@ private extension TimelineViewController { let sortedArticles = articles.sortedByDate(.orderedAscending) let items = sortedArticles.map { ArticlePasteboardWriter(article: $0) } - let standardServices = NSSharingService.sharingServices(forItems: items) + let standardServices = NSSharingService.sharingServices(forItems_noDeprecationWarning: items) as? [NSSharingService] ?? [NSSharingService]() let customServices = SharingServicePickerDelegate.customSharingServices(for: items) let services = standardServices + customServices if services.isEmpty { diff --git a/Mac/NetNewsWire-Bridging-Header.h b/Mac/NetNewsWire-Bridging-Header.h index 3f547bcf1..01bbec4e2 100644 --- a/Mac/NetNewsWire-Bridging-Header.h +++ b/Mac/NetNewsWire-Bridging-Header.h @@ -7,3 +7,4 @@ // #import "WKPreferencesPrivate.h" +#import "NSSharingService+Extension.h" From 6c30dd3c4203e259dc5c0c6697b42f5da64ff420 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 25 Apr 2025 09:34:32 -0700 Subject: [PATCH 9/9] Click the upgrade-settings thing and let Xcode fill in the right things so it will stop nagging. --- .../.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme | 2 +- .../.swiftpm/xcode/xcshareddata/xcschemes/Articles.xcscheme | 2 +- NetNewsWire.xcodeproj/project.pbxproj | 3 ++- .../xcschemes/NetNewsWire iOS Share Extension.xcscheme | 2 +- .../xcshareddata/xcschemes/NetNewsWire-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/NetNewsWire.xcscheme | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Modules/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme b/Modules/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme index 4b5135dd2..0b77ed72e 100644 --- a/Modules/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme +++ b/Modules/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme @@ -1,6 +1,6 @@