기능 구현 #1
OpenAiKit
OpenAIKit
| APIKey 생성
간단한 회원가입을 하고, 'View API Keys'를 선택한다.
화면에 표시되는 'Create new secret key' 버튼을 눌러 API Key를 생성하면 되는데,
이후 표시되는 안내창에 적혀있듯 확인창을 닫으면 Key는 더 이상 확인 할 수 있는 방법이 없다.
따라서 닫기 전에 복사 할 수 있도록 하고, 메모장 등에 적어 놓도록 하자.
OpenAiKit
| Import
Swift Package Manager를 사용해 Package를 추가한다.
Git에 적혀있는 Url을 그대로 우측 상단의 검색창에 붙여 넣으면 된다.
정상적으로 프로젝트에 추가 됐다면 Package Dependencies에 OpenAIKit이 표시된다.
OpenAiKit
| Initializing
import OpenAIKit
import SwiftUI
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
}
OpenAiKit을 import하고 initializing을 진행한다.
해당 과정에서 organization과 apiKey가 필요한데 이 둘은 OpenAI 홈페이지에서 생성한 데이터를 문자열로 전달한다.
OpenAiKit
| generateImage
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
func generateImage(prompt: String) async -> UIImage? {
guard let openai = openai else {
return nil
}
}
}
키워드를 입력 받아 이미지를 생성하는 generateImage 메서드를 구현한다.
입력 파라미터는 키워드에 해당하는 문자열이고, 반환 값은 optional UIImage 데이터다.
메서드가 동작 하기에 앞서 OpenAI가 제대로 초기화 됐는지 확인한다.
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
func generateImage(prompt: String) async -> UIImage? {
guard let openai = openai else {
return nil
}
do {
} catch {
print(String(describing: error))
return nil
}
}
}
앱 내에서 진행되는 것이 아닌 OpenAI의 서버와 통신을 하는 형태로 작업이 진행되기 때문에
async를 사용했고, 이에 따른 오류에 대응할 수 있도록 do-catch 패턴을 사용한다.
만약 작업이 제대로 진행되지 않는다면, 콘솔에 에러를 출력하고 nil을 반환한다.
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
func generateImage(prompt: String) async -> UIImage? {
guard let openai = openai else {
return nil
}
do {
let params = ImageParameters(prompt: prompt, resolution: .medium, responseFormat: .base64Json)
} catch {
print(String(describing: error))
return nil
}
}
}
전달 받은 문자열을 사용해 ImageParameters 객체를 생성한다.
사용한 파라미터는 아래와 같다.
- prompt
키워드에 해당하는 문자열이다. - resolution
생성할 이미지의 크기를 설정한다.
small, medium, large 중 medium을 사용했다. - responseFormat
반환받을 데이터의 형식을 지정한다.
url과 base64 중 하나를 선택할 수 있다.
Sample 코드와 같이 base64를 사용했다.
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
func generateImage(prompt: String) async -> UIImage? {
guard let openai = openai else {
return nil
}
do {
let params = ImageParameters(prompt: prompt, resolution: .medium, responseFormat: .base64Json)
let result = try await openai.createImage(parameters: params)
} catch {
print(String(describing: error))
return nil
}
}
}
결과는 초기화 된 openai의 createImage 메서드에 ImageParameters 객체를 전달해 반환받는다.
이미지 생성은 상대적으로 오래 걸리는 작업이기에 비동기 처리의 async를 위한 aswait가 여기서 등장한다.
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
func generateImage(prompt: String) async -> UIImage? {
guard let openai = openai else {
return nil
}
do {
let params = ImageParameters(prompt: prompt, resolution: .medium, responseFormat: .base64Json)
let result = try await openai.createImage(parameters: params)
let data = result.data[0].image
} catch {
print(String(describing: error))
return nil
}
}
}
반환받은 결과를 image로 분리하고,
final class ViewModel: ObservableObject {
private var openai: OpenAI?
func setup() {
openai = OpenAI(Configuration(organization: "[organization]", apiKey: "[apiKey]"))
}
func generateImage(prompt: String) async -> UIImage? {
guard let openai = openai else {
return nil
}
do {
let params = ImageParameters(prompt: prompt, resolution: .medium, responseFormat: .base64Json)
let result = try await openai.createImage(parameters: params)
let data = result.data[0].image
let image = try openai.decodeBase64Image(data)
return image
} catch {
print(String(describing: error))
return nil
}
}
}
분리된 이미지는 base64로 encoding 돼 있기 때문에 다시 decoding을 진행해 이를 반환한다.
'프로젝트 > Image Generator (w∕OpenAI)' 카테고리의 다른 글
05. 인터페이스 디자인 #2 (0) | 2022.12.28 |
---|---|
04. 기능구현 #3 (0) | 2022.12.28 |
03. 기능구현 #2 (0) | 2022.12.27 |
01. 인터페이스 디자인 #1 (0) | 2022.12.24 |
00. 시작하며 (0) | 2022.12.23 |