From 300ffbb711771870f1c6919d193a99243b66ab15 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 7 Apr 2024 15:05:38 -0700 Subject: [PATCH] Create ArticleExtractor module. --- ArticleExtractor/.gitignore | 8 ++++ ArticleExtractor/Package.swift | 30 ++++++++++++++ .../ArticleExtractor}/ArticleExtractor.swift | 19 +++++---- .../ArticleExtractor}/ExtractedArticle.swift | 33 ++++++++------- .../ArticleExtractorTests.swift | 12 ++++++ FeedFinder/Package.swift | 1 - .../Detail/DetailViewController.swift | 1 + Mac/MainWindow/MainWindowController.swift | 1 + NetNewsWire.xcodeproj/project.pbxproj | 40 ++++++++----------- .../Article Rendering/ArticleRenderer.swift | 1 + iOS/Article/ArticleViewController.swift | 1 + iOS/Article/WebViewController.swift | 1 + 12 files changed, 96 insertions(+), 52 deletions(-) create mode 100644 ArticleExtractor/.gitignore create mode 100644 ArticleExtractor/Package.swift rename {Shared/Article Extractor => ArticleExtractor/Sources/ArticleExtractor}/ArticleExtractor.swift (87%) rename {Shared/Article Extractor => ArticleExtractor/Sources/ArticleExtractor}/ExtractedArticle.swift (57%) create mode 100644 ArticleExtractor/Tests/ArticleExtractorTests/ArticleExtractorTests.swift diff --git a/ArticleExtractor/.gitignore b/ArticleExtractor/.gitignore new file mode 100644 index 000000000..0023a5340 --- /dev/null +++ b/ArticleExtractor/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/ArticleExtractor/Package.swift b/ArticleExtractor/Package.swift new file mode 100644 index 000000000..af892f032 --- /dev/null +++ b/ArticleExtractor/Package.swift @@ -0,0 +1,30 @@ +// swift-tools-version: 5.10 + +import PackageDescription + +let package = Package( + name: "ArticleExtractor", + platforms: [.macOS(.v14), .iOS(.v17)], + products: [ + .library( + name: "ArticleExtractor", + targets: ["ArticleExtractor"]), + ], + dependencies: [ + .package(path: "../FoundationExtras") + ], + targets: [ + .target( + name: "ArticleExtractor", + dependencies: [ + "FoundationExtras", + ], + swiftSettings: [ + .enableExperimentalFeature("StrictConcurrency") + ] + ), + .testTarget( + name: "ArticleExtractorTests", + dependencies: ["ArticleExtractor"]), + ] +) diff --git a/Shared/Article Extractor/ArticleExtractor.swift b/ArticleExtractor/Sources/ArticleExtractor/ArticleExtractor.swift similarity index 87% rename from Shared/Article Extractor/ArticleExtractor.swift rename to ArticleExtractor/Sources/ArticleExtractor/ArticleExtractor.swift index eb025e5ea..61b5274d2 100644 --- a/Shared/Article Extractor/ArticleExtractor.swift +++ b/ArticleExtractor/Sources/ArticleExtractor/ArticleExtractor.swift @@ -9,7 +9,7 @@ import Foundation import FoundationExtras -public enum ArticleExtractorState { +public enum ArticleExtractorState: Sendable { case ready case processing case failedToParse @@ -17,22 +17,21 @@ public enum ArticleExtractorState { case cancelled } -protocol ArticleExtractorDelegate { +public protocol ArticleExtractorDelegate { @MainActor func articleExtractionDidFail(with: Error) @MainActor func articleExtractionDidComplete(extractedArticle: ExtractedArticle) } -@MainActor final class ArticleExtractor { +@MainActor public final class ArticleExtractor { + + public var state: ArticleExtractorState! + public var article: ExtractedArticle? + public var delegate: ArticleExtractorDelegate? + public let articleLink: String? private var dataTask: URLSessionDataTask? = nil - - var state: ArticleExtractorState! - var article: ExtractedArticle? - var delegate: ArticleExtractorDelegate? - let articleLink: String? - - private let url: URL! + private let url: URL! public init?(_ articleLink: String, clientID: String, clientSecret: String) { self.articleLink = articleLink diff --git a/Shared/Article Extractor/ExtractedArticle.swift b/ArticleExtractor/Sources/ArticleExtractor/ExtractedArticle.swift similarity index 57% rename from Shared/Article Extractor/ExtractedArticle.swift rename to ArticleExtractor/Sources/ArticleExtractor/ExtractedArticle.swift index 460302477..761fd4cc9 100644 --- a/Shared/Article Extractor/ExtractedArticle.swift +++ b/ArticleExtractor/Sources/ArticleExtractor/ExtractedArticle.swift @@ -8,23 +8,23 @@ import Foundation -struct ExtractedArticle: Codable, Equatable { +public struct ExtractedArticle: Codable, Equatable, Sendable { + + public let title: String? + public let author: String? + public let datePublished: String? + public let dek: String? + public let leadImageURL: String? + public let content: String? + public let nextPageURL: String? + public let url: String? + public let domain: String? + public let excerpt: String? + public let wordCount: Int? + public let direction: String? + public let totalPages: Int? + public let renderedPages: Int? - let title: String? - let author: String? - let datePublished: String? - let dek: String? - let leadImageURL: String? - let content: String? - let nextPageURL: String? - let url: String? - let domain: String? - let excerpt: String? - let wordCount: Int? - let direction: String? - let totalPages: Int? - let renderedPages: Int? - enum CodingKeys: String, CodingKey { case title = "title" case author = "author" @@ -41,5 +41,4 @@ struct ExtractedArticle: Codable, Equatable { case totalPages = "total_pages" case renderedPages = "rendered_pages" } - } diff --git a/ArticleExtractor/Tests/ArticleExtractorTests/ArticleExtractorTests.swift b/ArticleExtractor/Tests/ArticleExtractorTests/ArticleExtractorTests.swift new file mode 100644 index 000000000..a91142d2c --- /dev/null +++ b/ArticleExtractor/Tests/ArticleExtractorTests/ArticleExtractorTests.swift @@ -0,0 +1,12 @@ +import XCTest +@testable import ArticleExtractor + +final class ArticleExtractorTests: XCTestCase { + func testExample() throws { + // XCTest Documentation + // https://developer.apple.com/documentation/xctest + + // Defining Test Cases and Test Methods + // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods + } +} diff --git a/FeedFinder/Package.swift b/FeedFinder/Package.swift index abf09412d..397730b6f 100644 --- a/FeedFinder/Package.swift +++ b/FeedFinder/Package.swift @@ -16,7 +16,6 @@ let package = Package( .package(path: "../FoundationExtras"), .package(path: "../CommonErrors"), ], - targets: [ .target( name: "FeedFinder", diff --git a/Mac/MainWindow/Detail/DetailViewController.swift b/Mac/MainWindow/Detail/DetailViewController.swift index 845f2fafc..0c5758b54 100644 --- a/Mac/MainWindow/Detail/DetailViewController.swift +++ b/Mac/MainWindow/Detail/DetailViewController.swift @@ -10,6 +10,7 @@ import Foundation import WebKit import Articles import Web +import ArticleExtractor enum DetailState: Equatable { case noSelection diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index cc072f4f9..57199216f 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -12,6 +12,7 @@ import Articles import Account import Core import AppKitExtras +import ArticleExtractor enum TimelineSourceMode { case regular, search diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index a82b26e3f..dcbdf66e6 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -354,10 +354,6 @@ 51F9F3F723DF6DB200A314FD /* ArticleIconSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F9F3F623DF6DB200A314FD /* ArticleIconSchemeHandler.swift */; }; 51F9F3F923DFB16300A314FD /* UITableView-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F9F3F823DFB16300A314FD /* UITableView-Extensions.swift */; }; 51F9F3FB23DFB25700A314FD /* Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F9F3FA23DFB25700A314FD /* Animations.swift */; }; - 51FA73A42332BE110090D516 /* ArticleExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A32332BE110090D516 /* ArticleExtractor.swift */; }; - 51FA73A52332BE110090D516 /* ArticleExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A32332BE110090D516 /* ArticleExtractor.swift */; }; - 51FA73A72332BE880090D516 /* ExtractedArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A62332BE880090D516 /* ExtractedArticle.swift */; }; - 51FA73A82332BE880090D516 /* ExtractedArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A62332BE880090D516 /* ExtractedArticle.swift */; }; 51FA73B72332D5F70090D516 /* LegacyArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73B62332D5F70090D516 /* LegacyArticleExtractorButton.swift */; }; 51FD413B2342BD0500880194 /* TimelineUnreadCountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FD413A2342BD0500880194 /* TimelineUnreadCountView.swift */; }; 51FE10032345529D0056195D /* UserNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FE10022345529D0056195D /* UserNotificationManager.swift */; }; @@ -510,7 +506,6 @@ 65ED4025235DEF6C0081F399 /* DetailWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E8E0EA202F693600562D8F /* DetailWebView.swift */; }; 65ED4026235DEF6C0081F399 /* TimelineTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97691ED9EBC8007D329B /* TimelineTableRowView.swift */; }; 65ED4027235DEF6C0081F399 /* UnreadIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97751ED9EC04007D329B /* UnreadIndicatorView.swift */; }; - 65ED4028235DEF6C0081F399 /* ExtractedArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A62332BE880090D516 /* ExtractedArticle.swift */; }; 65ED4029235DEF6C0081F399 /* DeleteCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C9C1FAE83C600ECDEDB /* DeleteCommand.swift */; }; 65ED402A235DEF6C0081F399 /* AddFeedWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97521ED9EAC0007D329B /* AddFeedWindowController.swift */; }; 65ED402B235DEF6C0081F399 /* ImportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */; }; @@ -519,7 +514,6 @@ 65ED402E235DEF6C0081F399 /* MainWindowController+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */; }; 65ED402F235DEF6C0081F399 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C9FC6E22629E1200D921D6 /* PreferencesWindowController.swift */; }; 65ED4030235DEF6C0081F399 /* SmallIconProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84411E701FE5FBFA004B527F /* SmallIconProvider.swift */; }; - 65ED4031235DEF6C0081F399 /* ArticleExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A32332BE110090D516 /* ArticleExtractor.swift */; }; 65ED4032235DEF6C0081F399 /* FetchRequestQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CAFCA322BC8C08007694F0 /* FetchRequestQueue.swift */; }; 65ED4033235DEF6C0081F399 /* SidebarKeyboardDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */; }; 65ED4034235DEF6C0081F399 /* AccountsPreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C9FC7222629E1200D921D6 /* AccountsPreferencesViewController.swift */; }; @@ -691,6 +685,8 @@ 84A37CB5201ECD610087C5AF /* RenameWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A37CB4201ECD610087C5AF /* RenameWindowController.swift */; }; 84A3EE5F223B667F00557320 /* DefaultFeeds.opml in Resources */ = {isa = PBXBuildFile; fileRef = 84A3EE52223B667F00557320 /* DefaultFeeds.opml */; }; 84A3EE61223B667F00557320 /* DefaultFeeds.opml in Resources */ = {isa = PBXBuildFile; fileRef = 84A3EE52223B667F00557320 /* DefaultFeeds.opml */; }; + 84A699152BC34F3D00605AB8 /* ArticleExtractor in Frameworks */ = {isa = PBXBuildFile; productRef = 84A699142BC34F3D00605AB8 /* ArticleExtractor */; }; + 84A699172BC34F4400605AB8 /* ArticleExtractor in Frameworks */ = {isa = PBXBuildFile; productRef = 84A699162BC34F4400605AB8 /* ArticleExtractor */; }; 84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EA92031617300BC20B7 /* PasteboardFolder.swift */; }; 84AD1EBA2031649C00BC20B7 /* SmartFeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EB92031649C00BC20B7 /* SmartFeedPasteboardWriter.swift */; }; 84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EBB2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift */; }; @@ -1266,8 +1262,6 @@ 51F9F3F623DF6DB200A314FD /* ArticleIconSchemeHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleIconSchemeHandler.swift; sourceTree = ""; }; 51F9F3F823DFB16300A314FD /* UITableView-Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView-Extensions.swift"; sourceTree = ""; }; 51F9F3FA23DFB25700A314FD /* Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Animations.swift; sourceTree = ""; }; - 51FA73A32332BE110090D516 /* ArticleExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractor.swift; sourceTree = ""; }; - 51FA73A62332BE880090D516 /* ExtractedArticle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractedArticle.swift; sourceTree = ""; }; 51FA73B62332D5F70090D516 /* LegacyArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyArticleExtractorButton.swift; sourceTree = ""; }; 51FD413A2342BD0500880194 /* TimelineUnreadCountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineUnreadCountView.swift; sourceTree = ""; }; 51FE10022345529D0056195D /* UserNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationManager.swift; sourceTree = ""; }; @@ -1396,6 +1390,7 @@ 84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToMarsEditCommand.swift; sourceTree = ""; }; 84A37CB4201ECD610087C5AF /* RenameWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RenameWindowController.swift; sourceTree = ""; }; 84A3EE52223B667F00557320 /* DefaultFeeds.opml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DefaultFeeds.opml; sourceTree = ""; }; + 84A699132BC34E8500605AB8 /* ArticleExtractor */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = ArticleExtractor; sourceTree = ""; }; 84AD1EA92031617300BC20B7 /* PasteboardFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteboardFolder.swift; sourceTree = ""; }; 84AD1EB92031649C00BC20B7 /* SmartFeedPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeedPasteboardWriter.swift; sourceTree = ""; }; 84AD1EBB2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarOutlineDataSource.swift; sourceTree = ""; }; @@ -1598,6 +1593,7 @@ 8410C4A52BC1E28200D4F799 /* ReaderAPI in Frameworks */, 84C1A8582BBBA5BD006E3E96 /* Web in Frameworks */, 516B695F24D2F33B00B5702F /* Account in Frameworks */, + 84A699152BC34F3D00605AB8 /* ArticleExtractor in Frameworks */, 845611742BBD145D00507B73 /* ParserObjC in Frameworks */, 845611712BBD145D00507B73 /* Parser in Frameworks */, 513F32712593EE6F0003048F /* Articles in Frameworks */, @@ -1619,6 +1615,7 @@ 513277642590FC640064F1E7 /* SyncDatabase in Frameworks */, 17192ADA2567B3D500AAEACA /* RSSparkle in Frameworks */, 8438C2DB2BABE0B00040C9EE /* CoreResources in Frameworks */, + 84A699172BC34F4400605AB8 /* ArticleExtractor in Frameworks */, 5132775E2590FC640064F1E7 /* Articles in Frameworks */, 84DCA5252BABBB5A00792720 /* Core in Frameworks */, 8479ABE32B9E906E00F84C4D /* Database in Frameworks */, @@ -2059,15 +2056,6 @@ name = Frameworks; sourceTree = ""; }; - 51FA739A2332BDE70090D516 /* Article Extractor */ = { - isa = PBXGroup; - children = ( - 51FA73A32332BE110090D516 /* ArticleExtractor.swift */, - 51FA73A62332BE880090D516 /* ExtractedArticle.swift */, - ); - path = "Article Extractor"; - sourceTree = ""; - }; 51FE0FF9234552490056195D /* UserNotifications */ = { isa = PBXGroup; children = ( @@ -2359,6 +2347,7 @@ D5907CDA2002F084005947E5 /* xcconfig */, 849C64611ED37A5D003D8FC0 /* Products */, 51C452B22265141B00C03939 /* Frameworks */, + 84A699132BC34E8500605AB8 /* ArticleExtractor */, 51CD32C624D2DEF9009ABAEF /* Account */, 84FB9FAE2BC3494B00B7AFC3 /* FeedFinder */, 84FB9FAD2BC344F800B7AFC3 /* Feedbin */, @@ -2461,7 +2450,6 @@ 51C452AD2265102800C03939 /* Timeline */, 84702AB31FA27AE8006B8943 /* Commands */, 51934CCC231078DC006127BE /* Activity */, - 51FA739A2332BDE70090D516 /* Article Extractor */, 51C452A822650DA100C03939 /* Article Rendering */, 849A97861ED9ECEF007D329B /* Article Styles */, 84DAEE201F86CAE00058304B /* Importers */, @@ -2985,6 +2973,7 @@ 845611702BBD145D00507B73 /* Parser */, 845611732BBD145D00507B73 /* ParserObjC */, 8410C4A42BC1E28200D4F799 /* ReaderAPI */, + 84A699142BC34F3D00605AB8 /* ArticleExtractor */, ); productName = "NetNewsWire-iOS"; productReference = 840D617C2029031C009BC708 /* NetNewsWire.app */; @@ -3032,6 +3021,7 @@ 8456116A2BBD145200507B73 /* Parser */, 8456116D2BBD145200507B73 /* ParserObjC */, 8410C4A22BC1E27A00D4F799 /* ReaderAPI */, + 84A699162BC34F4400605AB8 /* ArticleExtractor */, ); productName = NetNewsWire; productReference = 849C64601ED37A5D003D8FC0 /* NetNewsWire.app */; @@ -3862,7 +3852,6 @@ 65ED4026235DEF6C0081F399 /* TimelineTableRowView.swift in Sources */, 65ED4027235DEF6C0081F399 /* UnreadIndicatorView.swift in Sources */, 51A9A5F22380DE520033AADF /* AddFeedDefaultContainer.swift in Sources */, - 65ED4028235DEF6C0081F399 /* ExtractedArticle.swift in Sources */, 65ED4029235DEF6C0081F399 /* DeleteCommand.swift in Sources */, 65ED402A235DEF6C0081F399 /* AddFeedWindowController.swift in Sources */, 65ED402B235DEF6C0081F399 /* ImportOPMLWindowController.swift in Sources */, @@ -3875,7 +3864,6 @@ 653813192680E15B007A082C /* CacheCleaner.swift in Sources */, 847120D82B8AE6AF00BBFC34 /* UTType+Extensions.swift in Sources */, 510C417E24E5D1AE008226FD /* ExtensionFeedAddRequest.swift in Sources */, - 65ED4031235DEF6C0081F399 /* ArticleExtractor.swift in Sources */, 51868BF2254386630011A17B /* SidebarDeleteItemsAlert.swift in Sources */, 6538131B2680E176007A082C /* IconImage.swift in Sources */, 65ED4032235DEF6C0081F399 /* FetchRequestQueue.swift in Sources */, @@ -3955,7 +3943,6 @@ 176813D02564BA5900D98635 /* WidgetData.swift in Sources */, 510289CD24519A1D00426DDF /* SelectComboTableViewCell.swift in Sources */, 514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */, - 51FA73A52332BE110090D516 /* ArticleExtractor.swift in Sources */, 51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */, FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */, 51C4525C226508DF00C03939 /* String-Extensions.swift in Sources */, @@ -3993,7 +3980,6 @@ 5142192A23522B5500E07E2C /* ImageViewController.swift in Sources */, 516244E3241E19F000B61C47 /* ColorPaletteTableViewController.swift in Sources */, 51C45258226508CF00C03939 /* AppAssets.swift in Sources */, - 51FA73A82332BE880090D516 /* ExtractedArticle.swift in Sources */, 51C4527C2265091600C03939 /* TimelineDefaultCellLayout.swift in Sources */, 51E4398023805EBC00015C31 /* AddComboTableViewCell.swift in Sources */, 51C4529A22650A0400C03939 /* ArticleTheme.swift in Sources */, @@ -4219,7 +4205,6 @@ 84E8E0EB202F693600562D8F /* DetailWebView.swift in Sources */, 849A976C1ED9EBC8007D329B /* TimelineTableRowView.swift in Sources */, 849A977B1ED9EC04007D329B /* UnreadIndicatorView.swift in Sources */, - 51FA73A72332BE880090D516 /* ExtractedArticle.swift in Sources */, 84B99C9D1FAE83C600ECDEDB /* DeleteCommand.swift in Sources */, 849A97541ED9EAC0007D329B /* AddFeedWindowController.swift in Sources */, 5144EA40227A37EC00D19003 /* ImportOPMLWindowController.swift in Sources */, @@ -4231,7 +4216,6 @@ 84C9FC7922629E1200D921D6 /* PreferencesWindowController.swift in Sources */, 84411E711FE5FBFA004B527F /* SmallIconProvider.swift in Sources */, 847120D72B8AE6AF00BBFC34 /* UTType+Extensions.swift in Sources */, - 51FA73A42332BE110090D516 /* ArticleExtractor.swift in Sources */, 84CAFCA422BC8C08007694F0 /* FetchRequestQueue.swift in Sources */, 844B5B591FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift in Sources */, 84C9FC7C22629E1200D921D6 /* AccountsPreferencesViewController.swift in Sources */, @@ -4945,6 +4929,14 @@ isa = XCSwiftPackageProductDependency; productName = Web; }; + 84A699142BC34F3D00605AB8 /* ArticleExtractor */ = { + isa = XCSwiftPackageProductDependency; + productName = ArticleExtractor; + }; + 84A699162BC34F4400605AB8 /* ArticleExtractor */ = { + isa = XCSwiftPackageProductDependency; + productName = ArticleExtractor; + }; 84C1A8572BBBA5BD006E3E96 /* Web */ = { isa = XCSwiftPackageProductDependency; productName = Web; diff --git a/Shared/Article Rendering/ArticleRenderer.swift b/Shared/Article Rendering/ArticleRenderer.swift index 3c1fd0c00..2bf1db30e 100644 --- a/Shared/Article Rendering/ArticleRenderer.swift +++ b/Shared/Article Rendering/ArticleRenderer.swift @@ -13,6 +13,7 @@ import UIKit import Articles import Account import Core +import ArticleExtractor @MainActor struct ArticleRenderer { diff --git a/iOS/Article/ArticleViewController.swift b/iOS/Article/ArticleViewController.swift index 1b23925fc..6f60b462d 100644 --- a/iOS/Article/ArticleViewController.swift +++ b/iOS/Article/ArticleViewController.swift @@ -11,6 +11,7 @@ import WebKit import Account import Articles import SafariServices +import ArticleExtractor class ArticleViewController: UIViewController { diff --git a/iOS/Article/WebViewController.swift b/iOS/Article/WebViewController.swift index 5ca9bdc52..1c467fed4 100644 --- a/iOS/Article/WebViewController.swift +++ b/iOS/Article/WebViewController.swift @@ -13,6 +13,7 @@ import Articles import SafariServices import MessageUI import Core +import ArticleExtractor protocol WebViewControllerDelegate: AnyObject { func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState)