playgrounds - Cómo leer desde una aplicación de Swift 3 para iOS
swift para windows (7)
Aquí hay un ejemplo de cómo obtener BundleID de Info plist:
var appBundleID = "Unknown Bundle ID"
if let bundleDict = Bundle.main.infoDictionary,
let bundleID = bundleDict[kCFBundleIdentifierKey as String] as? String {
appBundleID = bundleID
}
De la misma manera que puede acceder fácilmente a cualquier clave. Este enfoque es bueno para muchos proyectos objetivo.
-Renuncia-
Soy extremadamente nuevo en el desarrollo de iOS y Swift, pero no soy particularmente nuevo en programación.
Tengo una aplicación básica de iOS
con elementos de Swift3
.
He creado un archivo plist
con algunas entradas que quiero leer y mostrar en mi aplicación. (No es necesario el acceso de escritura)
¿Cómo se puede leer un valor para una clave determinada para un archivo plist
incluido en Swift3?
Esto me parece una pregunta realmente simple, pero un montón de búsqueda me hace cuestionar todo mi enfoque conceptual.
Consejos útiles serían apreciados.
Aquí hay una implementación de Swift 3 , basada en share :
/// 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
}
Como Swift 4 introduce Codable
Paso 1: carga el archivo Plist del paquete.
Paso 2: use PropertyListDecoder para decodificar los valores de la lista de propiedades en tipos decodificables semánticos.
Paso 3: Crear estructura codificable
Código completo -
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)
}
}
Archivo Plist de muestra -> https://gist.github.com/janeshsutharios/4b0fb0e3edeff961d3e1f2829eb518db
De la misma manera que lo ha hecho en Swift 2.3 o inferior, solo se cambia la sintaxis.
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] {
}
}
Nota: En Swift, es mejor utilizar el tipo genérico Array and Dictionary de Swift en lugar de NSArray
y NSDictionary
.
Editar: en lugar de NSArray(contentsOfFile: path)
y NSDictionary(contentsOfFile:)
también podemos usar PropertyListSerialization.propertyList(from:)
para leer datos del archivo 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)
}
}
Para Swift 3.0, código siguiente directo a la clave. Donde como objeto dict dará todo lo que estará allí en su archivo 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
}
También puede leer el valor directamente desde su archivo plist simplemente
let value = Bundle.init(for: AppDelegate.self).infoDictionary?["your plist key name"] as? Any
En el archivo 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
}
En 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()
}
}
}