2017-10-23 1 views
0

Ich weiß bereits, wie Sie Dinge speichern und ich kann sie automatisch beim Öffnen der App laden. Aber ich habe keine Ahnung, wie ich sie retten kann, wenn sie schließt! Ich habe einen Knopf für jetzt. Ich versuche, nur einen Wert zu speichern, StreakNumber. Aber wenn ich es versuche, scheitere ich.Die App speichern Daten, wenn die App beendet

Wenn ich in der App Delegat versuche ich sagen ViewController.AppSave(ViewController). Ich erhalte eine Fehlermeldung:

Editor placeholder in source file Expression resolves to an unused function

und wenn ich ViewController.AppSave() verwenden bekomme ich folgende Fehlermeldung:

Instance member 'SaveApp' cannot be used on type 'ViewController'; did you mean to use a value of this type instead?

import UIKit 
import UserNotifications 

class ViewController: UIViewController { 
    //TEST PLAY AREA// 

    @IBAction func SaveButton(_ sender: Any) { 
     SaveApp() 
    } 

    @IBAction func LoadButton(_ sender: Any) { 
     LoadApp() 
    } 

    ///TEST PLAY AREA ENDS 
    public var streakNumber = 0 
    public var streakNumberString = "" 

    public var activated = false 

    let defaults = UserDefaults.standard 
    //Labels 
    @IBOutlet var streakNumberLabel: UILabel! 

    @IBOutlet var remainingTimeTextLabel: UILabel! 

    @IBOutlet var remainingTimeNumberLabel: UILabel! 
    //Buttons 
    @IBAction func startButton(_ sender: Any) { 
     Activate() 

    } 
    @IBAction func stopButton(_ sender: Any) { 
     Deactivate() 
     seconds = 59 
     minutes = 59 
     hours = 47 

    } 

    //Timer 
    var timer = Timer() 
    var seconds = 0 
    var minutes = 0 
    var hours = 0 

    // Nitifications 
    //END 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     LoadApp() 

     // this enables notifications 
     UNUserNotificationCenter.current().requestAuthorization(options:[.alert , .sound , .badge], completionHandler:{ didAllow, error in 
     }) 
    } 

    func Activate(){ 
     if activated == false { 
      streakNumber += 1 

     } 
     activated = true 
     streakNumberLabel.text = String(streakNumber) 
    } 

    func Deactivate(){ 
     if activated == true{ 
      activated = false 
      ActivTimer() 

      // Notification 
      let content = UNMutableNotificationContent() 
      content.title = " 10 secodns are up " 
      content.subtitle = " yep time passed" 
      content.body = " The 10 seconds are really up!!" 
      content.badge = 1 
      let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 600, repeats:false) 
      let request = UNNotificationRequest(identifier: "timerDone", content: content , trigger: trigger) 
      UNUserNotificationCenter.current().add(request,withCompletionHandler:nil) 
     } 
    } 

    @objc func Clock(){ 
     seconds = seconds-1 
     if seconds == -1{ 
      seconds = 59 
      minutes = minutes-1 
     } 
     if minutes == -1{ 
      minutes = 59 
      hours = hours-1 
     } 
     remainingTimeNumberLabel.text = (String(hours) + ":" + String(minutes) + ":" + String(seconds)) 
     if seconds == 0 && hours == 0 && minutes == 0 { 

      timer.invalidate() 

     } 
    } 

    func ActivTimer(){ 
     timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.Clock), userInfo: nil, repeats: true) 
    }//SAVING STUFF DOESNT WORK 
    // 

    func SaveApp(){ 
     streakNumberString = String(streakNumber) 
     defaults.set(streakNumberString, forKey: "streakNumbers") 
     print("Saved" + String(defaults.integer(forKey: "streakNumbers"))) 

    } 

    func LoadApp(){ 
     streakNumberString = defaults.string(forKey: "streakNumbers")! 
     print (defaults.integer(forKey: "streakNumbers")) 
     streakNumber = Int(streakNumberString)! 
     streakNumberLabel.text = String(streakNumber) 
    }// 
} 
+0

appdidEnterBackground & willEnterforeground ist der beste Ort. Werfen Sie einen Blick auf 1. https://stackoverflow.com/questions/9011868/whats-the-best-way-to-detect-when-the-app-is-enter-the-background-for-my-vie 2. https://stackoverflow.com/questions/9599431/is-there-any-notification-to-get-before-application-did-enter-background 3. https://stackoverflow.com/questions/9039606/refresh- Daten nach dem Betreten eines Vordergrunds 4. https://stackoverflow.com/questions/10648388/ios-app-applicationwillenterforeground-and-it-stucked-for-a-while –

+0

Der meiste Code, den Sie gepostet haben, hat nichts mit dem Code zu tun, der Ihre Fehler verursacht. Bitte bearbeiten Sie Ihre Frage, um den relevanten Code einzubeziehen. Fügen Sie den tatsächlichen Code ein, den Sie ausprobiert haben und der Ihre Probleme verursacht. – rmaddy

Antwort

0

Der Fehler sagt alles. Sie können SaveApp() unter ViewController nicht aufrufen. Sie benötigen tatsächlich eine Instanz der ViewController, um auf sich selbst aufzurufen.

Wenn Sie Ihr ViewController Beispiel wollen ihre Daten über App Beendigung zu speichern, können Sie eine Benachrichtigung von den AppDelegate ‚Post s applicationDidEnterBackground Methode, die aufgerufen wird, wenn die App wird minimiert und vor der Beendigung auch:

func applicationDidEnterBackground(_ application: UIApplication) { 

    NotificationCenter.default.post(Notification(name: Notification.Name("AppAboutToTerminateOrMinimize"))) 
} 

Dann könnten Sie zu dieser Mitteilung in Ihrem ViewController ‚s viewDidLoad() abonnieren:

NotificationCenter.default.addObserver(self, 
             selector: #selector(AppSave), 
             name: Notification.Name("AppAboutToTerminateOrMinimize"), 
             object: nil) 

Oder wie rmaddy im Kommentar erwähnt s, kann man einfach den Code unten setzen in ViewController ‚s viewDidLoad() und überspringen die AppDelegate Teil:

NotificationCenter.default.addObserver(self, 
             selector: #selector(AppSave), 
             name: Notification(name: UIApplicationDidEnterBackgroundNotification, 
             object: nil) 

Auf diese Weise, wenn die Anwendung minimiert/beendet die AppDelegate Meldung senden, die ViewController Instanz (falls lebendig) erhalten es und wird AppSave()

Sie nennen würde haben AppSave() Methode als @objc

mit Anmerkungen versehen und es ist eine gute Praxis lowerCamelCase für die Benennung von Eigenschaften und Methoden/dhzu verwenden,statt AppSave()

+0

Es gibt einen viel besseren Weg, dies zu tun. Lassen Sie den View-Controller einfach für die Benachrichtigung "UIApplicationDidEnterBackground" registrieren. Keine Notwendigkeit für eine benutzerdefinierte Benachrichtigung. Sie müssen nichts mehr in der app delegate-Methode 'applicationDidEnterBackground' posten. – rmaddy

+0

@rmaddy Richtig! Das kam mir nicht in den Sinn :) – Dan

+0

@rmaddy wie mache ich das? –

Verwandte Themen