web-dev-qa-db-fra.com

Comment lire depuis un plist avec l'application Swift 3 iOS

-Avertissement-
Je suis extrêmement novice en développement iOS et Swift, mais je ne suis pas particulièrement novice en programmation.
 

J'ai une application iOS de base avec des éléments Swift3.
J'ai créé un fichier plist avec certaines entrées que je veux lire et afficher dans mon application. (Aucun accès en écriture n'est nécessaire)

Comment pouvez-vous lire une valeur pour une clé donnée pour un fichier plist intégré, dans Swift3?

Cela me semble une question très simple, mais une série de recherches me fait remettre en question toute mon approche conceptuelle.

Des conseils utiles seraient appréciés.

27
James T Snell

De la même manière que vous l'avez fait dans Swift 2.3 ou une version antérieure inférieure, la syntaxe est modifiée.

if let path = Bundle.main.path(forResource: "fileName", ofType: "plist") {

    //If your plist contain root as Array
    if let array = NSArray(contentsOfFile: path) as? [[String: Any]] {

    }

    ////If your plist contain root as Dictionary
    if let dic = NSDictionary(contentsOfFile: path) as? [String: Any] {

    }
}

Remarque: Dans Swift, il est préférable d'utiliser le type générique Array and Dictionary de Swift au lieu de NSArray et NSDictionary

Edit: Au lieu de NSArray(contentsOfFile: path) et NSDictionary(contentsOfFile:), nous pouvons également utiliser PropertyListSerialization.propertyList(from:) pour lire les données du fichier plist.

if let fileUrl = Bundle.main.url(forResource: "fileName", withExtension: "plist"),
   let data = try? Data(contentsOf: fileUrl) {
       if let result = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [[String: Any]] { // [String: Any] which ever it is 
            print(result)
       }
}
68
Nirav D

Comme Swift 4 introduit Codable

Étape 1: chargez le fichier Plist à partir du paquet.

Étape 2: Utilisez PropertyListDecoder pour le décodage des valeurs de liste de propriétés en types sémantiques Decodable.

Étape 3: Créer une structure codable 

Code complet -

 func setData() {
        // location of plist file
        if let settingsURL = Bundle.main.path(forResource: "JsonPlist", ofType: "plist") {

            do {
                var settings: MySettings?
                let data = try Data(contentsOf: URL(fileURLWithPath: settingsURL))
                    let decoder = PropertyListDecoder()
                settings = try decoder.decode(MySettings.self, from: data)
                    print("toolString is \(settings?.toolString ?? "")")
                print("DeviceDictionary is \(settings?.deviceDictionary?.phone ?? "")")
                print("RootPartArray is \(settings?.RootPartArray ?? [""])")

            } catch {
                print(error)
            }
        }
    }
}
struct MySettings: Codable {
    var toolString: String?
    var deviceDictionary: DeviceDictionary?
    var RootPartArray: [String]?

    private enum CodingKeys: String, CodingKey {
        case toolString = "ToolString"
        case deviceDictionary = "DeviceDictionary"
        case RootPartArray
    }

    struct DeviceDictionary: Codable {
        var phone: String?
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            phone = try values.decodeIfPresent(String.self, forKey: .phone)
        }
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        toolString = try values.decodeIfPresent(String.self, forKey: .toolString)
        deviceDictionary = try values.decodeIfPresent(DeviceDictionary.self, forKey: .deviceDictionary)
        RootPartArray = try values.decodeIfPresent([String].self, forKey: .RootPartArray)

    }
}

Exemple de fichier Plist -> https://Gist.github.com/janeshsutharios/4b0fb0e3edeff961d3e1f2829eb518db

8
Jack

Voici un exemple pour obtenir BundleID à partir de la pliste Info:

var appBundleID = "Unknown Bundle ID"    
if let bundleDict = Bundle.main.infoDictionary, 
   let bundleID = bundleDict[kCFBundleIdentifierKey as String] as? String {
       appBundleID = bundleID
   }

De la même manière, vous pouvez facilement accéder à n'importe quelle clé. Cette approche convient aux projets à objectifs multiples.

2
Eugene Martinson

Voici une implémentation de Swift 3, basée sur la réponse de Nirav D :

    /// Read Plist File.
    ///
    /// - Parameter fileURL: file URL.
    /// - Returns: return plist content.
    func ReadPlist(_ fileURL: URL) -> [String: Any]? {
        guard fileURL.pathExtension == FileExtension.plist, let data = try? Data(contentsOf: fileURL) else {
            return nil
        }
        guard let result = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any] else {
            return nil
        }
        print(result)
        return result
    }
2
Jerome

Dans le fichier AppDelegate

var bundlePath:String!
    var documentPath:String!
    var plistDocumentPath:URL!
    let fileManager = FileManager()


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        bundlePath = Bundle.main.path(forResource: "Team", ofType: "plist")

        documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first

        plistDocumentPath = URL.init(string: documentPath)?.appendingPathComponent("Team.plist")
        print(plistDocumentPath.path)

        if !fileManager.fileExists(atPath: plistDocumentPath.path){

            do {
                try fileManager.copyItem(atPath: bundlePath, toPath: plistDocumentPath.path)
            } catch  {
                print("error Occured \(error.localizedDescription)")
            }

        }


        return true
    }

Dans ViewController

 @IBOutlet weak var TeamTable: UITableView!
    var appDelegate:AppDelegate!
    var arrayForContacts:[[String:Any]]! // array object


    override func viewDidLoad() {
        super.viewDidLoad()




        appDelegate = UIApplication.shared.delegate as! AppDelegate


    }
    override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)

        if appDelegate.fileManager.fileExists(atPath: appDelegate.plistDocumentPath.path){
            arrayForContacts = []
            if let contentOfPlist = NSArray.init(contentsOfFile: appDelegate.plistDocumentPath.path ){
                arrayForContacts = contentOfPlist as! [[String:Any]]
                TeamTable.reloadData()
            }

        }
    }
0
Rob-4608

Vous pouvez également lire la valeur directement à partir de votre fichier plist simplement 

let value = Bundle.init(for: AppDelegate.self).infoDictionary?["your plist key name"] as? Any
0
Deepak Carpenter

Pour Swift 3.0, le code suivant est directement ciblé sur la clé. Où comme dict object donnera tout ce qui sera là dans votre fichier plist.

if let path = Bundle.main.path(forResource: "YourPlistFile", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
            let value = dict["KeyInYourPlistFile"] as! String
    }
0
FARAZ