LoginSignup
12
0

ChatGPTとGASを用いたiOSアプリを作成してみた。(Qiita × Fast DOCTOR Health Tech Hackathonの備忘録)

Posted at

「Qiita × Fast DOCTOR Health Tech Hackathon」に参加して、SwiftとGASでChatGPTを用いたiOSアプリを作成したのですが、ただ感想を書いてもつまらないので、
開発中に引っかかったポイント(SwiftとGASを用いたアプリ開発で気をつけたい点)と、作成したGASやChatGPTを用いたiOSアプリを作る上で、汎用性の高いSwiftの関数をご紹介します。

開発には、GASとXcodeを使用しました。

1. SwiftとGASを用いたアプリ開発で気をつけたい点

1.1. 文字の型に気をつける

swiftからGASにリクエストして、スプレッドシートなどを参照する際に、数字を扱う場合、swiftのリクエストは文字列型ですが、GASが取得してくる数字は数値型なので、GASがスプレッドシートなどから取得した値を文字列型に変換してからswiftのリクエストを処理する必要があります。

1.2. 日本語を扱う場合、エンコードとデコードが必要

swiftからGASに日本語を送って処理を行う場合、swiftで日本語をエンコードしてGASに送り、GASで受け取った日本語をデコードする必要があります。そうしないと空の文字列として処理されます。
GASからswiftに日本語を送る場合には、そのままで良いようです。

2. GASやChatGPTを用いたiOSアプリを作る上で、汎用性の高いswiftの関数

2.1. HTTP POSTリクエストを行う関数

以下の関数を用いる事で、HTTP POSTリクエストをiOSアプリから行えます。

struct HTTPRequest {
    static func post(url: String, params: [String: String], completion: @escaping (Data?, URLResponse?, Error?) -> Void) {
        guard let url = URL(string: url) else { return }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = params
            .map { key, value in "\(key)=\(value)" }
            .joined(separator: "&")
            .data(using: .utf8)

        URLSession.shared.dataTask(with: request, completionHandler: completion).resume()
    }
}

2.2. ChatGPTでテキスト生成する関数

以下の関数を用いる事で、swiftからOpenAI APIにリクエストを行いChatGPTでテキスト生成が出来ます。
この関数には、ChatGPTに記憶を持たせるアシストを組み込んでいませんが、リクエスト部分に含めることで実装可能です。

struct GPT3Message: Codable {
    let role: String
    let content: String
}

struct GPT3Payload: Codable {
    let model: String
    let messages: [GPT3Message]
}

func chatWithGPT3(apiKey: String, system: String, text: String) async throws -> String {
    let url = URL(string: "https://api.openai.com/v1/chat/completions")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    let systemMessage = GPT3Message(role: "system", content: system)
    let userMessage = GPT3Message(role: "user", content: text)
    let payload = GPT3Payload(model: "gpt-3.5-turbo", messages: [systemMessage, userMessage])
    
    do {
        let jsonData = try JSONEncoder().encode(payload)
        request.httpBody = jsonData
    } catch {
        print("Error: \(error)")
        throw error
    }
    
    let (data, response) = try await URLSession.shared.data(for: request)

    if let httpResponse = response as? HTTPURLResponse,
       httpResponse.statusCode != 200 {
        throw URLError(.badServerResponse)
    }
    
    do {
        let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
        if let jsonDict = jsonObject as? [String: Any],
           let choices = jsonDict["choices"] as? [[String: Any]],
           let firstChoice = choices.first,
           let message = firstChoice["message"] as? [String: Any],
           let content = message["content"] as? String {
            return content
        }
    } catch {
        print("Error: \(error)")
        throw error
    }

    return ""
}

最後に

Qiita × Fast DOCTOR Health Tech Hackathonはとても楽しいイベントでした。
良い人ばかりで、尚且つ、頭も良い方が集まっていたので、心地良かったです。都合が合えば、また参加させて頂きたいと思ってます。

12
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
0