AppleWatchアプリを作ってみる(6)音を出すアプリを作ってみる

前回はアプリに画像を入れてAppleWatchじゃんけんアプリを作成しました。
今回は、以下の
今回は、SwiftUI対応 たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 12/iOS 14対応 単行本 – 2021/2/1を写経して、「音出しアプリ」を作ってみたいと思います。この本はiPhoneアプリ作成入門の本ですが、ほとんどそのまま、AppleWatchアプリ作成にも使えます。
- 1. ソースコード
- 2. AppleWatchアプリを作ってみる 目次
- 3. 開発環境
- 4. 新規watchOSアプリの作成
- 5. 画像ファイルと音声ファイル(mp3形式)をAssets.xcassetsフォルダにドラッグ
- 6. HStackを用いて画像ファイルを縦に3つ並べる
- 7. 音源ファイルのFile inspector > Target Membershipの設定
- 8. 音を鳴らすためのファイルSoundPlayer.swiftを作成
- 9. SoundPlayer.swiftを編集して、音を鳴らすコードを書く
- 10. ContenView.swiftで画像をタップすると音声がなるようにコードを編集
- 11. AppleWatch実機テスト
- 12. ソースコード
ソースコード
ttps://github.com/adash333/AppleWatch-Sound
AppleWatchアプリを作ってみる 目次
- (0)XcodeインストールとiOSとwatchOSのアップデートに合計10時間かけてAppleWatch実機で”HelloWorld”
- (1)ボタンをタップするとテキストが変化
- (2)複数ページからなるアプリ
- (3)実機テストで"Your maximum App ID limit has been reached. You may create up to 10 App IDs every 7 days"が出たら2個目のAppleIDを新規作成してそのIDでwatchOSアプリを作成し実機テストを行う
- (4)じゃんけんアプリ
- (5)作曲アプリGarageBandでmp3ファイルを作成
- (6)音を出すアプリを作ってみる
- (7)HealthKitを設定して心拍数を表示するアプリを実機で動かす
開発環境
MacBookAir (M1, 2020)
macOS Big Sur 11.6
Xcode 13.0
git version 2.30.1 (Apple Git-130) (最初から入っていたもの)
xcode-select version 2384.
Homebrew 3.2.13
VisualStudioCode 1.60.2
iPhone12mini, iOS 15.0
AppleWatch Series 6, watchOS 8.0
新規watchOSアプリの作成
- Xcodeを起動し、「Create a new Xcode project」をクリック
- watchOS > Watch App > Next の順にクリック
- 「Choose options for your new project」の画面が出てくるので、プロジェクト名を入力してNextをクリック(今回は、"Chord"という名前にしました。)
- 保存場所を選択する画面が出てくるので、Users > {ユーザ名} > src フォルダを選択して、Create をクリック
- CanvasのResume を押して、Previewを表示
すると、以下のような画面になります。

画像ファイルと音声ファイル(mp3形式)をAssets.xcassetsフォルダにドラッグ
いらすとやから音符の画像を3つダウンロードします。これらと、AppleWatchアプリを作ってみる(5)作曲アプリGarageBandでmp3ファイルを作成で作成した音声ファイル(c1.mp3, f1.mp3, g1.mp3)をAssets.xcassetsフォルダにドラッグします。

画像ファイル3つと、音声ファイル3つが保存されます。

HStackを用いて画像ファイルを縦に3つ並べる
Navitator AreaのContentVIew.swiftをクリックしたのち、
- カーソルを12行目 Text(“Hello, World!") の前にカーソルをあわせて
- Toolbarの右側の、「Library追加ボタン」をクリック

Library追加画面で検索窓にVStaと入力し、下に出てくる vertical Stack をダブルクリックします。

以下のようになるので、VStack{}の中身に以下のように書き込みます。
VStack {
Text("音符をタップ!")
Image("c")
.resizable()
.aspectRatio(contentMode: .fit)
Image("f")
.resizable()
.aspectRatio(contentMode: .fit)
Image("g")
.resizable()
.aspectRatio(contentMode: .fit)
}

音源ファイルのFile inspector > Target Membershipの設定
音を鳴らすための準備をします。
Assets.xcassetsフォルダで、Commandキーを押しながら、c1, f1, g1を選択した状態で、「Show the File inspector」をクリックします(下図参照)。

その状態で、Target Membership の チェックボックスを全てONにします。私の場合は、
- Chord (プロジェクト名)
- Chord WatchLKit App
のチェックボックスがOFFになっていたので、ONにしました。


音を鳴らすためのファイルSoundPlayer.swiftを作成
NavitatorAreaでContentView.swiftを選択した状態(Chord WatchKit Extensionの中であればどれでもよいです)で、右クリック

WatchOS > WatchKit Class を選択した状態で、Nextをクリック

Class のところに、 SoundPlayer と入力し、Next をクリック

そのままCreateします(必要あるかわかりませんが、念の為、TargetsのチェックボックスはすべてONにしておきます)。

なにか聞かれますが、一応、Don’t Createにしておきます。

以下のような画面になります。

SoundPlayer.swiftを編集して、音を鳴らすコードを書く
AVFoundationをimportするのがポイントだそうです。
以下のように記載します。
import WatchKit
import AVFoundation
import UIKit
class SoundPlayer: NSObject {
// cの音源データの読み込み
let cData = NSDataAsset(name: "c1")!.data
// c用プレイヤーの変数
var cPlayer: AVAudioPlayer!
func cPlay() {
// c用のプレイヤーに、音源データを指定
cPlayer = AVAudioPlayer(data: cData)
// cの音源再生
cPlayer.play()
}
}

しかし、"Call can trhow, but it is not…"というエラーが出てくるので、func cPlay() {}の中身を
do {
try メソッド呼び出し
} catch {
// エラー処理
}
構文で書き直します。
func cPlay() {
do {
// c用のプレイヤーに、音源データを指定
cPlayer = try AVAudioPlayer(data: cData)
// cの音源再生
cPlayer.play()
} catch {
print("cで、エラー発生")
}
}

なんか、SwiftUI対応 たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 12/iOS 14対応 単行本 – 2021/2/1を写経しただけで、いまいち理解していない感じですが、他のf1.mp3, g1.mp3についても同様のコードを記載します。

ContenView.swiftで画像をタップすると音声がなるようにコードを編集
Navitator AreaのContentView.swiftをクリックし、Canvasで一番上の画像を選択し、Inspector Areaの上の方の一番右側のアイコンをクリックした状態にします。

この状態で、Inspector Areaの一番下の Add Modifierをクリックし、tap で検索して、"On Tap Gesture"をクリックします。

Image(“c")の後の方に、.onTapGesture {} が追加されるので、
.onTapGesture {
soundPlayer.cPlay()
}
と記載します。

上記のように、"Cannot find 'soundPlayer’ in scope"というエラーが表示されるので、struct ContentView’ View { の直下に以下を記載します。
// 音を鳴らすためのsoundPlayerクラスのインスタンスを生成
let soundPlayer = soundPlayer()

これで、Canvasでプレビューした状態で青い音符をタップすると、c1.mp3が再生されます。
同様に、f1.mp3, g1.mp3もタップで再生されるようにコードを記載します。

AppleWatch実機テスト
- iPhoneを有線でMacに接続
- iPhoneのロックを解除
- XcodeのToolbarの真ん中のあたりをクリックして、「x さんのApple Watch via x さんの iPhone」を選択
- Toolbarの左側にある三角ボタン(▲)をクリックして、実機用にビルドを開始
7−8分くらい待った後、また、CanvasでResumeを押したりして、ビルド開始から10分後くらいに、無事、AppleWatch実機でアプリを動かすことができました。毎回、ここのところは10分くらい時間がかかってひやひやします。無事、音も成りました。うれしい!

Watchアプリは画面が小さい分、単純なアプリしか作れないので、アプリ作成にかかる時間が短い気がします。なんとなく、、、本格的なアプリを作る場合は、時間がかかるのかもしれません、、、
ディスカッション
コメント一覧
まだ、コメントがありません