見出し画像

ChatGPTで単語帳アプリを作ってみよう①

どうも、重めの記事を投げたけど、普段から割と考えてる案件なので病んでるわけではありませんと、それなニキです。

さて、ここ数か月の間、ChatGPTとBingAIをこき使って遊び散らかしていましたが、ある日、大学の先輩がAIを利用したアプリを制作していることを聞きました。

で、ふと思いました。AIを使うアプリはまだ作れなくても、AIを使ってアプリを作ることはできるのでは?

そしてあわよくば、完成したアプリを持って行って、その先輩がやってるベンチャーに入れてもらえるのでは()

というわけで、気分が向くままにやってみます。

AndroidとiOSどっちにするか

AndroidとiOSのどちら向けのアプリにしようか迷いましたが、GPTにそれぞれの開発方法を聞いてみたところ、Android開発環境を整える上でまさかのCPUの要件を満たせていないことが判明しました(私は第一世代core i7を使っている変人です。早くCPUアップグレードしたいけどお金が…)。

んなわけで、Appのリリースにかかるお金はめっちゃ高いですけど(年99ドルの会費がかかる)、iOS向けの開発を先にやってみることにしました。うちの大学生協PCはmacbookなので環境はバッチリです(東大の特権?)。

Xcodeの導入の流れは省略します。まあapp storeにあるのでダウンロードしてもろて…

なかなかBuildingが成功しない…

さあ、さっそくコードを書いてもらいましょう!!
というわけでGPTにコードを書いてもらいました。

私:I want to make an wordbook app with swift for iOS. I already have Xcode, so can you show me some example code?

import SwiftUI

struct ContentView: View {
    @State private var words: [String] = ["apple", "banana", "carrot"]
    @State private var newWord = ""
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(words, id: \.self) { word in
                        Text(word)
                    }
                    .onDelete(perform: removeWord)
                }
                
                HStack {
                    TextField("Add a new word", text: $newWord, onCommit: {
                        addWord()
                    })
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    
                    Button(action: addWord) {
                        Image(systemName: "plus")
                    }
                }
                .padding()
            }
            .navigationTitle("Wordbook")
            .navigationBarItems(trailing: EditButton())
        }
    }
    
    func addWord() {
        if !newWord.isEmpty {
            words.append(newWord)
            newWord = ""
        }
    }
    
    func removeWord(at offsets: IndexSet) {
        words.remove(atOffsets: offsets)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

早速コピペじゃー!
と、張り切って新規プロジェクトのコードにコピペしてみたのですが、struct content viewがダメだとかなんとか返ってくるばかり。Building Failedという表示も出て、うーん困った。

で、色々GPTに聞いてみたのですが、どうやらContent Viewにのみ貼り付ければ良かったみたいですね。Codeが書かれているファイル全てに片っ端からペーストするもんだと思い込んでました。恥ずかしい(´・ω・`)

ひとまずBuilding Successedと出たので一安心。

DeepL君と力を合わせて

ここから徐々にプログラムを変えてUIを調整していきます。
調整していくんですけど、どんなアプリにしたいか考える方に頭を使いたいのに、指示に使う英語を捻り出す方に結構労力が割かれてしまってこれがまあ大変。
英語は得意な方ではあると思うのですが、正直あまり好きでなはい…
しかし日本語で打ち込むとGPT側に日本語訳を行わせる分、書けるプログラム量に制限が出る可能性も…

というわけで、我々の世代が多分一番お世話になった翻訳ツールこと、DeepLを使って

  1. 私が日本語で指示を書く

  2. DeepLが英語に翻訳

  3. ChatGPTがその英語を読んでプログラムを生成

  4. コピペ

の流れを作り、何回か回してみました。

で、回しすぎた結果、GPTの「3時間につき25回以内で勘弁して」という制限に引っかかってしまいました()

今日の成果物がこちらです。

import SwiftUI

struct WordPair: Identifiable {
    let id = UUID()
    let word: String
    let translation: String
}

struct FlashcardView: View {
    let wordPair: WordPair
    @State private var isFlipped = false
    
    var body: some View {
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.white)
            .frame(maxWidth: .infinity, minHeight: 150)
            .padding(.horizontal)
            .shadow(radius: 5)
            .overlay(
                VStack {
                    if isFlipped {
                        Text(wordPair.translation)
                            .font(.title)
                            .padding()
                    } else {
                        Text(wordPair.word)
                            .font(.title)
                            .padding()
                    }
                }
            )
            .onTapGesture {
                withAnimation(.spring()) {
                    isFlipped.toggle()
                }
            }
    }
}

struct ContentView: View {
    @State private var wordPairs: [WordPair] = [
        WordPair(word: "apple", translation: "りんご"),
        WordPair(word: "banana", translation: "バナナ"),
        WordPair(word: "carrot", translation: "にんじん")
    ]
    @State private var newWord = ""
    @State private var newTranslation = ""
    
    var body: some View {
        NavigationView {
            VStack {
                ScrollView(showsIndicators: false) {
                    VStack(spacing: 20) {
                        ForEach(wordPairs) { wordPair in
                            FlashcardView(wordPair: wordPair)
                        }
                    }
                    .padding()
                }
                
                HStack {
                    TextField("Add a new word", text: $newWord)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                    
                    TextField("Add translation", text: $newTranslation)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                    
                    Button(action: addWordPair) {
                        Image(systemName: "plus")
                    }
                }
                .padding()
            }
            .navigationTitle("Wordbook")
        }
    }
    
    func addWordPair() {
        if !newWord.isEmpty && !newTranslation.isEmpty {
            wordPairs.append(WordPair(word: newWord, translation: newTranslation))
            newWord = ""
            newTranslation = ""
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
UIは今の所こんな感じ
単語追加機能と
それぞれをひっくり返して答えを見る機能がついています。

今後の方針と最終目標

最終的には、市販されている暗記アプリと同等の機能を実装できればと思っています。
できれば記憶曲線に基づく復習機能がつけられれば満足かな。
動画や画像を暗記カードとして登録できる機能もつけたいです。

次回以降はUIの調整と、カードのフォルダ分け、カード削除機能をつけていきたいですね。

いいなと思ったら応援しよう!