Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
// swift-tools-version:5.3
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "SupabaseStorage",
platforms: [
.iOS(.v13),
.macCatalyst(.v13),
.macOS(.v10_15),
.watchOS(.v6),
.tvOS(.v13),
],
products: [
.library(
name: "SupabaseStorage",
targets: ["SupabaseStorage"]
)
),
],
dependencies: [],
targets: [
Expand Down
13 changes: 7 additions & 6 deletions Sources/SupabaseStorage/Bucket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ public struct Bucket {
public var updatedAt: String

init?(from dictionary: [String: Any]) {
guard let id: String = dictionary["id"] as? String,
let name: String = dictionary["name"] as? String,
let owner: String = dictionary["owner"] as? String,
let createdAt: String = dictionary["created_at"] as? String,
let updatedAt: String = dictionary["updated_at"] as? String,
let isPublic: Bool = dictionary["public"] as? Bool
guard
let id = dictionary["id"] as? String,
let name = dictionary["name"] as? String,
let owner = dictionary["owner"] as? String,
let createdAt = dictionary["created_at"] as? String,
let updatedAt = dictionary["updated_at"] as? String,
let isPublic = dictionary["public"] as? Bool
else {
return nil
}
Expand Down
32 changes: 16 additions & 16 deletions Sources/SupabaseStorage/FileObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ public struct FileObject {
public var bucket_id: String
public var owner: String
public var id: String
public var updated_at: String
public var created_at: String
public var last_accessed_at: String
public var updatedAt: String
public var createdAt: String
public var lastAccessedAt: String
public var metadata: [String: Any]
public var buckets: Bucket?

public init?(from dictionary: [String: Any]) {
guard let name: String = dictionary["name"] as? String,
let bucket_id: String = dictionary["bucket_id"] as? String,
let owner: String = dictionary["owner"] as? String,
let id: String = dictionary["id"] as? String,
let updated_at: String = dictionary["updated_at"] as? String,
let created_at: String = dictionary["created_at"] as? String,
let last_accessed_at: String = dictionary["last_accessed_at"] as? String,
let metadata: [String: Any] = dictionary["metadata"] as? [String: Any],
let buckets: [String: Any] = dictionary["buckets"] as? [String: Any]

guard
let name = dictionary["name"] as? String,
let bucket_id = dictionary["bucket_id"] as? String,
let owner = dictionary["owner"] as? String,
let id = dictionary["id"] as? String,
let updatedAt = dictionary["updated_at"] as? String,
let createdAt = dictionary["created_at"] as? String,
let lastAccessedAt = dictionary["last_accessed_at"] as? String,
let metadata = dictionary["metadata"] as? [String: Any],
let buckets = dictionary["buckets"] as? [String: Any]
else {
return nil
}
Expand All @@ -28,9 +28,9 @@ public struct FileObject {
self.bucket_id = bucket_id
self.owner = owner
self.id = id
self.updated_at = updated_at
self.created_at = created_at
self.last_accessed_at = last_accessed_at
self.updatedAt = updatedAt
self.createdAt = createdAt
self.lastAccessedAt = lastAccessedAt
self.metadata = metadata
self.buckets = Bucket(from: buckets)
}
Expand Down
122 changes: 41 additions & 81 deletions Sources/SupabaseStorage/StorageApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import Foundation
public class StorageApi {
var url: String
var headers: [String: String]
var http: StorageHTTPClient

init(url: String, headers: [String: String]) {
init(url: String, headers: [String: String], http: StorageHTTPClient) {
self.url = url
self.headers = headers
self.http = http
// self.headers.merge(["Content-Type": "application/json"]) { $1 }
}

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

@discardableResult
internal func fetch(
url: URL, method: HTTPMethod = .get, parameters: [String: Any]?,
headers: [String: String]? = nil, jsonSerialization _: Bool = true,
completion: @escaping (Result<Any, Error>) -> Void
) -> URLSessionDataTask? {
url: URL,
method: HTTPMethod = .get,
parameters: [String: Any]?,
headers: [String: String]? = nil
) async throws -> Any {
var request = URLRequest(url: url)
request.httpMethod = method.rawValue

Expand All @@ -43,53 +46,31 @@ public class StorageApi {
}

if let parameters = parameters {
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
} catch {
completion(.failure(error))
return nil
}
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
}

let session = URLSession.shared
let dataTask: URLSessionDataTask = session.dataTask(
with: request,
completionHandler: { (data, response, error) -> Void in
if let error = error {
completion(.failure(error))
return
}

if let resp = response as? HTTPURLResponse {
if let data = data, let mimeType = response?.mimeType {
do {
switch mimeType {
case "application/json":
let json = try JSONSerialization.jsonObject(with: data, options: [])
completion(.success(try self.parse(response: json, statusCode: resp.statusCode)))
default:
completion(.success(try self.parse(response: data, statusCode: resp.statusCode)))
}
} catch {
completion(.failure(error))
return
}
}
} else {
completion(.failure(StorageError(message: "failed to get response")))
}

})

dataTask.resume()
return dataTask
let (data, response) = try await http.fetch(request)
if let mimeType = response.mimeType {
switch mimeType {
case "application/json":
let json = try JSONSerialization.jsonObject(with: data, options: [])
return try parse(response: json, statusCode: response.statusCode)
default:
return try parse(response: data, statusCode: response.statusCode)
}
} else {
throw StorageError(message: "failed to get response")
}
}

internal func fetch(
url: URL, method: HTTPMethod = .post, formData: FormData, headers: [String: String]? = nil,
fileOptions: FileOptions? = nil, jsonSerialization: Bool = true,
completion: @escaping (Result<Any, Error>) -> Void
) {
url: URL,
method: HTTPMethod = .post,
formData: FormData,
headers: [String: String]? = nil,
fileOptions: FileOptions? = nil,
jsonSerialization: Bool = true
) async throws -> Any {
var request = URLRequest(url: url)
request.httpMethod = method.rawValue

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

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

let session = URLSession.shared
let dataTask = session.uploadTask(
with: request, from: formData.data,
completionHandler: { (data, response, error) -> Void in
if let error = error {
completion(.failure(error))
return
}

if let resp = response as? HTTPURLResponse {
if let data = data {
if jsonSerialization {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
completion(.success(try self.parse(response: json, statusCode: resp.statusCode)))
} catch {
completion(.failure(error))
return
}
} else {
if let dataString = String(data: data, encoding: .utf8) {
completion(.success(dataString))
return
}
}
}
} else {
completion(.failure(StorageError(message: "failed to get response")))
}

})

dataTask.resume()
let (data, response) = try await http.upload(request, from: formData.data)

if jsonSerialization {
let json = try JSONSerialization.jsonObject(with: data, options: [])
return try parse(response: json, statusCode: response.statusCode)
}

if let dataString = String(data: data, encoding: .utf8) {
return dataString
}

throw StorageError(message: "failed to get response")
}

private func parse(response: Any, statusCode: Int) throws -> Any {
if statusCode == 200 || 200..<300 ~= statusCode {
if statusCode == 200 || 200 ..< 300 ~= statusCode {
return response
} else if let dict = response as? [String: Any], let error = dict["error"] as? String {
throw StorageError(statusCode: statusCode, message: error)
Expand Down
Loading