mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Make Articles module adhere to strict Swift concurrency.
This commit is contained in:
@@ -2,22 +2,26 @@
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Articles",
|
||||
name: "Articles",
|
||||
platforms: [.macOS(.v14), .iOS(.v17)],
|
||||
products: [
|
||||
.library(
|
||||
name: "Articles",
|
||||
products: [
|
||||
.library(
|
||||
name: "Articles",
|
||||
type: .dynamic,
|
||||
targets: ["Articles"]),
|
||||
],
|
||||
dependencies: [
|
||||
targets: ["Articles"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMinor(from: "1.0.0")),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Articles",
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Articles",
|
||||
dependencies: [
|
||||
"RSCore"
|
||||
]),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ public struct Article: Hashable {
|
||||
}
|
||||
|
||||
public static func calculatedArticleID(feedID: String, uniqueID: String) -> String {
|
||||
return databaseIDWithString("\(feedID) \(uniqueID)")
|
||||
return DatabaseIDCache.shared.databaseIDWithString("\(feedID) \(uniqueID)")
|
||||
}
|
||||
|
||||
// MARK: - Hashable
|
||||
|
||||
@@ -33,7 +33,7 @@ public struct Author: Codable, Hashable {
|
||||
s += url ?? ""
|
||||
s += avatarURL ?? ""
|
||||
s += emailAddress ?? ""
|
||||
self.authorID = databaseIDWithString(s)
|
||||
self.authorID = DatabaseIDCache.shared.databaseIDWithString(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,23 +9,30 @@
|
||||
import Foundation
|
||||
import RSCore
|
||||
|
||||
// MD5 works because:
|
||||
// * It’s fast
|
||||
// * Collisions aren’t going to happen with feed data
|
||||
class DatabaseIDCache: @unchecked Sendable {
|
||||
|
||||
private var databaseIDCache = [String: String]()
|
||||
private var databaseIDCacheLock = NSLock()
|
||||
public func databaseIDWithString(_ s: String) -> String {
|
||||
databaseIDCacheLock.lock()
|
||||
defer {
|
||||
databaseIDCacheLock.unlock()
|
||||
}
|
||||
|
||||
if let identifier = databaseIDCache[s] {
|
||||
static let shared = DatabaseIDCache()
|
||||
|
||||
private var databaseIDCache = [String: String]()
|
||||
private let databaseIDCacheLock = NSLock()
|
||||
|
||||
/// Generates — or retrieves from cache — a database-suitable ID based on a String.
|
||||
func databaseIDWithString(_ s: String) -> String {
|
||||
|
||||
databaseIDCacheLock.lock()
|
||||
defer {
|
||||
databaseIDCacheLock.unlock()
|
||||
}
|
||||
|
||||
if let identifier = databaseIDCache[s] {
|
||||
return identifier
|
||||
}
|
||||
|
||||
// MD5 works because:
|
||||
// * It’s fast
|
||||
// * Collisions aren’t going to happen with feed data
|
||||
let identifier = s.md5String
|
||||
databaseIDCache[s] = identifier
|
||||
return identifier
|
||||
}
|
||||
|
||||
let identifier = s.md5String
|
||||
databaseIDCache[s] = identifier
|
||||
return identifier
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user