我正在使用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秒之后。
我该怎么做?
答案 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
方法中添加这些代码也想导入AudioToolBox
和AVFoundation
答案 1 :(得分:2)
据我所知,由于iOS中的后台模式限制,无法完成此操作。请参阅Background modes。只要您的应用不属于这些应用,您就不能要求您的代码在当天(或夜晚)的特定时间点火。
我假设您的应用程序不会出现在前台(基于凌晨1点)
作为一种解决方法,您可以在上述时间启动本地通知,要求用户清除本地通知中的数据。(虽然看起来很愚蠢)
或者如果您的应用支持上述模式,您可以查看this回答。