plist Werteliste mit Datumsangaben filtern geht nicht.

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • plist Werteliste mit Datumsangaben filtern geht nicht.

    Hallo zusammen

    Vorab. Bin relativ neu bei Xcode, habe noch fast keine Kenntnisse. Ich wollte mich mal an plists versuchen, um eine einfach App zu erstellen, die folgendes macht:

    Schauen, wieviel Geld man jetzt hätte, wenn man zu einem Zeitpunkt x, die Geldmenge y investiert hätte.

    Ich hab erstmal eine pliste mit den ganzen Daten erstellt (Zeitpunkt und Kurs). Aber anscheinend ist etwas bei mir schief gelaufen. Könntet ihr mir weiterhelfen?

    Es müsste quasi 2 Auswahlfelder geben; 1x den wählbaren Monat und 1x das wählbare Jahr. Und zum schluss noch das Feld mit dem Betrag y, mit dem der Kurs des Zeitpunkt x multipliziert wird.

    Vielen Dank!
  • Hallo Lukas!

    Du lieferst etwas wenig Informationen, um helfen zu können: Was machst Du genau, welcher Fehler tritt wann auf? Etwas Code es evt. auch hilfreich.

    So wird Dir keiner sinnvolle Tipps geben können...

    Grundsätzlich würde ich die Werte einfach in einem NSDictionary ablegen und dieses mittels der entsprechenden Methoden in eine Datei schreiben bzw. das Dictionary mit dem Dateiinhalt initialisieren. Alternativ könntest Du auch mit NSUserDefaults arbeiten.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Hallo Mattes

    Danke für deine Antwort!

    Ich habe Dir anbei den bisherigen Code, sowie einen Screenshot von einem Ausschnitt der Datentabelle gesendet.

    Gruss

    Lukas





    import UIKit

    class ViewController: UIViewController {

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            print(getDataForDate(date: "05.05.2009"))
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        
        func getSwiftArrayFromPlist(name: String)->(Array<Dictionary<String,String>>)
        {
            let path = Bundle.main.path(forResource: name, ofType: "plist")
            var arr : NSArray?
            arr = NSArray(contentsOfFile: path!)
            return (arr as? Array<Dictionary<String, String>>)!
            
            
        }
        
        func getDataForDate(date:String)->(Array<[String:String]>)
        {
            let array = getSwiftArrayFromPlist(name: "date")
            let namePredicate = NSPredicate(format: "price")
            return [array.filter {namePredicate.evaluate(with: $0)}[0]]
    Bilder
    • plist.png

      13,46 kB, 462×91, 8 mal angesehen
  • Ich gebe zu, Swift bis jetzt nicht zu verstehen, aber m. E. passen die Datentypen auf dem Screenshot nicht zum Code (Number vs. String).

    Bitte sag doch einmal, was nicht funktioniert: Bis jetzt hast Du noch nix zum Fehler gesagt. Wo ist das Problem? Vielleicht hilft es, mit dem Debugger mal durch Deinen Code zu steppen.

    BTW, es wäre nett (und besser lesbar), wenn Du Code in die entsprechenden Tags packen würdest...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Der Pfad path (unglückliche Variablenbezeichnung) scheint ja auch nil zu sein. Gibt es denn eine entsprechende Plist im AppBundle? Wahrscheinlich nicht, ich würde das auf jeden Fall prüfen, bevor ich damit weiterarbeite.

    Gibt es da in Swift nicht so etwas wie guard? Aber damit kennen sich andere besser aus...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Zunächst würde ich nicht raten, wo das Problem liegt, sondern den Code einmal Zeile für Zeile mit dem Debugger durchgehen und Variableninhalte prüfen. Dabei vielleicht die Zuweisung des Pfades in mehrere Zeilen aufteilen.

    Außerdem würde ich die Plist nicht im AppBundle speichern, da Du (vermutlich) deren Inhalt zur Laufzeit ändern möchtest: Dort hat der Benutzer keine Schreibrechte.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Das Lader der plist funktioniert in dem Projekt doch jetzt.

    Beim Ausführen gibt es allerdings eine EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) Exception bei der Zeile

    Quellcode

    1. return (arr as? Array<Dictionary<String, String>>)!
    Da habe ich leider keine Idee, woran dies liegen könnte und in der Console gibt es leider auch keine Ausgabe oder weitere Information dazu. :(


    Swift ist ja schon toll und einfach und daher können Dir die Swift Profis sicherlich weiterhelfen. ;)
  • MCDan schrieb:

    Das Lader der plist funktioniert in dem Projekt doch jetzt.

    Beim Ausführen gibt es allerdings eine EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) Exception bei der Zeile

    Quellcode

    1. return (arr as? Array<Dictionary<String, String>>)!
    Da habe ich leider keine Idee, woran dies liegen könnte und in der Console gibt es leider auch keine Ausgabe oder weitere Information dazu. :(


    Swift ist ja schon toll und einfach und daher können Dir die Swift Profis sicherlich weiterhelfen.
    Also als Swift Profi mag ich mich nicht bezeichnen aber ein wenig verstehe ich schon davon. Ich hab deswegen mal den Code angeschaut.

    Das sieht ja mehr als abenteuerlich aus. Du hast eine Variable arr vom Typ NSArray. Diesen willst du nun als erstes Optional als Array<Dictionary<String,String>> umcasten. Dann machst du aber ein expliziten Unwrap. Das kann nur schiefgehen. Das sind doch zwei verschiedene Typen.

    Was willst du da machen? Warum sagst du nicht einfach:

    Quellcode

    1. return arr
  • Du musst natürlich noch den Rückgabewert seiner Funktion ändern. Diese gibt nun ein NSArray mit allen Objekten zurück.

    Jetzt musst du dieses NSArray nutzen um dein gewünschtes Objekt zu finden. Sei es mit Filtern oder am Anfang erstmal drüber loopen.

    Dann solltest du dir Gedanken machen, was der Rückgabewert davon ist. Denn dieser passt auch nicht.

    Man hat das Gefühl, du weißt nicht so recht was du da machst. Les dir mal durch was der Unterschied zwischen einem NSArray und Array ist und schaue dir an was das für Objekte da drinnen sind. Diese bestimmen ja dann auch den Rückgabewert
  • Mimimi Swift Gebashe, was ganz Neues ;)

    Hier ein hoffentlich verständlicher Ansatz


    C-Quellcode

    1. override func viewDidLoad() {
    2. super.viewDidLoad()
    3. print(filterForDate("05.05.2009"))
    4. }
    5. func swiftArrayFromPlist(name: String)-> [[String: Any]]
    6. {
    7. guard
    8. let url = Bundle.main.url(forResource: name, withExtension: "plist"),
    9. let data = try? Data(contentsOf: url),
    10. let arrayFromPlist = try? PropertyListSerialization.propertyList(from:data, options: [], format: nil) as? [[String: Any]],
    11. let finalData = arrayFromPlist
    12. else {
    13. fatalError("Something went wrong")
    14. }
    15. return finalData
    16. }
    17. func filterForDate(_ date:String) -> [[String: Any]]
    18. {
    19. let array = swiftArrayFromPlist(name: "date")
    20. let namePredicate = NSPredicate(format: "date = %@", date)
    21. let result = array.filter({
    22. namePredicate.evaluate(with: $0)
    23. })
    24. return result
    25. }
    Alles anzeigen
    Wenn ich zu komme, hab ich auch noch eine Swiftigere Lösung
  • Michael schrieb:

    Die Zeile

    let finalData = arrayFromPlist

    ist eigentlich überflüssig.
    Ähhh… Jein. if let some = try? optionalProducingExpression reduziert aktuell leider keine doppelten Optionals. Da ist gerade ein Proposal in der Mache, das hoffentlich durchkommt: Make try? + optional chain flattening work together

    @matz hat hier vorbildlich da rumgearbeitet! ;)
    Twix heißt jetzt Raider!