Skip to content

Commit 04703e4

Browse files
author
Guilherme Souza
authored
Implement StorageHTTPClient and remove non-concurrency method versions (#6)
* Refactor to async/await and add HTTP Client * Remove type declaration for Bucket and FileObject * Rename FileObject properties to camel case * Make Default http client public
1 parent ebb1ee7 commit 04703e4

File tree

10 files changed

+279
-395
lines changed

10 files changed

+279
-395
lines changed

Package.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1-
// swift-tools-version:5.3
1+
// swift-tools-version:5.5
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "SupabaseStorage",
8+
platforms: [
9+
.iOS(.v13),
10+
.macCatalyst(.v13),
11+
.macOS(.v10_15),
12+
.watchOS(.v6),
13+
.tvOS(.v13),
14+
],
815
products: [
916
.library(
1017
name: "SupabaseStorage",
1118
targets: ["SupabaseStorage"]
12-
)
19+
),
1320
],
1421
dependencies: [],
1522
targets: [

Sources/SupabaseStorage/Bucket.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ public struct Bucket {
77
public var updatedAt: String
88

99
init?(from dictionary: [String: Any]) {
10-
guard let id: String = dictionary["id"] as? String,
11-
let name: String = dictionary["name"] as? String,
12-
let owner: String = dictionary["owner"] as? String,
13-
let createdAt: String = dictionary["created_at"] as? String,
14-
let updatedAt: String = dictionary["updated_at"] as? String,
15-
let isPublic: Bool = dictionary["public"] as? Bool
10+
guard
11+
let id = dictionary["id"] as? String,
12+
let name = dictionary["name"] as? String,
13+
let owner = dictionary["owner"] as? String,
14+
let createdAt = dictionary["created_at"] as? String,
15+
let updatedAt = dictionary["updated_at"] as? String,
16+
let isPublic = dictionary["public"] as? Bool
1617
else {
1718
return nil
1819
}

Sources/SupabaseStorage/FileObject.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ public struct FileObject {
33
public var bucket_id: String
44
public var owner: String
55
public var id: String
6-
public var updated_at: String
7-
public var created_at: String
8-
public var last_accessed_at: String
6+
public var updatedAt: String
7+
public var createdAt: String
8+
public var lastAccessedAt: String
99
public var metadata: [String: Any]
1010
public var buckets: Bucket?
1111

1212
public init?(from dictionary: [String: Any]) {
13-
guard let name: String = dictionary["name"] as? String,
14-
let bucket_id: String = dictionary["bucket_id"] as? String,
15-
let owner: String = dictionary["owner"] as? String,
16-
let id: String = dictionary["id"] as? String,
17-
let updated_at: String = dictionary["updated_at"] as? String,
18-
let created_at: String = dictionary["created_at"] as? String,
19-
let last_accessed_at: String = dictionary["last_accessed_at"] as? String,
20-
let metadata: [String: Any] = dictionary["metadata"] as? [String: Any],
21-
let buckets: [String: Any] = dictionary["buckets"] as? [String: Any]
22-
13+
guard
14+
let name = dictionary["name"] as? String,
15+
let bucket_id = dictionary["bucket_id"] as? String,
16+
let owner = dictionary["owner"] as? String,
17+
let id = dictionary["id"] as? String,
18+
let updatedAt = dictionary["updated_at"] as? String,
19+
let createdAt = dictionary["created_at"] as? String,
20+
let lastAccessedAt = dictionary["last_accessed_at"] as? String,
21+
let metadata = dictionary["metadata"] as? [String: Any],
22+
let buckets = dictionary["buckets"] as? [String: Any]
2323
else {
2424
return nil
2525
}
@@ -28,9 +28,9 @@ public struct FileObject {
2828
self.bucket_id = bucket_id
2929
self.owner = owner
3030
self.id = id
31-
self.updated_at = updated_at
32-
self.created_at = created_at
33-
self.last_accessed_at = last_accessed_at
31+
self.updatedAt = updatedAt
32+
self.createdAt = createdAt
33+
self.lastAccessedAt = lastAccessedAt
3434
self.metadata = metadata
3535
self.buckets = Bucket(from: buckets)
3636
}

Sources/SupabaseStorage/StorageApi.swift

Lines changed: 41 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import Foundation
77
public class StorageApi {
88
var url: String
99
var headers: [String: String]
10+
var http: StorageHTTPClient
1011

11-
init(url: String, headers: [String: String]) {
12+
init(url: String, headers: [String: String], http: StorageHTTPClient) {
1213
self.url = url
1314
self.headers = headers
15+
self.http = http
1416
// self.headers.merge(["Content-Type": "application/json"]) { $1 }
1517
}
1618

@@ -28,10 +30,11 @@ public class StorageApi {
2830

2931
@discardableResult
3032
internal func fetch(
31-
url: URL, method: HTTPMethod = .get, parameters: [String: Any]?,
32-
headers: [String: String]? = nil, jsonSerialization _: Bool = true,
33-
completion: @escaping (Result<Any, Error>) -> Void
34-
) -> URLSessionDataTask? {
33+
url: URL,
34+
method: HTTPMethod = .get,
35+
parameters: [String: Any]?,
36+
headers: [String: String]? = nil
37+
) async throws -> Any {
3538
var request = URLRequest(url: url)
3639
request.httpMethod = method.rawValue
3740

@@ -43,53 +46,31 @@ public class StorageApi {
4346
}
4447

4548
if let parameters = parameters {
46-
do {
47-
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
48-
} catch {
49-
completion(.failure(error))
50-
return nil
51-
}
49+
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
5250
}
5351

54-
let session = URLSession.shared
55-
let dataTask: URLSessionDataTask = session.dataTask(
56-
with: request,
57-
completionHandler: { (data, response, error) -> Void in
58-
if let error = error {
59-
completion(.failure(error))
60-
return
61-
}
62-
63-
if let resp = response as? HTTPURLResponse {
64-
if let data = data, let mimeType = response?.mimeType {
65-
do {
66-
switch mimeType {
67-
case "application/json":
68-
let json = try JSONSerialization.jsonObject(with: data, options: [])
69-
completion(.success(try self.parse(response: json, statusCode: resp.statusCode)))
70-
default:
71-
completion(.success(try self.parse(response: data, statusCode: resp.statusCode)))
72-
}
73-
} catch {
74-
completion(.failure(error))
75-
return
76-
}
77-
}
78-
} else {
79-
completion(.failure(StorageError(message: "failed to get response")))
80-
}
81-
82-
})
83-
84-
dataTask.resume()
85-
return dataTask
52+
let (data, response) = try await http.fetch(request)
53+
if let mimeType = response.mimeType {
54+
switch mimeType {
55+
case "application/json":
56+
let json = try JSONSerialization.jsonObject(with: data, options: [])
57+
return try parse(response: json, statusCode: response.statusCode)
58+
default:
59+
return try parse(response: data, statusCode: response.statusCode)
60+
}
61+
} else {
62+
throw StorageError(message: "failed to get response")
63+
}
8664
}
8765

8866
internal func fetch(
89-
url: URL, method: HTTPMethod = .post, formData: FormData, headers: [String: String]? = nil,
90-
fileOptions: FileOptions? = nil, jsonSerialization: Bool = true,
91-
completion: @escaping (Result<Any, Error>) -> Void
92-
) {
67+
url: URL,
68+
method: HTTPMethod = .post,
69+
formData: FormData,
70+
headers: [String: String]? = nil,
71+
fileOptions: FileOptions? = nil,
72+
jsonSerialization: Bool = true
73+
) async throws -> Any {
9374
var request = URLRequest(url: url)
9475
request.httpMethod = method.rawValue
9576

@@ -108,43 +89,22 @@ public class StorageApi {
10889

10990
request.setValue(formData.contentType, forHTTPHeaderField: "Content-Type")
11091

111-
let session = URLSession.shared
112-
let dataTask = session.uploadTask(
113-
with: request, from: formData.data,
114-
completionHandler: { (data, response, error) -> Void in
115-
if let error = error {
116-
completion(.failure(error))
117-
return
118-
}
119-
120-
if let resp = response as? HTTPURLResponse {
121-
if let data = data {
122-
if jsonSerialization {
123-
do {
124-
let json = try JSONSerialization.jsonObject(with: data, options: [])
125-
completion(.success(try self.parse(response: json, statusCode: resp.statusCode)))
126-
} catch {
127-
completion(.failure(error))
128-
return
129-
}
130-
} else {
131-
if let dataString = String(data: data, encoding: .utf8) {
132-
completion(.success(dataString))
133-
return
134-
}
135-
}
136-
}
137-
} else {
138-
completion(.failure(StorageError(message: "failed to get response")))
139-
}
140-
141-
})
142-
143-
dataTask.resume()
92+
let (data, response) = try await http.upload(request, from: formData.data)
93+
94+
if jsonSerialization {
95+
let json = try JSONSerialization.jsonObject(with: data, options: [])
96+
return try parse(response: json, statusCode: response.statusCode)
97+
}
98+
99+
if let dataString = String(data: data, encoding: .utf8) {
100+
return dataString
101+
}
102+
103+
throw StorageError(message: "failed to get response")
144104
}
145105

146106
private func parse(response: Any, statusCode: Int) throws -> Any {
147-
if statusCode == 200 || 200..<300 ~= statusCode {
107+
if statusCode == 200 || 200 ..< 300 ~= statusCode {
148108
return response
149109
} else if let dict = response as? [String: Any], let error = dict["error"] as? String {
150110
throw StorageError(statusCode: statusCode, message: error)

0 commit comments

Comments
 (0)