Skip to content

Commit c3d812b

Browse files
authored
Add support for getting public URL for asset (#11)
* Add support for getting public URL for asset * Refactor implementation to use URLComponents
1 parent 6203cb0 commit c3d812b

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

Sources/SupabaseStorage/StorageFileApi.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,35 @@ public class StorageFileApi: StorageApi {
198198
}
199199
return data
200200
}
201+
202+
/// Returns a public url for an asset.
203+
/// - Parameters:
204+
/// - path: The file path to the asset. For example `folder/image.png`.
205+
/// - download: Whether the asset should be downloaded.
206+
/// - fileName: If specified, the file name for the asset that is downloaded.
207+
/// - options: Transform the asset before retrieving it on the client.
208+
public func getPublicUrl(
209+
path: String,
210+
download: Bool = false,
211+
fileName: String = "",
212+
options: TransformOptions? = nil
213+
) throws -> URL {
214+
guard var components = URLComponents(string: url) else {
215+
throw StorageError(message: "badURL")
216+
}
217+
218+
let renderPath = options != nil ? "render/image" : "object"
219+
220+
let downloadQueryItem = download ? [URLQueryItem(name: "download", value: fileName)] : []
221+
let optionsQueryItems = options?.queryItems ?? []
222+
223+
components.path = "/\(renderPath)/public/\(path)"
224+
components.queryItems = downloadQueryItem + optionsQueryItems
225+
226+
guard let generatedUrl = components.url else {
227+
throw StorageError(message: "badUrl")
228+
}
229+
230+
return generatedUrl
231+
}
201232
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import Foundation
2+
3+
public struct TransformOptions {
4+
public var width: Int?
5+
public var height: Int?
6+
public var resize: String?
7+
public var quality: Int?
8+
public var format: String?
9+
10+
public init(
11+
width: Int? = nil,
12+
height: Int? = nil,
13+
resize: String? = "cover",
14+
quality: Int? = 80,
15+
format: String? = "origin"
16+
) {
17+
self.width = width
18+
self.height = height
19+
self.resize = resize
20+
self.quality = quality
21+
self.format = format
22+
}
23+
24+
var queryItems: [URLQueryItem] {
25+
var items = [URLQueryItem]()
26+
27+
if let width = width {
28+
items.append(URLQueryItem(name: "width", value: String(width)))
29+
}
30+
31+
if let height = height {
32+
items.append(URLQueryItem(name: "height", value: String(height)))
33+
}
34+
35+
if let resize = resize {
36+
items.append(URLQueryItem(name: "resize", value: resize))
37+
}
38+
39+
if let quality = quality {
40+
items.append(URLQueryItem(name: "quality", value: String(quality)))
41+
}
42+
43+
if let format = format {
44+
items.append(URLQueryItem(name: "format", value: format))
45+
}
46+
47+
return items
48+
}
49+
}

Tests/SupabaseStorageTests/SupabaseStorageTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,20 @@ final class SupabaseStorageTests: XCTestCase {
6767
let objects = try await storage.from(id: "public").list()
6868
XCTAssertEqual(objects.count, 4)
6969
}
70+
71+
func testGetPublicUrl() throws {
72+
let path = "README.md"
73+
74+
let baseUrl = try storage.from(id: bucket).getPublicUrl(path: path)
75+
XCTAssertEqual(baseUrl.absoluteString, "\(Self.supabaseURL)/object/public/\(path)?")
76+
77+
let baseUrlWithDownload = try storage.from(id: bucket).getPublicUrl(path: path, download: true)
78+
XCTAssertEqual(baseUrlWithDownload.absoluteString, "\(Self.supabaseURL)/object/public/\(path)?download=")
79+
80+
let baseUrlWithDownloadAndFileName = try storage.from(id: bucket).getPublicUrl(path: path, download: true, fileName: "test")
81+
XCTAssertEqual(baseUrlWithDownloadAndFileName.absoluteString, "\(Self.supabaseURL)/object/public/\(path)?download=test")
82+
83+
let baseUrlWithAllOptions = try storage.from(id: bucket).getPublicUrl(path: path, download: true, fileName: "test", options: TransformOptions(width: 300, height: 300))
84+
XCTAssertEqual(baseUrlWithAllOptions.absoluteString, "\(Self.supabaseURL)/render/image/public/\(path)?download=test&width=300&height=300&resize=cover&quality=80&format=origin")
85+
}
7086
}

0 commit comments

Comments
 (0)