webentwicklung-frage-antwort-db.com.de

Swift Plist Lesen und Initialisieren von Arrays als Objekte für Schlüssel

Ich entwickle eine kleine UITableView-basierte App in Swift. Ich habe einige grundlegende Arrays als solche hartcodiert (dazu gehören die grundlegende Klassendeklaration und die UITableView-Outlet-Deklaration:

import UIKit

class ScenesViewController: UITableViewController {

@IBOutlet var myTableView: UITableView

var sceneName = ["Scene 1", "Scene 2", "Scene 3", "Scene 4", "Scene 5"]
var sceneDetail = ["Hi", "Hello", "Bye", "My Bad", "Happy"]

Dieser Code befindet sich in einer UITableViewController, die einen Auslass hat, der an eine UITableView angeschlossen ist. Ich habe dafür eine Plist namens "Scenes.plist" erstellt und versucht, den Code zu ersetzen. In Objective-C würde ich Folgendes tun:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Scenes" ofType:@"plist"];

NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
sceneName = [dict objectForKey:@"SceneName"];
sceneDetail = [dict objectForKey:@"SceneDetail"];

Ich fing an, dies in Swift so zu tun:

let path = NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist")

let dict = NSDictionary(contentsOfFile:path)  // Error: 'ScenesViewController.Type' does not have a member named 'path'

Ich suchte im Internet nach einer Lösung, konnte aber keine finden. Also habe ich den nächsten Weg eingeschlagen - ein "fast" Einzeiler:

let dict = NSDictionary(contentsOfFile: 
    NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist"))

var sceneName = dict["SceneName"] // Error: 'ScenesViewController.Type' does not have a member named 'dict'

Nun, die einzige Lösung, auf die ich fast zurückgreifen kann, besteht darin, für jedes Array alles auf einer Zeile zu haben:

var sceneName = NSDictionary(contentsOfFile: 
    NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist").objectForKey("SceneName")
// Warning: Variable 'sceneName' inferred to have type 'AnyObject!', which may be unexpected
// Fix-It: Add an explicit type annotation to silence this warning (var sceneName: AnyObject! = ...)

Also habe ich die explizite Typanmerkung hinzugefügt, um herauszufinden, dass es mehr Fehler gibt. Innerhalb der cellForRowAtIndexPath:-Funktion:

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
    let cell: UITableViewCell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell

    // Configure the cell...

    cell.textLabel.text = sceneName[indexPath!.row] // Error: could not find member 'row'
    return cell
}

Es gibt tatsächlich zwei Fehler ; Ich weiß nicht, ob dies versehentlich vervielfältigt wird oder nicht. Die nächsten Fehler befinden sich in der prepareForSegue:sender:-Methode:

override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
    if segue?.identifier == "ShowDetails" {
        var detailVC: ScenesDetailViewController = segue!.destinationViewController as ScenesDetailViewController

        var myIndexPath: NSIndexPath = myTableView.indexPathForSelectedRow()

        var row: Int = myIndexPath.row

        detailVC.detailModal = [sceneDetail[row], sceneName[row]] // Error: Could not find an overload for 'subscript' that accepts the supplied arguments
    }
}

Wieder gibt es zwei Fehler. Ich glaube jedoch, dass dies daran liegt, dass sceneDetail und sceneName beide verwendet werden. Es scheint überall zu Fehlern beim Lesen und Verwenden von plists in Dateien zu kommen, die in Objective-C nicht vorhanden sind (oder auf die ich nicht gestoßen bin).

Danke im Voraus,

-KodInc

13
KodInc

Um Ihr anfängliches Problem zu lösen, fügen Sie den Code in eine Funktion ein, wie zum Beispiel:

var memoryName = []
var memoryDetail = []

override func awakeFromNib() {
    super.awakeFromNib()

    let path = NSBundle.mainBundle().pathForResource("Memories", ofType:"plist")
    let dict = NSDictionary(contentsOfFile:path)

    memoryName = dict["MemoryName"] as Array<String>
    memoryDetail = dict["MemoryDetail"] as Array<String>
}
19
paiv

Sie können dieses Problem lösen, indem Sie Ihren Code in eine Funktion verschieben, die nach der Objektinitialisierung aufgerufen wird.

Eigenschaften werden als Teil der Initialisierung Ihres Objekts initialisiert. Sie haben path und dict als Eigenschaften erstellt und versuchen, sie mit Code zu initialisieren, der die Voraussetzungen für die Initialisierung nicht erfüllt.

Ein Initialisierer kann keine Instanzmethoden aufrufen, Die Werte von Instanzeigenschaften lesen oder auf self als Wert Verweisen, bis die erste Phase der Initialisierung abgeschlossen ist.

- Die Programmiersprache Swift - Initialisierung - Sicherheitsprüfung 4

Es scheint auch so, dass Sie nur sceneName und sceneDetail als Eigenschaften festlegen möchten, sodass Sie sie innerhalb des Bereichs der Methode, die Sie zum Auffüllen von sceneDetail und sceneName nach der Initialisierung verwenden, vollständig verschieben können.

Es ist schwer für mich zu sagen, was der Indexfehler ist genau , weil ich nicht sehe, welche Art von Daten detailVC.detailModal enthalten soll; Es scheint jedoch, dass der falsche Objekttyp an das Array detailModal übergeben wird. Eine gute kleine Beschreibung dieser Ausgabe ist Swift und Arrays

1
timeSmith