web-dev-qa-db-fra.com

Swift Plist Lecture et initialisation de tableaux en tant qu'objets pour une clé

Je développe une petite application basée sur UITableView- dans Swift. J'ai commencé à coder en dur certains tableaux de base en tant que tels (inclus la déclaration de classe de base et la déclaration UITableView outlet:

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"]

Ce code se trouve dans une UITableViewController qui a un point de vente relié à une UITableView. J'ai créé un plist appelé "Scenes.plist" et tenté de remplacer le code. En Objective-C, je ferais ceci:

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

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

J'ai commencé à faire ceci dans Swift comme ceci:

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

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

J'ai parcouru Internet à la recherche d'une solution, mais je n'ai pas réussi à en trouver une. J'ai donc pris la ligne de conduite suivante: un «presque» one-liner:

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

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

Maintenant, la seule solution à laquelle je peux presque avoir recours est d'avoir tout cela sur une seule ligne pour chaque tableau:

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! = ...)

J'ai donc ajouté l'annotation de type explicite uniquement pour découvrir qu'il y avait plus d'erreurs. Dans la fonction cellForRowAtIndexPath::

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
}

Il y a en fait deux erreurs ; Je ne sais pas si c'est dupliqué accidentellement ou non. Les erreurs suivantes sont dans la méthode prepareForSegue:sender::

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
    }
}

Encore une fois, il y a deux erreurs; Cependant, je pense que c'est parce que sceneDetail et sceneName sont tous deux utilisés. Il semble y avoir des erreurs partout avec la lecture et l'utilisation de plists dans des fichiers qui ne sont pas présents (ou que je n'ai pas rencontrés) dans Objective-C.

Merci d'avance,

-KodInc

13
KodInc

Pour résoudre votre problème initial, placez le code dans une fonction, telle que:

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

Vous pouvez résoudre ce problème en déplaçant votre code dans une fonction appelée après l'initialisation de vos objets.

Les propriétés sont initialisées dans le cadre de l'initialisation de votre objet. Vous avez créé path et dict en tant que propriétés et vous essayez de les initialiser avec un code qui ne répond pas aux exigences d’initialisation.

Un initialiseur ne peut appeler aucune méthode d'instance, ne lit Les valeurs d'aucune propriété d'instance, ni se réfère à self en tant que valeur Avant la fin de la première phase d'initialisation.

- Le langage de programmation Swift - Initialisation - Contrôle de sécurité 4

En outre, il semble que vous souhaitiez uniquement que sceneName et sceneDetail soient des propriétés, afin que vous puissiez les déplacer complètement dans le cadre de la méthode utilisée pour renseigner sceneDetail et sceneName après l'initialisation.

Il m'est difficile de dire quelle est l'erreur en indice exactement parce que je ne vois pas quel type de données detailVC.detailModal est supposé contenir; même dans ce cas, il semble que le type d'objet incorrect soit passé dans le tableau detailModal. Une bonne petite description de ce problème est Swift and arrays

1
timeSmith