如何在Swift 3中每天为特定时间设置闹钟?

时间:2017-10-20 04:24:43

标签: ios swift swift3 timer

我正在使用Swift 3开发一个iOS应用程序,我需要运行一个代码来清除在某个时间使用的本地数据库(假设每天凌晨1点)。

我遇到this example for running a code at a given time,但他提供的示例使用了代码运行时的时间间隔。这是已发布代码的修改版本:

func setAlarm(){
    print("set alarm called")
    let date = Date().addingTimeInterval(5 * 60 * 1)
    let timer = Timer(fireAt: date, interval: 0, target: self, selector: #selector(self.clearAllData), userInfo: nil, repeats: false)
    RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
}

此代码将在调用函数clearAllData代码后5分钟调用setAlarm()函数。这很好用,但这不是我想要的。我希望能够在某个时间设置一个警报,而不是在N秒之后。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

我做过这样的iOS应用程序,最后搜索了很多我使用的本地通知。延迟通知显示时间。试试这个,让我知道结果

`func scheduleNotification(date:String , time: String , subject:String) {

    var dateString = date+" "+time
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"

    let convertedDate = dateFormatter.date(from: dateString)!

    let subtractTime = Calendar.current.date(byAdding: .minute, value: -10, to: convertedDate)

    dateString = dateFormatter.string(from: subtractTime!)

    var localTimeZoneName: String { return TimeZone.current.identifier }
    var secondsFromGMT: Int { return TimeZone.current.secondsFromGMT() }
    dateFormatter.timeZone = TimeZone(secondsFromGMT: secondsFromGMT)
    dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"

    let dateObj:Date = dateFormatter.date(from: dateString)!

    print("alaram time  : \(dateObj)")

    let triggerDaily = Calendar.current.dateComponents([.day,.month,.year,.hour,.minute,], from: dateObj)


    let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)

    let alarmId = UUID().uuidString

    let content = UNMutableNotificationContent()
    content.title = "your title"
    content.body = subject
    content.sound = UNNotificationSound.init(named: "your sound filename.mp3")
    content.categoryIdentifier = alarmId

    let request = UNNotificationRequest(identifier: alarmIdentifier, content: content, trigger: trigger)

    print("alarm identi   : \(alarmIdentifier)")

    UNUserNotificationCenter.current().delegate = self
    UNUserNotificationCenter.current().add(request) {(error) in

        if let error = error {
            print("Uh oh! i had an error: \(error)")
        }
    }
}`   

以上func是设置通知

func playSound(_ soundName: String) {

    //vibrate phone first
    AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
    //set vibrate callback
    AudioServicesAddSystemSoundCompletion(SystemSoundID(kSystemSoundID_Vibrate),nil,
                                          nil,
                                          { (_:SystemSoundID, _:UnsafeMutableRawPointer?) -> Void in
                                            print("callback", terminator: "") //todo
    },
                                          nil)
    let url = URL(
        fileURLWithPath: Bundle.main.path(forResource: soundName, ofType: "mp3")!)

    var error: NSError?

    do {
        audioPlayer = try AVAudioPlayer(contentsOf: url)
    } catch let error1 as NSError {
        error = error1
        audioPlayer = nil
    }

    if let err = error {
        print("audioPlayer error \(err.localizedDescription)")
    } else {
        audioPlayer!.delegate = self
        audioPlayer!.prepareToPlay()
    }
    //negative number means loop infinity
    audioPlayer!.numberOfLoops = -1
    audioPlayer!.play()
}

播放声音传递你的mp3文件名也声明audioPlayer为AVAudioPlayer

playSound("Your sound file name")

    let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
    actionSheet.view.tintColor = UIColor.black

    actionSheet.addAction(UIAlertAction(title: "Stop Alert", style: UIAlertActionStyle.default, handler: { (alert:UIAlertAction!) -> Void in


        self.audioPlayer?.stop()
    }))
    window?.rootViewController!.present(actionSheet, animated: true, completion: nil)

UNUserNotificationCenterDelegate方法中添加这些代码也想导入AudioToolBoxAVFoundation

答案 1 :(得分:2)

据我所知,由于iOS中的后台模式限制,无法完成此操作。请参阅Background modes。只要您的应用不属于这些应用,您就不能要求您的代码在当天(或夜晚)的特定时间点火。

我假设您的应用程序不会出现在前台(基于凌晨1点)

作为一种解决方法,您可以在上述时间启动本地通知,要求用户清除本地通知中的数据。(虽然看起来很愚蠢)

或者如果您的应用支持上述模式,您可以查看this回答。