Skip to content

Commit cb5658d

Browse files
committed
updated loader
1 parent bb4c3e0 commit cb5658d

File tree

2 files changed

+61
-28
lines changed

2 files changed

+61
-28
lines changed

Sources/openai-async-image-swiftui/enum/AsyncImageErrors.swift

+18-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import Foundation
99

10-
/// Enumeration representing the various errors that can occur in `OpenAIAsyncImage`
1110
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
1211
enum AsyncImageErrors: Error, Equatable {
1312

@@ -20,4 +19,22 @@ enum AsyncImageErrors: Error, Equatable {
2019
/// Error indicating that the response returned no images
2120
case returnedNoImages
2221

22+
/// Status is not valid
23+
case httpStatus(String)
24+
}
25+
26+
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
27+
extension AsyncImageErrors: LocalizedError {
28+
public var errorDescription: String? {
29+
switch self {
30+
case .imageInit:
31+
return NSLocalizedString("Unable to create image from the provided data.", comment: "")
32+
case .clientIsNotDefined:
33+
return NSLocalizedString("Client not found. The URL might be invalid.", comment: "")
34+
case .returnedNoImages:
35+
return NSLocalizedString("The response did not contain any images.", comment: "")
36+
case .httpStatus(let data):
37+
return NSLocalizedString("HTTP status error: \(data).", comment: "")
38+
}
39+
}
2340
}

Sources/openai-async-image-swiftui/viewModel/OpenAIDefaultLoader.swift

+43-27
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,20 @@ import AppKit.NSImage
1717
#endif
1818

1919
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
20-
public final class OpenAIDefaultLoader : IOpenAILoader{
20+
public final class OpenAIDefaultLoader: IOpenAILoader {
2121

2222
/// HTTP async client to handle requests
23-
private let client : Http.Proxy<JsonReader, JsonWriter>?
23+
private let client: Http.Proxy<JsonReader, JsonWriter>?
2424

2525
/// Endpoint parameters required for making requests
26-
private let endpoint : IOpenAIImageEndpoint
26+
private let endpoint: IOpenAIImageEndpoint
2727

2828
/// Initializes the loader with endpoint parameters
2929
/// - Parameter endpoint: Set of parameters for making requests
30-
public init(endpoint : IOpenAIImageEndpoint) {
31-
30+
public init(endpoint: IOpenAIImageEndpoint) {
3231
self.endpoint = endpoint
3332

34-
guard let url = URL(string: endpoint.urlString) else{
33+
guard let url = URL(string: endpoint.urlString) else {
3534
client = nil
3635
return
3736
}
@@ -45,33 +44,52 @@ public final class OpenAIDefaultLoader : IOpenAILoader{
4544
/// - size: The size of the generated image
4645
/// - Returns: OpenAI Image
4746
public func load(
48-
_ prompt : String,
49-
with size : OpenAIImageSize
50-
) async throws -> Image{
51-
52-
// Prepare the request body with the prompt and size
53-
let body = Input(prompt: prompt, size: size, response_format: .b64, n: 1)
54-
55-
// Set the request headers, including authorization
56-
let headers = ["Content-Type": "application/json","Authorization": "Bearer \(endpoint.apiKey)"]
57-
let path = endpoint.path
47+
_ prompt: String,
48+
with size: OpenAIImageSize
49+
) async throws -> Image {
5850

59-
guard let client = client else{
51+
guard let client = client else {
6052
throw AsyncImageErrors.clientIsNotDefined
6153
}
6254

63-
// Send the request and get the response
64-
let result: Http.Response<Output> = try await client.post(path: path, body: body, headers: headers)
55+
do {
56+
let (path, body, headers) = prepareRequest(prompt: prompt, size: size)
57+
let result: Http.Response<Output> = try await client.post(path: path, body: body, headers: headers)
58+
return try imageBase64(from: result.value)
59+
60+
} catch {
61+
try handleRequestError(error)
62+
}
63+
}
64+
65+
/// Prepares the request with the necessary parameters
66+
/// - Parameters:
67+
/// - prompt: The text prompt describing the desired image
68+
/// - size: The size of the generated image
69+
/// - Returns: A tuple containing the path, body, and headers for the request
70+
private func prepareRequest(prompt: String, size: OpenAIImageSize) -> (String, Input, [String: String]) {
71+
let body = Input(prompt: prompt, size: size, response_format: .b64, n: 1)
72+
let headers = ["Content-Type": "application/json", "Authorization": "Bearer \(endpoint.apiKey)"]
73+
let path = endpoint.path
74+
return (path, body, headers)
75+
}
76+
77+
/// Handles errors that occur during the request
78+
/// - Parameter error: The error that occurred
79+
private func handleRequestError(_ error: Error) throws -> Never {
80+
if case let Http.Errors.status(_, _, data) = error, let responseData = data {
81+
let data = String(data: responseData, encoding: .utf8) ?? "Unable to decode data"
82+
throw AsyncImageErrors.httpStatus(data)
83+
}
6584

66-
// Convert the response to an image
67-
return try imageBase64(from: result.value)
85+
throw error
6886
}
6987

7088
/// Decodes base64 encoded string to Data
7189
/// - Parameter output: The output received from the endpoint
7290
/// - Returns: Decoded Data
73-
private func decodeBase64(from output: Output) throws -> Data?{
74-
guard let base64 = output.firstImage else {
91+
private func decodeBase64(from output: Output) throws -> Data? {
92+
guard let base64 = output.firstImage else {
7593
throw AsyncImageErrors.returnedNoImages
7694
}
7795

@@ -83,10 +101,9 @@ public final class OpenAIDefaultLoader : IOpenAILoader{
83101
/// - Parameter output: OpenAI response type
84102
/// - Returns: UIImage
85103
private func imageBase64(from output: Output) throws -> Image {
86-
87104
let data = try decodeBase64(from: output)
88105

89-
if let data, let image = UIImage(data: data){
106+
if let data, let image = UIImage(data: data) {
90107
return Image(uiImage: image)
91108
}
92109

@@ -99,10 +116,9 @@ public final class OpenAIDefaultLoader : IOpenAILoader{
99116
/// - Parameter output: OpenAI response type
100117
/// - Returns: NSImage
101118
private func imageBase64(from output: Output) throws -> Image {
102-
103119
let data = try decodeBase64(from: output)
104120

105-
if let data, let image = NSImage(data: data){
121+
if let data, let image = NSImage(data: data) {
106122
return Image(nsImage: image)
107123
}
108124

0 commit comments

Comments
 (0)