diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 4633e2070..ff3a360ad 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -391,6 +391,8 @@ 840958632201629A002C1579 /* Subscribe to Feed.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 840BEE4121D70E64009BBAFA /* CrashReportWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840BEE4021D70E64009BBAFA /* CrashReportWindowController.swift */; }; 840D617F2029031C009BC708 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840D617E2029031C009BC708 /* AppDelegate.swift */; }; + 8413C1382D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */; }; + 8413C1392D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */; }; 84162A152038C12C00035290 /* MarkCommandValidationStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84162A142038C12C00035290 /* MarkCommandValidationStatus.swift */; }; 841ABA4E20145E7300980E11 /* NothingInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841ABA4D20145E7300980E11 /* NothingInspectorViewController.swift */; }; 841ABA5E20145E9200980E11 /* FolderInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841ABA5D20145E9200980E11 /* FolderInspectorViewController.swift */; }; @@ -1030,6 +1032,7 @@ 840D617E2029031C009BC708 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 840D61952029031D009BC708 /* NetNewsWire_iOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetNewsWire_iOSTests.swift; sourceTree = ""; }; 840D61972029031D009BC708 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UniformTypeIdentifiers+Extras.swift"; sourceTree = ""; }; 84162A142038C12C00035290 /* MarkCommandValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkCommandValidationStatus.swift; sourceTree = ""; }; 841ABA4D20145E7300980E11 /* NothingInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NothingInspectorViewController.swift; sourceTree = ""; }; 841ABA5D20145E9200980E11 /* FolderInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderInspectorViewController.swift; sourceTree = ""; }; @@ -2096,6 +2099,7 @@ 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */, 511B9805237DCAC90028BCAA /* UserInfoKey.swift */, 8454C3F2263F2D8700E3F9C7 /* IconImageCache.swift */, + 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */, 51C452AD2265102800C03939 /* Timeline */, 84702AB31FA27AE8006B8943 /* Commands */, 51934CCC231078DC006127BE /* Activity */, @@ -3282,6 +3286,7 @@ FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */, 51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */, 51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */, + 8413C1382D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */, 51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */, 5148F4552336DB7000F8CD8B /* MasterTimelineTitleView.swift in Sources */, 51627A6723861DA3007B3B4B /* MasterFeedViewController+Drag.swift in Sources */, @@ -3431,6 +3436,7 @@ 84E8E0EB202F693600562D8F /* DetailWebView.swift in Sources */, 849A976C1ED9EBC8007D329B /* TimelineTableRowView.swift in Sources */, 849A977B1ED9EC04007D329B /* UnreadIndicatorView.swift in Sources */, + 8413C1392D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */, 51FA73A72332BE880090D516 /* ExtractedArticle.swift in Sources */, 84B99C9D1FAE83C600ECDEDB /* DeleteCommand.swift in Sources */, 849A97541ED9EAC0007D329B /* AddWebFeedWindowController.swift in Sources */, diff --git a/Shared/UniformTypeIdentifiers+Extras.swift b/Shared/UniformTypeIdentifiers+Extras.swift new file mode 100644 index 000000000..4efadc760 --- /dev/null +++ b/Shared/UniformTypeIdentifiers+Extras.swift @@ -0,0 +1,14 @@ +// +// UniformTypeIdentifiers+Extras.swift +// NetNewsWire +// +// Created by Brent Simmons on 11/3/24. +// Copyright © 2024 Ranchero Software. All rights reserved. +// + +import UniformTypeIdentifiers + +extension UTType { + + static let opml = UTType("public.opml")! +} diff --git a/iOS/Article/WebViewController.swift b/iOS/Article/WebViewController.swift index a1224df60..84dd1a778 100644 --- a/iOS/Article/WebViewController.swift +++ b/iOS/Article/WebViewController.swift @@ -7,7 +7,7 @@ // import UIKit -import WebKit +@preconcurrency import WebKit import RSCore import Account import Articles diff --git a/iOS/Settings/ArticleThemesTableViewController.swift b/iOS/Settings/ArticleThemesTableViewController.swift index b7793d5c4..2143ab86d 100644 --- a/iOS/Settings/ArticleThemesTableViewController.swift +++ b/iOS/Settings/ArticleThemesTableViewController.swift @@ -7,9 +7,13 @@ // import Foundation - +import UniformTypeIdentifiers import UIKit +extension UTType { + static var netNewsWireTheme: UTType { UTType(importedAs: "com.ranchero.netnewswire.theme") } +} + class ArticleThemesTableViewController: UITableViewController { override func viewDidLoad() { @@ -27,7 +31,7 @@ class ArticleThemesTableViewController: UITableViewController { } @objc func importTheme(_ sender: Any?) { - let docPicker = UIDocumentPickerViewController(documentTypes: ["com.ranchero.netnewswire.theme"], in: .import) + let docPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.netNewsWireTheme]) docPicker.delegate = self docPicker.modalPresentationStyle = .formSheet self.present(docPicker, animated: true) diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift index eb70e5604..68b5f9b79 100644 --- a/iOS/Settings/SettingsViewController.swift +++ b/iOS/Settings/SettingsViewController.swift @@ -11,6 +11,7 @@ import Account import CoreServices import SafariServices import SwiftUI +import UniformTypeIdentifiers class SettingsViewController: UITableViewController { @@ -403,16 +404,7 @@ private extension SettingsViewController { func importOPMLDocumentPicker() { - let utiArray = UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, "opml" as NSString, nil)?.takeRetainedValue() as? [String] ?? [String]() - - var opmlUTIs = utiArray - .compactMap({ UTTypeCopyDeclaration($0 as NSString)?.takeUnretainedValue() as? [String: Any] }) - .reduce([String]()) { (result, dict) in - return result + dict.values.compactMap({ $0 as? String }) - } - opmlUTIs.append("public.xml") - - let docPicker = UIDocumentPickerViewController(documentTypes: opmlUTIs, in: .import) + let docPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.opml, UTType.xml], asCopy: true) docPicker.delegate = self docPicker.modalPresentationStyle = .formSheet self.present(docPicker, animated: true)