🍜
iOSアプリにサッとChatGPTを組み込んで試す(Swift)
前段
2023年はアプリにAIを組み込む企画が走りそうな気配があります。
まずは企画メンバーに触ってもらって理解を深めてもらいたいということで、ライブラリを組み合わせた簡易版をサッと作ってみました。
(だいたい2時間程度で作れました)
手順
環境: Xcode14.3 / iOS16.4.1
1. ChatGPTのAPI Keyをゲットする
OpenAIのページでAPI keyを作成します。
(API利用にはクレジットカード登録&利用に応じた料金が発生するので注意※2023年5月18日時点)
2. Swift Package Manager でライブラリを組み込む
利用するのは以下の2つ
-
OpenAISwift
- OpenAI APIのラッパーライブラリ
- クライアントから直接OpenAIのAPIを利用できるものです。今回はデモアプリなので使用していますが、プロダクションとして提供するアプリではバックエンドを介してAPIを利用する方が望ましいです。
- OpenAI APIのラッパーライブラリ
-
MessageKit
- チャットUIのライブラリ
3. 画面を作る
-
MessageKit
のMessagesViewController
を継承したUIViewControllerを作ります
import MessageKit
class ChatViewController: MessagesViewController {
...
}
- protocol
MessageType
とSenderType
の型を定義する
struct MyAppSender: SenderType {
var senderId: String
var displayName: String
}
struct MyAppMessage: MessageType {
var sender: MessageKit.SenderType
var messageId: String
var sentDate: Date
var kind: MessageKit.MessageKind
}
-
MessagesDataSource
MessagesLayoutDelegate
を実装する
class ChatViewController: MessagesViewController {
private var messages = [MyAppMessage]()
override func viewDidLoad() {
super.viewDidLoad()
messagesCollectionView.messagesDataSource = self
messagesCollectionView.messagesLayoutDelegate = self
DispatchQueue.main.async {
self.messagesCollectionView.reloadData()
self.messagesCollectionView.scrollToLastItem(animated: false)
}
}
}
extension ChatViewController: MessagesDataSource {
var currentSender: MessageKit.SenderType {
MyAppSender(senderId: "you", displayName: "あなた")
}
func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessageKit.MessagesCollectionView) -> MessageKit.MessageType {
// チャットの吹き出しがrowでなくsectionで表現されることに注意
messages[indexPath.section]
}
func numberOfSections(in messagesCollectionView: MessageKit.MessagesCollectionView) -> Int {
messages.count
}
}
(レイアウトは特にこだわりがなかったので MessageKit
のexampleをそのまま使っています)
extension ChatViewController: MessagesLayoutDelegate {
func cellTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView)
-> CGFloat {
18
}
func cellBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
17
}
func messageTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
20
}
func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
16
}
}
4. 送信処理とメッセージ表示を実装する
-
送信ボタンタップ
MessagesViewController
のプロパティmessageInputBar.sendButton
が送信ボタンです。UIButtonを継承しているのでお好きなイベントハンドリングを実装してください。 -
ChatGPTへの質問送信処理を実装
チャット形式で回答を得るには↓
import OpenAISwift
let openAI = OpenAISwift(authToken: "XXXX") // API Key
openAI.sendChat(
with: [ChatMessage(role: .user, content: text)],
completionHandler: { result in
switch result {
case let .success(messageResult):
print(messageResult)
case let .failure(error):
print(error)
}
}
)
※API Keyはgit管理に含めないほうが賢明です
- 質問文とレスポンスを
MyAppMessage
に変換し、配列に追加した後messagesCollectionView.reloadData()
を実行する
その他
チャットUIの細かいところは MessageKit
の Example が参考になります。
- テキスト入力フォームのプレースホルダ文言を変えたい
messageInputBar.inputTextView.placeholder
- 送信ボタンのタイトルを変えたい
messageInputBar.sendButton.title
- メッセージにアイコンなどのアバターを表示したい
-
MessagesDisplayDelegate
↓を実装
-
extension ChatViewController: MessagesDisplayDelegate {
func configureAvatarView(_ avatarView: AvatarView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) {
avatarView.set(avatar: Avatar(image: UIImage(systemName: "face.smiling")))
}
}
Discussion