見出し画像

ChatGPTに教えてもらえばAIアプリだって作れる様になるはず‼︎ 5.Unit Converter #機械学習による人間学習

はじめに

このブログでは、ChatGPTで作成した「AIアプリを作れる様になるまでの100個のアプリ案」を実際に作り、学んだことや失敗したこと、感じたことを記していきます。

各記事のページ下部にはChatGPTによるStep by Stepガイドを貼付し、学習内容をトレース出来る様にしています。

プログラミング初心者の方や新しくスキルを身に付けようとしている方の参考になれば幸いです。

(※本ブログはマガジン「ChatGPTに教えてもらえばにまとめてあります。)


今回のアプリ "5.Unit Converter"

100mをkmに変換

概要 : 様々な単位(温度、長さなど)間の変換

m(メートル)からkm(キロメートル)への変換など単位変換をするアプリ。コードにより長さ以外にも重さなど様々な単位を変換出来ます。

狙い : ロジックの構成とユーザー入力の処理方法

ChatGPTに表示された内容のままですが、ちょっと分かりにくいですね。制作ステップが、変数の定義、Text( )などのUIの配置、ヘルパーの作成、単位変換ロジックの順番で書かれているので、これらの構成のことを指しているのでしょう。

ユーザー入力の処理方法は、Textfieldへのユーザー入力、Pickerでの単位選択、単位変換の実行ボタンなど数種類の入力方法が紹介されているので、そのことを指していると思います。

学習したこと

  • [UnitLength] = [.meters, .kilometers, .feet, .yards, .miles]

    • [ ](角カッコ)で配列を作ることが出来る。

  • switch unit {case: .meters return "Meters" 〜中略〜 default: return "Unknown"}

    • unitの値によって{ }内の処理がunitに対応するcaseの処理に変わる。例の場合、unitに.metersが格納されていれば"Meters"が返ってくる。

  • Measurement(value: value, unit: fromUnit)

    • valueに格納された値をunitの単位で格納する。今回はvalueに100、fromUnitに.metersが入っていれば、100mが格納される。

    • .converted(to: toUnit)

      • Measurement( )で格納された値は.converted( )で単位を変換できる。例えば、格納された値が100m、toUnit=.kilometersであれば、0.1kmに変換される。

感想

今回は、変換前後の単位を変数に格納しておいてボタンを押すことで、単位が変換される仕組みの単位変換アプリでした。単位変換のmodifierがあり、時間や重さなど様々な単位の変換が出来るというのは便利です。意外と単位変換って合っているか検索したりするので、機能を拡張して網羅的に単位変換出来るアプリは意外とニーズがあるかもと思いました。

アプリ制作の基本的なセクションは「変数の準備」、「ユーザーインターフェースの設置」、「funcの作成」に分けられるというのが、今回までに気付いた内容です。似た様なコードを繰り返し見ることで、変わらない基本的な部分と毎回変わる部分が分かってきたのかもしれません。基本の積み重ねを続けることで段々と理解が深まると思うので、継続して頑張っていきたいと思います。

この記事が参考になったという方は、スキ!やフォローを頂けると励みになります!

ChatGPTの回答


以下では、SwiftUI を使用して Xcode 上で単位変換アプリを構築する手順をステップバイステップで解説します。この例では長さの単位(メートル、キロメートル、マイルなど)の変換に焦点を当てていますが、同じアプローチを利用して温度や重量、体積など他のカテゴリーにも簡単に拡張できます。

1. 新しい Xcode プロジェクトを作成する

  1. Xcode を起動する

    • アプリケーションフォルダから Xcode を起動します。

  2. 新しいプロジェクトを作成する

    • 「Create a new Xcode project」(または File > New > Project…) を選択します。

  3. アプリのテンプレートを選択する

    • iOS のセクションで「App」を選択し、「Next」をクリックします。

  4. プロジェクトの詳細を設定する

    • Product Name: UnitConverter

    • Team: Apple Developer アカウントを選択、またはローカルテストの場合は “None”

    • Organization Identifier: 例: com.yourname

    • Interface: SwiftUI

    • Language: Swift

    • 「Next」をクリックし、プロジェクトを保存するフォルダを指定して「Create」をクリックします。

2. 対応する単位を決める

この例では長さの単位変換を扱います。Swift の Foundation には、多くの単位が組み込まれている UnitLength があり、以下のようなユニットが使用できます:
• .meters
• .kilometers
• .feet
• .yards
• .miles

必要に応じてさらに追加することも可能です。

3. SwiftUI レイアウトを実装する

ContentView.swift を開き、初期コードを以下のステップに沿って置き換えていきます。

Step 1: State と単位オプションを定義する

  1. State 変数

    • inputValue: ユーザーの数値入力を文字列として受け取るためのプロパティ

    • fromUnit と toUnit: 選択された変換元と変換先の単位を保存するためのプロパティ

    • convertedValue: 変換結果を保持するためのプロパティ

  2. 単位の配列

    • ピッカーに表示する長さの単位の配列を用意します。

import SwiftUI

struct ContentView: View {
    @State private var inputValue: String = ""
    @State private var fromUnit: UnitLength = .meters
    @State private var toUnit: UnitLength = .kilometers
    @State private var convertedValue: Double = 0.0

    let lengthUnits: [UnitLength] = [.meters, .kilometers, .feet, .yards, .miles]

Step 2: ユーザーインターフェースを構築する

VStack を使い要素を縦に配置します。
含める主な要素:

  • 数値を入力する TextField

  • 変換元と変換先の単位を選ぶ 2 つの Picker

  • 変換処理を実行するボタン

  • 結果を表示する Text

    var body: some View {
        VStack(spacing: 20) {
            Text("Unit Converter")
                .font(.largeTitle)
                .padding()

            // ユーザー入力
            TextField("Enter value", text: $inputValue)
                .keyboardType(.decimalPad)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            // 変換元ユニットのピッカー
            Text("From Unit")
                .font(.headline)
            Picker("From Unit", selection: $fromUnit) {
                ForEach(lengthUnits, id: \.self) { unit in
                    Text(displayName(for: unit))
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()

            // 変換先ユニットのピッカー
            Text("To Unit")
                .font(.headline)
            Picker("To Unit", selection: $toUnit) {
                ForEach(lengthUnits, id: \.self) { unit in
                    Text(displayName(for: unit))
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()

            // 変換ボタン
            Button(action: convertUnits) {
                Text("Convert")
                    .font(.headline)
                    .padding()
                    .frame(maxWidth: .infinity)
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
            .padding(.horizontal)

            // 結果表示
            Text("Converted Value: \(convertedValue, specifier: \"%.4f\")")
                .font(.title2)
                .padding()

            Spacer()
        }
        .padding()
    }

Step 3: 単位名を表示するためのヘルパーを作成する

.meters や .miles のようなシステム内部名ではなく、「Meters」や「Miles」のようなわかりやすい名称を表示するための関数を作成します。

    func displayName(for unit: UnitLength) -> String {
        switch unit {
        case .meters:
            return "Meters"
        case .kilometers:
            return "Kilometers"
        case .feet:
            return "Feet"
        case .yards:
            return "Yards"
        case .miles:
            return "Miles"
        default:
            return "Unknown"
        }
    }

Step 4: 変換ロジックを書く

ユーザーが入力した文字列 (String) を Double に変換し、Swift の Measurement API を使って指定された単位間で変換します。

    func convertUnits() {
        guard let value = Double(inputValue) else {
            // 入力が不正な場合は 0 にリセット
            convertedValue = 0
            return
        }

        let inputMeasurement = Measurement(value: value, unit: fromUnit)
        let outputMeasurement = inputMeasurement.converted(to: toUnit)
        convertedValue = outputMeasurement.value
    }
}

4. 完成した ContentView.swift の例

以下に、上記の内容をすべてまとめたコードを示します。

import SwiftUI

struct ContentView: View {
    @State private var inputValue: String = ""
    @State private var fromUnit: UnitLength = .meters
    @State private var toUnit: UnitLength = .kilometers
    @State private var convertedValue: Double = 0.0

    let lengthUnits: [UnitLength] = [.meters, .kilometers, .feet, .yards, .miles]

    var body: some View {
        VStack(spacing: 20) {
            Text("Unit Converter")
                .font(.largeTitle)
                .padding()

            // 入力
            TextField("Enter value", text: $inputValue)
                .keyboardType(.decimalPad)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            // 変換元ユニットのピッカー
            Text("From Unit")
                .font(.headline)
            Picker("From Unit", selection: $fromUnit) {
                ForEach(lengthUnits, id: \.self) { unit in
                    Text(displayName(for: unit))
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()

            // 変換先ユニットのピッカー
            Text("To Unit")
                .font(.headline)
            Picker("To Unit", selection: $toUnit) {
                ForEach(lengthUnits, id: \.self) { unit in
                    Text(displayName(for: unit))
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()

            // 変換ボタン
            Button(action: convertUnits) {
                Text("Convert")
                    .font(.headline)
                    .padding()
                    .frame(maxWidth: .infinity)
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
            .padding(.horizontal)

            // 結果表示
            Text("Converted Value: \(convertedValue, specifier: \"%.4f\")")
                .font(.title2)
                .padding()

            Spacer()
        }
        .padding()
    }

    // ユニットに対応するわかりやすい名称を返すヘルパー
    func displayName(for unit: UnitLength) -> String {
        switch unit {
        case .meters:      return "Meters"
        case .kilometers:  return "Kilometers"
        case .feet:        return "Feet"
        case .yards:       return "Yards"
        case .miles:       return "Miles"
        default:           return "Unknown"
        }
    }

    // 変換ロジック
    func convertUnits() {
        guard let value = Double(inputValue) else {
            convertedValue = 0.0
            return
        }
        let inputMeasurement = Measurement(value: value, unit: fromUnit)
        let outputMeasurement = inputMeasurement.converted(to: toUnit)
        convertedValue = outputMeasurement.value
    }
}

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

5. アプリを実行する

  1. Xcode のツールバーからシミュレータ (例: iPhone 14) を選択します。

  2. Run ボタンをクリック、または Cmd + R キーでビルド & 実行します。

  3. テキストフィールドに数値を入力し、「From Unit」「To Unit」を選択して「Convert」をタップします。

  4. 「Converted Value」の下に結果が表示されます。

6. オプションの拡張機能

  1. 複数のカテゴリ

    • ユニットの配列を拡張し、温度 (UnitTemperature)、重量 (UnitMass)、などを追加

    • どのカテゴリを変換するかを選ぶためのセグメントコントロールを用意する

  2. ピッカースタイル

    • .segmentedPickerStyle() の代わりに、.wheelPickerStyle() や .menu など、好みに合わせて変更

  3. 入力バリデーション & アラート

    • ユーザーが不正な文字を入力した際に、アラートやラベルを表示してガイドする

  4. 履歴やお気に入り機能

    • よく使う変換を保存し、簡単に呼び出せるようにする

  5. ローカライズ

    • 別の言語や地域向けに表示文字列を翻訳し、多言語対応にする

まとめ

お疲れさまでした! これで、Swift の Measurement と Unit* 系クラスを活用し、使いやすい SwiftUI インターフェースを備えた単位変換アプリが完成しました。ここからさらにユニットの種類を増やしたり、UI を拡張したりして、より高度なアプリに仕上げていくこともできます。コーディングを楽しんでください!

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