From fb2007a3aca7a4e1856bd0abe6e78f4a53a5d006 Mon Sep 17 00:00:00 2001 From: kPherox Date: Sat, 4 Apr 2026 18:31:59 +0900 Subject: [PATCH] feat(JSONLD): add URLSession implementation --- .../Core/URLSessionDocumentLoader.swift | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Sources/JSONLD/Core/URLSessionDocumentLoader.swift diff --git a/Sources/JSONLD/Core/URLSessionDocumentLoader.swift b/Sources/JSONLD/Core/URLSessionDocumentLoader.swift new file mode 100644 index 0000000..3bbab2e --- /dev/null +++ b/Sources/JSONLD/Core/URLSessionDocumentLoader.swift @@ -0,0 +1,63 @@ +// Copyright 2026 kPherox +// SPDX-License-Identifier: Apache-2.0 + +#if canImport(FoundationNetworking) +import Foundation +public import class FoundationNetworking.URLSession +public import class FoundationNetworking.HTTPURLResponse +public import struct FoundationNetworking.URLRequest +#else +public import Foundation +#endif + +/// A reference document loader backed by `URLSession`. +/// +/// This loader is opt-in. Assign an instance to `JSONLDProcessor.loader` to enable +/// remote document loading with Swift Concurrency. +public struct URLSessionDocumentLoader: JSONLDDocumentLoader { + /// The session used to perform network requests. + public let session: URLSession + + /// Creates a URLSession-backed document loader. + public init(session: URLSession = .shared) { + self.session = session + } + + /// Loads a remote JSON-LD document from the specified URL. + public func load( + url: String, + requestProfile: String? + ) async -> Result { + guard let requestURL = URL(string: url) else { + return .failure(URLError(.badURL)) + } + + do { + var request = URLRequest(url: requestURL) + if let requestProfile { + request.setValue( + #"application/ld+json;profile="\#(requestProfile)", application/ld+json, application/json"#, + forHTTPHeaderField: "Accept" + ) + } + + let (data, response) = try await self.session.data(for: request) + + let httpResponse = response as? HTTPURLResponse + let responseURL = httpResponse?.url ?? response.url ?? requestURL + let contentType = httpResponse?.value(forHTTPHeaderField: "Content-Type") + let linkHeader = httpResponse?.value(forHTTPHeaderField: "Link") + + return .success( + RemoteDocumentResponse( + documentURL: responseURL.absoluteString, + body: data, + contentType: contentType, + linkHeaders: linkHeader + ) + ) + } catch { + return .failure(error) + } + } +}