タグ: Swift

  • Flutter iOSでビルドできない No such module ‘Flutter’ Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

    Flutter iOSでビルドできない No such module ‘Flutter’ Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

    Flutter で iOS用にbuild するも下記のエラーが AppDelegate.swift で起こってしまい、実行できません。

    No such module ‘Flutter’

    Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

    この記事はこれの解決方法です。

    解決方法

    Flutter プロジェクトのキャッシュを削除します。依存関係の問題を解消するために行います。

    flutter clean

    pubspec.yaml に従ってパッケージのダウンロードや更新、依存関係のセットアップを行います。

    flutter pud get

    ios ディレクトリに移動ます。

    cd ios

    ios/Podfile に基づいて Pods/ フォルダを作成します。また、ios/Podfile.lockを更新し、依存関係のバージョンを固定します。

    pod install

    xcode を書きコマンドで開きます。 Runner.xcodeproj ではないので注意⚠️

    open Runner.xcworkspace

    これで解決しない場合

    flutter をアップグレードしてみましょう。(私はこれで解決しました……。トホホ)アップグレードしたらまた、clean, pub get, pod install の手順を踏んでください。

    flutter upgrade

  • XCode 環境変数追加 Edit Scheme…

    XCode 環境変数追加 Edit Scheme…

    Flutter のプロジェクトで

    import Flutter
    import UIKit
    import GoogleMaps
    
    @main
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        GMSServices.provideAPIKey(ProcessInfo.processInfo.environment["MY_API_KEY"]!)
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

    のエラーが出ました。

    この際直打ちのAPIキーはやめて、環境変数に設置することにしました。

    やり方

    XCodeでプロジェクト名のところをクリックすると Edit Scheme… という項目があるのでクリックします。

    Environment Variables のところに + ボタンを押して、追加します。

    GOOGLE_MAPS_API_KEY
    
    hogehogehogehogehogehogehogeho

    みたいな感じで Name, Value に設定しました。

    その後、AppDelegate .swiftを以下のように書き換えました。

    import Flutter
    import UIKit
    import GoogleMaps
    
    @main
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        
          // Xcode の環境変数から APIキー を取得
          if let apiKey = ProcessInfo.processInfo.environment["GOOGLE_MAPS_API_KEY"], !apiKey.isEmpty {
              GMSServices.provideAPIKey(apiKey)
          } else {
              fatalError("Google Maps API Key is missing. Please set GOOGLE_MAPS_API_KEY in Xcode's Environment Variables.")
          }
    
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    

    これで動作しました!やったー

  • Vision OS 音量をコントロールする

    Vision OS 音量をコントロールする

    ❓ これは何

    VisionOS での音(AudioPlaybackController)を Slider を使って音量をコントロールする方法についてです。

    🪴 環境

    • sonoma 14.5(23F79)
    • Apple M1
    • 16GB

    🛠️ やり方

    今回は自然の音を再生するアプリを例に作っていきます。

    NatureEntity.swift

    import SwiftUI
    import RealityKit
    
    class NatureEntity: Entity {
        private var fireAudioController: AudioPlaybackController?
        
        @MainActor required init() {
            super.init()
        }
        
        init(fireAudio: AudioPlaybackController?, rainAudio: AudioPlaybackController?, insectAudio: AudioPlaybackController?) {
            super.init()
            self.fireAudioController = fireAudio
        }
        
        func updateGlobalVolume(_ volume: Double) {
            fireAudioController?.gain = volume
        }
    }
    

    続いて、Sliderでの操作部分の作成です。

    NatureControls.swift

    import SwiftUI
    
    struct NatureControls: View {
        @Binding var globalVolume: Float
        
        var body: some View {
            VStack {
                Text("Global Volume")
                Slider(value: $globalVolume, in: 0...1)
                    .padding()
            }
        }
    }

    最後に、これらをまとめて表示する部分です。

    SoundView.swift

    import SwiftUI
    import RealityKit
    
    struct SoundView: View {
        @State private var globalVolume: Double = -10
        @State private var natureEntity: NatureEntity?
    
        var body: some View {
            ZStack {
                RealityView { content in
                    let natureEntity = NatureEntity(fireAudio: nil) // 実際のオーディオコントローラーを渡す
                    content.add(natureEntity)
                    self.natureEntity = natureEntity
                }
                
                NatureControls(globalVolume: $globalVolume)
                    .onChange(of: globalVolume) { volume in
                        natureEntity?.updateGlobalVolume(volume)
                    }
                    .padding()
                    .background(Color.black.opacity(0.7))
                    .cornerRadius(10)
                    .padding()
            }
        }
    }

    これで、音量調整のできる機能が備わったと思います。

    ポイントは fireAudioController?.gain = volume という部分で、
    音量調整は gain で行うということです。Doubleで渡してあげたところうまくいきました。

Home
About
Blog
Works
Contact