Ios 如何使用NSUserDefaults保存NSTimer?敏捷的
我想使用NSUserDefaults保存一个计时器以实现我的目标。不幸的是,当我尝试使用NSUserDefaults保存NSDate()时,它会变成静态的,并且不会继续计数。我做错什么了吗?同样,我的目标是让计时器仍然工作,不管它是进入后台还是被终止。它应该保存当前时间,并将其与剩余时间进行比较。这是到目前为止我的代码。解决此问题的其他代码在OBJ C中,并在后台使用,这是不必要的Ios 如何使用NSUserDefaults保存NSTimer?敏捷的,ios,swift,nsdate,nstimer,nsdatecomponents,Ios,Swift,Nsdate,Nstimer,Nsdatecomponents,我想使用NSUserDefaults保存一个计时器以实现我的目标。不幸的是,当我尝试使用NSUserDefaults保存NSDate()时,它会变成静态的,并且不会继续计数。我做错什么了吗?同样,我的目标是让计时器仍然工作,不管它是进入后台还是被终止。它应该保存当前时间,并将其与剩余时间进行比较。这是到目前为止我的代码。解决此问题的其他代码在OBJ C中,并在后台使用,这是不必要的 func startTimer() { // then set time interval to expi
func startTimer() {
// then set time interval to expirationDate…
expirationDate = NSDate(timeIntervalSinceNow: 86400 )
dateTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(QOTDVC.updateUI(timer:)), userInfo: nil, repeats: true)
RunLoop.current.add(dateTimer, forMode: RunLoopMode.commonModes)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "TimerAdded"), object: nil)
}
func updateUI(timer: Timer)
{
// Call the currentTimeString method which can decrease the time..
let timeString = currentTimeString()
timerLabel.text = "\(timeString)"
}
func currentTimeString() -> DateComponents {
let unitFlags: Set<Calendar.Component> = [.hour, .minute, .second]
let countdown: DateComponents = Calendar.current.dateComponents(unitFlags, from: defaults.object(forKey: currentTime.description) as! Date, to: expirationDate as Date)
print("this is the \(countdown)")
if countdown.second! > 0 {
} else {
dateTimer.invalidate()
}
return countdown
}
func startTimer(){
//然后将时间间隔设置为expirationDate…
expirationDate=NSDate(timeintervalencenow:86400)
dateTimer=Timer.scheduledTimer(时间间隔:1.0,目标:self,选择器:#选择器(QOTDVC.updateUI(计时器:)),userInfo:nil,repeats:true)
RunLoop.current.add(dateTimer,forMode:RunLoopMode.commonModes)
NotificationCenter.default.post(名称:NSNotification.name(rawValue:“timeraded”),对象:nil)
}
func updateUI(计时器:计时器)
{
//调用currentTimeString方法,该方法可以减少时间。。
让timeString=currentTimeString()
timerLabel.text=“\(timeString)”
}
func currentTimeString()->DateComponents{
let unitFlags:Set=[.hour、.minute、.second]
让倒计时:DateComponents=Calendar.current.DateComponents(unitFlags,from:defaults.object(forKey:currentTime.description)作为!日期,to:expirationDate作为日期)
打印(“这是\(倒计时)”)
如果倒计时。秒!>0{
}否则{
dateTimer.invalidate()
}
返回倒计时
}
以下是我的完整代码示例。我希望这就是你想要的
import UIKit
protocol UserDefaultsTimerDelegate {
func timerAction(timer: Timer, secondsToEnd:Int)
}
class UserDefaultsTimer {
static var delegate: UserDefaultsTimerDelegate?
class var timerEndDate: Date? {
get {
return UserDefaults.standard.value(forKey: "timerEndDate") as! Date?
}
set (newValue) {
UserDefaults.standard.setValue(newValue, forKey: "timerEndDate")
}
}
class var timerInited: Bool {
get {
if let _ = timerEndDate {
return true
} else {
return false
}
}
}
class func setTimer(date: Date, setDateOnlyIfCurrenTimerIsOver: Bool) {
if !setDateOnlyIfCurrenTimerIsOver {
timerEndDate = date
} else {
if !timerInited {
timerEndDate = date
} else {
let difference = timerEndDate!.seconds(from: Date())
if (difference <= 0) {
timerEndDate = date
}
}
}
}
class func resetTimer() {
timerEndDate = nil
}
class func resumeTimer() {
if timerInited {
NSLog("timer end date:\(timerEndDate)")
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(action(timer:)), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
}
}
@objc class func action(timer: Timer) {
if let timerEndDate = timerEndDate {
let difference = timerEndDate.seconds(from: timer.fireDate)
if let delegate = delegate {
delegate.timerAction(timer: timer, secondsToEnd: difference)
}
NSLog("timer: \(difference)")
if (difference <= 0) {
timer.invalidate()
resetTimer()
}
} else {
timer.invalidate()
resetTimer()
}
}
}
extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfYear], from: date, to: self).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}
class ViewController: UIViewController, UserDefaultsTimerDelegate {
var label = UILabel(frame: CGRect(x: 40, y: 40, width: 60, height: 20))
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
label.text = ""
label.textColor = UIColor.black
view.addSubview(label)
UserDefaultsTimer.delegate = self
UserDefaultsTimer.setTimer(date: Date(timeIntervalSinceNow: 50), setDateOnlyIfCurrenTimerIsOver: true)
UserDefaultsTimer.resumeTimer()
}
func timerAction(timer: Timer, secondsToEnd: Int) {
label.text = "\(secondsToEnd)"
}
}
导入UIKit
协议UserDefaultsTimerDelegate{
func timerAction(计时器:计时器,秒结束:Int)
}
类UserDefaultsTimer{
静态变量委托:UserDefaultsTimerDelegate?
类变量timerEndDate:日期{
得到{
将UserDefaults.standard.value(forKey:“timerEndDate”)返回为!Date?
}
设置(新值){
UserDefaults.standard.setValue(newValue,forKey:“timerEndDate”)
}
}
类变量timerInited:Bool{
得到{
如果let=timerEndDate{
返回真值
}否则{
返回错误
}
}
}
类func setTimer(日期:date,setdateonlyfcurrentimerisover:Bool){
如果!setDateOnlyIfCurrenTimerIsOver{
timerEndDate=日期
}否则{
如果!时间限制{
timerEndDate=日期
}否则{
让差异=timerEndDate!。秒(从:日期())
if(差分Int){
返回Calendar.current.dateComponents([.month],from:date,to:self)。月份??0
}
///返回从另一个日期算起的周数
func周数(从日期开始:日期)->Int{
返回Calendar.current.dateComponents([.weekOfYear],from:date,to:self)。weekOfYear??0
}
///返回从另一个日期算起的天数
func天(从日期开始:日期)->Int{
返回Calendar.current.dateComponents([.day],from:date,to:self).day±0
}
///返回从另一个日期算起的小时数
func小时数(从日期开始:日期)->Int{
返回Calendar.current.dateComponents([.hour],from:date,to:self).hour±0
}
///返回从另一个日期算起的分钟数
func分钟数(从日期开始:日期)->Int{
返回Calendar.current.dateComponents([.minute],from:date,to:self)。分钟??0
}
///返回从另一个日期算起的秒数
func秒(从日期开始:日期)->Int{
返回Calendar.current.dateComponents([.second],from:date,to:self).second±0
}
///返回从另一个日期开始的自定义时间间隔说明
func偏移量(从日期:日期)->字符串{
如果年(自:日期)>0{返回“\(年(自:日期))y”}
如果月份(从:日期起)>0{return“\(月份(从:日期起))M”}
如果周数(从:日期)>0{return“\(周数(从:日期))w”}
如果天(从:日期)>0{return“\(天(从:日期))d”}
如果小时数(从:日期)>0{返回“\(小时数(从:日期))h”}
如果分钟数(从:日期)>0{return“\(分钟数(从:日期))m”}
如果秒数(从:日期)>0{返回“\(秒数(从:日期))s”}
返回“”
}
}
类ViewController:UIViewController,UserDefaultsTimerDelegate{
var label=UILabel(帧:CGRect(x:40,y:40,宽度:60,高度:20))
重写func viewDidLoad(){
super.viewDidLoad()
//加载视图后,通常从nib执行任何其他设置。
label.text=“”
label.textColor=UIColor.black
view.addSubview(标签)
UserDefaultsTimer.delegate=self
UserDefaultsTimer.setTimer(日期:日期(timeIntervalSinceNow:50),setDateOnlyIfCurrenTimerIsOver:true)
UserDefaultsTimer.resumeTimer()
}
func timerAction(计时器:计时器,秒结束:Int){
label.text=“\(secondsToEnd)”
}
}
这是我的完整代码示例。我希望这是您想要的
import UIKit
protocol UserDefaultsTimerDelegate {
func timerAction(timer: Timer, secondsToEnd:Int)
}
class UserDefaultsTimer {
static var delegate: UserDefaultsTimerDelegate?
class var timerEndDate: Date? {
get {
return UserDefaults.standard.value(forKey: "timerEndDate") as! Date?
}
set (newValue) {
UserDefaults.standard.setValue(newValue, forKey: "timerEndDate")
}
}
class var timerInited: Bool {
get {
if let _ = timerEndDate {
return true
} else {
return false
}
}
}
class func setTimer(date: Date, setDateOnlyIfCurrenTimerIsOver: Bool) {
if !setDateOnlyIfCurrenTimerIsOver {
timerEndDate = date
} else {
if !timerInited {
timerEndDate = date
} else {
let difference = timerEndDate!.seconds(from: Date())
if (difference <= 0) {
timerEndDate = date
}
}
}
}
class func resetTimer() {
timerEndDate = nil
}
class func resumeTimer() {
if timerInited {
NSLog("timer end date:\(timerEndDate)")
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(action(timer:)), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
}
}
@objc class func action(timer: Timer) {
if let timerEndDate = timerEndDate {
let difference = timerEndDate.seconds(from: timer.fireDate)
if let delegate = delegate {
delegate.timerAction(timer: timer, secondsToEnd: difference)
}
NSLog("timer: \(difference)")
if (difference <= 0) {
timer.invalidate()
resetTimer()
}
} else {
timer.invalidate()
resetTimer()
}
}
}
extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfYear], from: date, to: self).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}
class ViewController: UIViewController, UserDefaultsTimerDelegate {
var label = UILabel(frame: CGRect(x: 40, y: 40, width: 60, height: 20))
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
label.text = ""
label.textColor = UIColor.black
view.addSubview(label)
UserDefaultsTimer.delegate = self
UserDefaultsTimer.setTimer(date: Date(timeIntervalSinceNow: 50), setDateOnlyIfCurrenTimerIsOver: true)
UserDefaultsTimer.resumeTimer()
}
func timerAction(timer: Timer, secondsToEnd: Int) {
label.text = "\(secondsToEnd)"
}
}
导入UIKit
协议UserDefaultsTimerDelegate{
func timerAction(计时器:计时器,秒结束:Int)
}
类UserDefaultsTimer{
静态变量委托:UserDefaultsTimerDelegate?
类变量timerEndDate:日期{
得到{
将UserDefaults.standard.value(forKey:“timerEndDate”)返回为!Date?
}
设置(新值){
UserDefaults.standard.setValue(newValue,forKey:“timerEndDate”)
}
}
类变量timerInited:Bool{
得到{
如果let=timerEndDate{
返回真值
}否则{
返回错误
}
}
}
类func setTimer(日期:date,setdateonlyfcurrentimerisover:Bool){
如果!setDateOnlyIfCurrenTimerIsOver{
timerEndDate=日期
}否则{
如果!时间限制{
timerEndDate=日期
}否则{
让差异=timerEndDate!。秒(从:日期())
if(差分Int){
返回Calendar.current.dateComponents([.month],from:date,to:self)。月份??0
}
///返回从另一个日期算起的周数
func周数(从日期开始:日期)->Int{
返回Calendar.current.dateComponents([.we