From 499a6658d3a3d6a432af30ade21805c0373e3028 Mon Sep 17 00:00:00 2001 From: qrutyy Date: Sun, 10 Aug 2025 16:06:52 +0300 Subject: [PATCH] feat: cached svg view for url --- Source/Model/Nodes/SVGCacheModel.swift | 33 +++++++++++++++++ Source/Parser/SVG/SVGCachedView.swift | 49 ++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 Source/Model/Nodes/SVGCacheModel.swift create mode 100644 Source/Parser/SVG/SVGCachedView.swift diff --git a/Source/Model/Nodes/SVGCacheModel.swift b/Source/Model/Nodes/SVGCacheModel.swift new file mode 100644 index 0000000..67a149b --- /dev/null +++ b/Source/Model/Nodes/SVGCacheModel.swift @@ -0,0 +1,33 @@ +// +// SVGCacheModel.swift +// SVGView +// +// Created by Michael Gavrilenko on 10.08.2025. +// + +import Foundation + +final class SVGCache { + static let shared = SVGCache() + + private let cache = NSCache() + + private init() {} + + func getNode(for url: URL) -> SVGNode? { + let key = url as NSURL + + if let cachedNode = cache.object(forKey: key) { + return cachedNode + } + + print("SVGCache: Parsing and caching new node for \(url.lastPathComponent)") + guard let newNode = SVGParser.parse(contentsOf: url) else { + return nil + } + + cache.setObject(newNode, forKey: key) + + return newNode + } +} diff --git a/Source/Parser/SVG/SVGCachedView.swift b/Source/Parser/SVG/SVGCachedView.swift new file mode 100644 index 0000000..cf139ea --- /dev/null +++ b/Source/Parser/SVG/SVGCachedView.swift @@ -0,0 +1,49 @@ +// +// SVGCachedView.swift +// SVGView +// +// Created by Michael Gavrilenko on 10.08.2025. +// + +import SwiftUI + +public struct CachedSVGView: View { + public let svg: SVGNode? + + public init(contentsOf url: URL) { + svg = SVGCache.shared.getNode(for: url) + } + + @available(*, deprecated, message: "Use (contentsOf:) initializer instead") + public init(fileURL: URL) { + svg = SVGCache.shared.getNode(for: fileURL) + } + + public init(data: Data) { + svg = SVGParser.parse(data: data) + } + + public init(string: String) { + svg = SVGParser.parse(string: string) + } + + public init(stream: InputStream) { + svg = SVGParser.parse(stream: stream) + } + + public init(xml: XMLElement) { + svg = SVGParser.parse(xml: xml) + } + + public init(svg: SVGNode) { + self.svg = svg + } + + public func getNode(byId id: String) -> SVGNode? { + svg?.getNode(byId: id) + } + + public var body: some View { + svg?.toSwiftUI() + } +}