Swift 中的循环振动

Loop vibration in Swift

我正在使用 AVPlayer 播放声音。我试图让 iPhone 在此声音期间振动。
我可以通过以下方式产生振动:

AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

但如果我使用:尝试循环振动时遇到问题:

vibrationTimer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(ViewController.loopVibration), userInfo: nil, repeats: true)

@objc func loopVibration() {
      AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}

函数 loopVibration() 每两秒调用一次,但它不振动

不允许使用持续振动,您的应用可能会被拒绝。如果你仍然想这样做,你可以尝试这样的事情:

func vibrate() {
    for i in 0...13 {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(Double(i) * 0.1 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {
            AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
            self.vibrate()
        })
    }
}

不确定为什么这对您不起作用——以下示例适用于我的测试设备(iPhone X,iOS 11.2)。

下面的 ViewController 示例包括用于播放单一声音、播放单一振动、循环声音和循环振动的出口。 "Chirp"声音是一个1s的wav文件。

请注意,由于这是一个示例,下面的代码不会处理系统声音,如果 ViewController 被隐藏,也不会使计时器无效。如果您对此进行调整,请确保适当地管理您的系统资源。

//
//  ViewController.swift
//

import UIKit
import AudioToolbox

class ViewController: UIViewController {

    static let soundId: SystemSoundID? = {
        guard let soundURL = Bundle.main.url(forResource: "Chirp", withExtension: "wav") else {
            return nil
        }

        var soundId: SystemSoundID = 0
        AudioServicesCreateSystemSoundID(soundURL as CFURL, &soundId)
        return soundId
    }()

    static let timerInterval: TimeInterval = 2

    var soundTimer: Timer?
    var vibrationTimer: Timer?
    var playCount = 0 {
        didSet {
            playCountLabel.text = String(playCount)
        }
    }

    func invalidateTimers() {
        if let vibrationTimer = vibrationTimer {
            vibrationTimer.invalidate()
        }
        if let soundTimer = soundTimer {
            soundTimer.invalidate()
        }
    }

    @IBOutlet weak var playCountLabel: UILabel!

    @IBAction func playSound(_ sender: Any) {
        if let soundId = ViewController.soundId {
            AudioServicesPlaySystemSound(soundId)
            playCount += 1
        }
    }

    @IBAction func loopSound(_ sender: Any) {
        invalidateTimers()
        soundTimer = Timer.scheduledTimer(timeInterval: ViewController.timerInterval, target: self, selector: #selector(playSound(_:)), userInfo: nil, repeats: true)
    }

    @IBAction func vibrate(_ sender: Any) {
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
        playCount += 1
    }

    @IBAction func loopVibrate(_ sender: Any) {
        invalidateTimers()
        soundTimer = Timer.scheduledTimer(timeInterval: ViewController.timerInterval, target: self, selector: #selector(vibrate(_:)), userInfo: nil, repeats: true)
    }

    @IBAction func cancelAll(_ sender: Any) {
        invalidateTimers()
    }

}