
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を使って
私が日本語で指示を書く
DeepLが英語に翻訳
ChatGPTがその英語を読んでプログラムを生成
コピペ
の流れを作り、何回か回してみました。
で、回しすぎた結果、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の調整と、カードのフォルダ分け、カード削除機能をつけていきたいですね。