[SWIFT] iOS app development: Timer app (5. Implementation of alarm and vibration)

スクリーンショット 2020-10-28 10.49.18.png

Contents

The points for creating a timer app are posted in multiple articles. This article describes the implementation of alarms and vibrations that fire when the timer countdown reaches zero.

environment

Git repository

You can see the sample code from the URL of the Git repository below. https://github.com/msnsk/Qiita_Timer.git

procedure

  1. Import the AudioToolbox library with TimeManager
  2. Add default alarm note name and alarm ID properties to TimeManager
  3. Import the AudioToolbox library in MainView
  4. Implement alarm triggering in .onReceive modifier of ZStack in MainView
  5. Implement vibration activation in .onReceive modifier of ZStack of MainView

1. Import the Audio Toolbox library with Time Manager

Import a new library called Audio Toolbox into TimeManager. The AudioToolbox library contains classes, properties, and methods primarily for sound effect sounds, which you can use to break in the alarm sound when the timer countdown reaches zero.

TimeManager.swift


import SwiftUI
import AudioToolbox //Additional import

class TimeManager: ObservableObject {
    //(Properties and methods omitted)
}

2. Add default alarm note name and alarm ID properties to TimeManager

To use a sound source included in AudioToolbox, you need to specify the SystemSoundID of that sound source. SystemSoundID is a data type, UInt32 typealias.

So, create a property for this data type in the TimeManager class, attach the @Published property wrapper, and assign the ID of the sound source you want to specify by default as the value.

The following resources will help you to find out which ID sounds what. https://github.com/TUNER88/iOSSystemSoundsLibrary

I checked the items of this resource one by one, but it seems to be the notification sound used in a fairly old model of iOS device. We could not find any information about the notification sound that is used by default on recent models. Please note. (If anyone knows, I would appreciate it if you could comment)

The property name was soundID, and I personally felt that it was a comfortable sound source, so I assigned 1151 as the ID.

TimeManager.swift


import SwiftUI
import AudioToolbox //Additional import

class TimeManager: ObservableObject {
    //(Other properties omitted)

    //Stores the default sound ID with the data type for using the sound source stored in Audio Toolbox
    @Published var soundID: SystemSoundID = 1151

    //(Method omitted)
}

3. Import the AudioToolbox library in MainView

Import the AudioToolbox library into the MainView as well as the TimeManager in step 1.

The reason for importing AudioToolbox here is that you need to write a method in MainView that sounds an alert when the countdown timer actually reaches 0, and that method is included in AudioToolbox.

MainView.swift


import SwiftUI
import AudioToolbox //Additional import

struct MainView: View {
    //(Properties and methods omitted)
}

4. Implement alarm triggering in the MainView ZStack .onReceive modifier

In the .onReceive modifier of ZStack of MainView, if the remaining time is more than 0 or less than 0, the conditional branch by the if-else statement was already done. Add a method for triggering the alarm sound in the else statement (when the remaining time is 0 or less).

The method is described as follows. In the first argument, specify the soundID property of the TimeManager class prepared earlier in step 2. The second argument is nil.

AudioServicesPlayAlertSoundWithCompletion(self.timeManager.soundID, nil)

MainView.swift


struct MainView: View {
    //(Property omitted)
    
    var body: some View {
        ZStack {
            //(abridgement)
        }
        //Executes the code in the closure triggered by a timer that is activated every specified time (1 second)
        .onReceive(timeManager.timer) { _ in
            //The timer status is.Do nothing except running
            guard self.timeManager.timerStatus == .running else { return }
            //If the remaining time is greater than 0
            if self.timeManager.duration > 0 {
                //From the remaining time-1 do
                self.timeManager.duration -= 1
            //When the remaining time is 0 or less
            } else {
                //Timer status.Change to stopped
                self.timeManager.timerStatus = .stopped
                //Sound an alarm
                AudioServicesPlayAlertSoundWithCompletion(self.timeManager.soundID, nil)
            }
        }
    }
}

5. Implement vibration activation in the .onReceive modifier of ZStack in MainView

Next to the alarm sound is the implementation of vibration. This also uses the same method as the alarm sound. The arguments change.

In the argument, the value of soundID for vibration obtained by the kSystemSoundID_Vibrate property is converted to the SystemSoundID data type and passed.

AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {}

MainView.swift


struct MainView: View {
    //(Property omitted)
    
    var body: some View {
        ZStack {
            //(abridgement)
        }
        .onReceive(timeManager.timer) { _ in
            guard self.timeManager.timerStatus == .running else { return }
            if self.timeManager.duration > 0 {
            //(abridgement)
            } else {
                //(abridgement)
                //Sound an alarm
                AudioServicesPlayAlertSoundWithCompletion(self.timeManager.soundID, nil)
                //Activate vibration
                AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {}
            }
        }
    }
}

Next time, we will create a setting screen that includes alarm and vibration on / off.

Recommended Posts

iOS app development: Timer app (5. Implementation of alarm and vibration)
iOS app development: Timer app (7. Implementation of alarm sound selection)
iOS app development: Timer app (8. Implementation of progress bar)
iOS app development: Timer app (4. Countdown implementation)
iOS app development: Timer app (6. Creation of setting screen)
iOS app development: Timer app (2. Timer display)
iOS app development: Timer app (summary)
iOS app development: Timer app (1. Timer time setting)
iOS app development: Timer app (10. Create animation)
iOS app development: Timer app (9. Customize the color of the progress bar)
iOS app development: Timer app (3. Start / Stop button, Reset button)
Complete self-study IOS app development diary
iOS App Development Skill Roadmap (Introduction)
Default implementation of Object.equals () and Object.hashCode ()
I stumbled upon the development and publication of my first iPhone app
Implementation comparison of production that makes images shine on iOS and Android
Whereabouts of JAXB Reference implementation and DatatypeConverterImpl
Thorough comparison of Android and iOS implementations
Implementation of tabs using TabLayout and ViewPager
iOS app development: Timer app (8. Implementation of progress bar)
Utilization of Active Hash
Utilization of seed file
iOS app development: Timer app (9. Customize the color of the progress bar)
List of libraries useful for ios application development
SKStoreReviewController implementation memo in Swift UI of iOS14
This and that of conditional branching of rails development