मुझे स्विफ्ट में एक शब्दकोश के रूप में एक प्लिस्ट कैसे मिलता है?


197

मैं Apple के नए के साथ खेल रहा हूं स्विफ्ट प्रोग्रामिंग भाषा और कुछ समस्याएं हैं ...

वर्तमान में मैं एक plist फ़ाइल पढ़ने की कोशिश कर रहा हूँ, Objective-C में मैं एनएसडॉर के रूप में सामग्री प्राप्त करने के लिए निम्न कार्य करूँगा:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];

मुझे स्विफ्ट में एक शब्दकोश के रूप में एक प्लिस्ट कैसे मिलता है?

मुझे लगता है कि मैं प्लिस्ट के लिए रास्ता पा सकता हूं:

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

जब यह काम करता है (यदि यह सही है?): मुझे एक शब्दकोश के रूप में सामग्री कैसे मिलेगी?

और भी सामान्य प्रश्न:

क्या डिफ़ॉल्ट NS * वर्गों का उपयोग करना ठीक है ? मुझे ऐसा लगता है ... या मुझे कुछ याद आ रहा है? जहां तक ​​मुझे पता है कि डिफ़ॉल्ट ढांचा एनएस * कक्षाएं अभी भी मान्य हैं और उपयोग करने के लिए ठीक है?


उत्तर अब मान्य नहीं है, क्या आप अशोक के उत्तर का चयन कर सकते हैं?
रोडोल्फऑनटोनीसी

जवाबों:


51

में तेजी से 3.0 Plist से पढ़ना।

func readPropertyList() {
        var propertyListFormat =  PropertyListSerialization.PropertyListFormat.xml //Format of the Property List.
        var plistData: [String: AnyObject] = [:] //Our data
        let plistPath: String? = Bundle.main.path(forResource: "data", ofType: "plist")! //the path of the data
        let plistXML = FileManager.default.contents(atPath: plistPath!)!
        do {//convert the data to a dictionary and handle errors.
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as! [String:AnyObject]

        } catch {
            print("Error reading plist: \(error), format: \(propertyListFormat)")
        }
    }

स्विफ्ट में अधिक संपत्ति का उपयोग कैसे करें (.PLIST) का उपयोग करें


Askok। इस पर आज इसका जवाब खोजने की कोशिश में कई घंटे खो गए! धन्यवाद!! यह पूरी तरह से काम किया !!!
14:30 पर user3069232

282

आप अभी भी स्विफ्ट में NSD शब्दकोशों का उपयोग कर सकते हैं:

स्विफ्ट 4 के लिए

 var nsDictionary: NSDictionary?
 if let path = Bundle.main.path(forResource: "Config", ofType: "plist") {
    nsDictionary = NSDictionary(contentsOfFile: path)
 }

स्विफ्ट 3+ के लिए

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
   let myDict = NSDictionary(contentsOfFile: path){
    // Use your myDict here
}

और स्विफ्ट के पुराने संस्करण

var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
    myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
    // Use your dict here
}

NSClasses अभी भी उपलब्ध हैं और स्विफ्ट में उपयोग करने के लिए पूरी तरह से ठीक हैं। मुझे लगता है कि वे शायद ध्यान केंद्रित करना चाहते हैं कि जल्द ही स्विफ्ट पर ध्यान केंद्रित किया जा सके, लेकिन वर्तमान में स्विफ्ट एपीआई में कोर NSClasses की सभी कार्यक्षमता नहीं है।


हम्म जब मैं आपके द्वारा प्रदान किए गए उस कोड का उपयोग करने का प्रयास करता हूं, तो मुझे त्रुटि मिलती है: xxx में एक सदस्य का नाम नहीं है
KennyVB

यह खेल के मैदान में ठीक काम करता है। सिर्फ मेरे स्विफ्ट दस्तावेज़ में नहीं
केनीवीबी

अगर ऐरे की तरह यह कैसा दिखता है?
अर्नले विज्केनो

की तरह दिखता है mainBundle()तो बस है mainस्विफ्ट 3 में
BallpointBen

8
यह उत्तर पुराना है। यहां तक ​​कि स्विफ्ट 3 में आपको संपत्ति सूची डेटा पढ़ने के लिए बिल्कुल भी उपयोग नहीं करना चाहिएNSArray/NSDictionaryPropertyListSerialization(और स्विफ्ट 4 में वैकल्पिक रूप से Codableप्रोटोकॉल) उपयुक्त एपीआई है। यह आधुनिक त्रुटि हैंडलिंग प्रदान करता है और डेटा को मूल स्विफ्ट संग्रह प्रकारों में सीधे परिवर्तित किया जा सकता है।
vadian

141

यदि मैं एक स्विफ्ट शब्दकोश में .plist को परिवर्तित करना चाहता हूं तो यह क्या है:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
  if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
    // use swift dictionary as normal
  }
}

स्विफ्ट 2.0 के लिए संपादित:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
    // use swift dictionary as normal
}

स्विफ्ट 3.0 के लिए संपादित:

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
        // use swift dictionary as normal
}

3
मुझे लगता है कि यह गुच्छा का "सबसे सही" उत्तर है जब तक कि ऐसा करने के लिए एक देशी तेज तरीका नहीं है।
ड्यूडेऑनॉक

1
यह उत्तर पुराना है। स्विफ्ट 3 में आपको संपत्ति सूची डेटा पढ़ने के लिए बिल्कुल भी उपयोग नहीं करना चाहिएNSArray/NSDictionaryPropertyListSerialization(और स्विफ्ट 4 में वैकल्पिक रूप से Codableप्रोटोकॉल) उपयुक्त एपीआई है। यह आधुनिक त्रुटि हैंडलिंग प्रदान करता है और डेटा को मूल स्विफ्ट संग्रह प्रकारों में सीधे परिवर्तित किया जा सकता है।
वाडियन

47

स्विफ्ट 4.0

अब आप किसी कस्टम संरचना में .plist को डिकोड करने के लिए डीकोडेबल प्रोटोकॉल का उपयोग कर सकते हैं। मैं एक अधिक जटिल उदाहरण के लिए जाऊंगा। अधिक जटिल .plist संरचनाओं के लिए मैं Decodable / Encodable (एक अच्छा संसाधन यहाँ पर पढ़ने की सलाह देता हूं: https://benscheirman.com/2017/06/swift-json/ ) ।

पहले अपनी संरचना को अपने .plist फ़ाइल के प्रारूप में सेट करें। इस उदाहरण के लिए, मैं एक मूल स्तर के शब्दकोश और 3 प्रविष्टियों के साथ एक .plist पर विचार करूंगा: 1 कुंजी "नाम" के साथ स्ट्रिंग, 1 "कुंजी" उम्र के साथ 1 इंट, और कुंजी "एकल" के साथ 1 बुलियन। यहाँ संरचना है:

struct Config: Decodable {
    private enum CodingKeys: String, CodingKey {
        case name, age, single
    }

    let name: String
    let age: Int
    let single: Bool
}

काफी सरल। अब शांत भाग। PropertyListDecoder वर्ग का उपयोग करके हम आसानी से .plist फ़ाइल को इस संरचना की तात्कालिकता में पार्स कर सकते हैं:

func parseConfig() -> Config {
    let url = Bundle.main.url(forResource: "Config", withExtension: "plist")!
    let data = try! Data(contentsOf: url)
    let decoder = PropertyListDecoder()
    return try! decoder.decode(Config.self, from: data)
}

चिंता करने के लिए और अधिक कोड नहीं है, और स्विफ्ट में इसके सभी। बेहतर अभी तक हम विन्यास संरचना का एक तात्कालिकता है जिसे हम आसानी से उपयोग कर सकते हैं:

let config = parseConfig()
print(config.name) 
print(config.age)
print(config.single) 

यह "नाम", "आयु" और "एकल" कुंजी के लिए .plist में प्रिंट करता है।


1
यह स्विफ्ट 4 के लिए सबसे अच्छा जवाब है। लेकिन क्यों नहीं Bundle.main.url(forResource: "Config", withExtension: "plist")और इससे छुटकारा पाएं URL(fileURLWithPath? और जैसा कि फ़ाइल मौजूद होना आवश्यक है (डिज़ाइन / संकलन समय पर) सभी मानों को अपरिवर्तित किया जा सकता है। यदि सब कुछ ठीक से डिज़ाइन किया गया हो तो कोड क्रैश नहीं होना चाहिए।

@vadian यकीन है कि आप उपयोग कर सकते हैं url(forResource: "Config", withExtension: "plist")मैं सिर्फ मिलान कर रहा था कि ओपी ने अपने कोड में तुलना के बिंदु के रूप में क्या किया। जहां तक ​​सब कुछ करने के लिए मजबूर करने की बात है, मैं सावधानी बरतने की कोशिश करता हूं। मुझे लगता है कि सामान्य तौर पर स्विफ्ट के लिए यह एक मौलिक प्रश्न है। मैं वास्तव में यह जानना चाहता हूं कि दुर्घटना की तुलना में मेरा कोड किसी भी स्थिति में क्या करेगा।
इकरेलोफ

1) अधिक उपयुक्त एपीआई होने पर कृपया बुरी आदतों को न अपनाएं। 2) यह उन कुछ मामलों में से एक है जहां एक मजबूर दुर्घटना एक डिजाइन त्रुटि का पता लगाती है। बंडल में किसी भी फाइल को संकलित समय पर मौजूद होना आवश्यक है और रनटाइम में परिवर्तित नहीं किया जा सकता क्योंकि सभी फाइलें कोड-हस्ताक्षरित हैं। एक बार फिर: यदि सब कुछ ठीक से डिज़ाइन किया गया है तो कोड को क्रैश नहीं होना चाहिए
vadian

हाँ, आप अपना अधिकार जानते हैं। बंडल संसाधनों के साथ मामला था कि एहसास नहीं था।
इकरेलॉफ

2
@NaveenGeorgeThoppan यदि आप इस उदाहरण का उपयोग अपने शब्दकोश के रूप में करते हैं तो यह बस होगा decoder.decode([Config].self, from: data)। ([कोष्ठक के चारों ओर कोष्ठक देखें)
ekreloff

22

यह उत्तर स्विफ्ट नेटिव ऑब्जेक्ट्स का उपयोग करता है, बजाय एनएसडाउडर के।

स्विफ्ट 3.0

//get the path of the plist file
guard let plistPath = Bundle.main.path(forResource: "level1", ofType: "plist") else { return }
//load the plist as data in memory
guard let plistData = FileManager.default.contents(atPath: plistPath) else { return }
//use the format of a property list (xml)
var format = PropertyListSerialization.PropertyListFormat.xml
//convert the plist data to a Swift Dictionary
guard let  plistDict = try! PropertyListSerialization.propertyList(from: plistData, options: .mutableContainersAndLeaves, format: &format) as? [String : AnyObject] else { return }
//access the values in the dictionary 
if let value = plistDict["aKey"] as? String {
  //do something with your value
  print(value)
}
//you can also use the coalesce operator to handle possible nil values
var myValue = plistDict["aKey"] ?? ""

क्या इसका कोई संक्षिप्त संस्करण है?
harsh_v

18

मैं स्विफ्ट 3.0 के साथ काम कर रहा हूं और अपडेटेड सिंटैक्स के लिए एक उत्तर देना चाहता हूं। इसके अतिरिक्त, और संभवतः अधिक महत्वपूर्ण बात यह है कि मैं प्रॉपर्टी लिस्ट्रलाइज़ेशन का उपयोग कर रहा हूं हेवी लिफ्टिंग करने के लिए ऑब्जेक्ट , जो कि एनएसबर्ड का उपयोग करने की तुलना में बहुत अधिक लचीला है, क्योंकि यह एक प्रकार के लिए मूल के रूप में एरे के लिए अनुमति देता है।

नीचे मैं उपयोग किए जा रहे प्लास्ट का स्क्रीनशॉट है। यह थोड़ा जटिल है, इसलिए उपलब्ध शक्ति को दिखाने के लिए, लेकिन यह किसी भी प्रकार के प्लस्ट प्रकार के स्वीकार्य संयोजन के लिए काम करेगा।

नमूना plist फ़ाइल जैसा कि आप देख सकते हैं कि मैं एक ऐरे ऑफ स्ट्रिंग का उपयोग कर रहा हूं: वेबसाइट के नामों की सूची और उनके संबंधित URL को संग्रहीत करने के लिए स्ट्रिंग शब्दकोश।

मैं PropertyListSerialization ऑब्जेक्ट का उपयोग कर रहा हूं , जैसा कि ऊपर उल्लेख किया गया है, मेरे लिए भारी उठाने के लिए। इसके अतिरिक्त, स्विफ्ट 3.0 अधिक "स्विफ्टी" बन गई है, इसलिए सभी ऑब्जेक्ट नामों ने "एनएस" उपसर्ग खो दिया है।

let path = Bundle.main().pathForResource("DefaultSiteList", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)

उपर्युक्त कोड रन plistके प्रकार के होंगे Array<AnyObject>, लेकिन हम जानते हैं कि यह वास्तव में किस प्रकार का है इसलिए हम इसे सही प्रकार में डाल सकते हैं:

let dictArray = plist as! [[String:String]]
// [[String:String]] is equivalent to Array< Dictionary<String, String> >

और अब हम अपने Arring of String के विभिन्न गुणों तक पहुँच सकते हैं: String डॉक्स एक प्राकृतिक तरीके से। उम्मीद है कि उन्हें वास्तविक रूप से टाइप किए गए ढांचे या कक्षाओं में परिवर्तित करें;)

print(dictArray[0]["Name"])

8

देशी शब्दकोशों और सरणियों का उपयोग करना सबसे अच्छा है क्योंकि वे स्विफ्ट के साथ उपयोग के लिए अनुकूलित किए गए हैं। कहा जा रहा है कि आप NS ... वर्गों का तेजी से उपयोग कर सकते हैं और मुझे लगता है कि यह स्थिति वारंट है। यहां बताया गया है कि आप इसे कैसे लागू करेंगे:

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

अब तक (मेरी राय में) यह एक प्लिस्ट तक पहुंचने का सबसे आसान और सबसे कुशल तरीका है, लेकिन भविष्य में मुझे उम्मीद है कि ऐप्पल देशी शब्दकोशों में अधिक कार्यक्षमता (जैसे कि प्लिस्ट का उपयोग करना) जोड़ देगा।


जहाँ तक आप जानते हैं, देशी शब्दकोशों में प्लिस्ट रीडिंग जोड़ना पहले से ही हुआ है?
SpacyRicochet

8

स्विफ्ट - पढ़ें और लिखो plist और पाठ फ़ाइल ....

override func viewDidLoad() {
    super.viewDidLoad()

    let fileManager = (NSFileManager .defaultManager())
    let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

    if (directorys != nil){
        let directories:[String] = directorys!;
        let dictionary = directories[0]; //documents directory


        //  Create and insert the data into the Plist file  ....
        let plistfile = "myPlist.plist"
        var myDictionary: NSMutableDictionary = ["Content": "This is a sample Plist file ........."]
        let plistpath = dictionary.stringByAppendingPathComponent(plistfile);

        if !fileManager .fileExistsAtPath(plistpath){//writing Plist file
            myDictionary.writeToFile(plistpath, atomically: false)
        }
        else{            //Reading Plist file
            println("Plist file found")

            let resultDictionary = NSMutableDictionary(contentsOfFile: plistpath)
            println(resultDictionary?.description)
        }


        //  Create and insert the data into the Text file  ....
        let textfile = "myText.txt"
        let sampleText = "This is a sample text file ......... "

        let textpath = dictionary.stringByAppendingPathComponent(textfile);
        if !fileManager .fileExistsAtPath(textpath){//writing text file
            sampleText.writeToFile(textpath, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
        } else{
            //Reading text file
            let reulttext  = String(contentsOfFile: textpath, encoding: NSUTF8StringEncoding, error: nil)
            println(reulttext)
        }
    }
    else {
        println("directory is empty")
    }
}

8

स्विफ्ट 2.0: एक्सेस करने की जानकारी।लिस्ट

InfoPlist में एक बूलियन मान के साथ मेरे पास एक कोच है जिसका नाम CoachMarksprise है। मैं बूल मूल्य का उपयोग करना चाहता हूं और इसे सच करना चाहता हूं।

let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  if let CoachMarksDict = dict["CoachMarksDictionary"] {
       print("Info.plist : \(CoachMarksDict)")

   var dashC = CoachMarksDict["DashBoardCompleted"] as! Bool
    print("DashBoardCompleted state :\(dashC) ")
  }

प्लिस्ट के लिए लेखन:

एक कस्टम प्लास्ट से: - (फाइल-न्यू-फाइल-रिसोर्स-प्रॉपर्टीलिस्ट से बनाएं। जोड़े गए तीन स्ट्रिंग्स नाम: DashBoard_New, DashBoard_Draft, DashBoard_Completed)

func writeToCoachMarksPlist(status:String?,keyName:String?)
 {
  let path1 = NSBundle.mainBundle().pathForResource("CoachMarks", ofType: "plist")
  let coachMarksDICT = NSMutableDictionary(contentsOfFile: path1!)! as NSMutableDictionary
  var coachMarksMine = coachMarksDICT.objectForKey(keyName!)

  coachMarksMine  = status
  coachMarksDICT.setValue(status, forKey: keyName!)
  coachMarksDICT.writeToFile(path1!, atomically: true)
 }

विधि के रूप में कहा जा सकता है

self.writeToCoachMarksPlist(" true - means user has checked the marks",keyName: "the key in the CoachMarks dictionary").

यह वही है जो मैं बाहर देख रहा था! धन्यवाद दोस्त!
जयप्रकाश दुबे

6

निक के जवाब के माध्यम से एक सुविधा विस्तार में परिवर्तित:

extension Dictionary {
    static func contentsOf(path: URL) -> Dictionary<String, AnyObject> {
        let data = try! Data(contentsOf: path)
        let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)

        return plist as! [String: AnyObject]
    }
}

उपयोग:

let path = Bundle.main.path(forResource: "plistName", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let dict = Dictionary<String, AnyObject>.contentsOf(path: url)

मैं शर्त लगाने के लिए तैयार हूँ कि यह ऐरे के लिए एक समान एक्सटेंशन बनाने के लिए भी काम करेगा


5

वास्तव में 1 लाइन में कर सकते हैं

    var dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Config", ofType: "plist"))

5

आप इस तरह स्विफ्ट लैंग्वेज में प्लिस्ट पढ़ सकते हैं:

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

एकल शब्दकोश मूल्य पढ़ें:

let test: AnyObject = dict.objectForKey("index1")

यदि आप प्लिस्ट में पूर्ण बहुआयामी शब्दकोश प्राप्त करना चाहते हैं:

let value: AnyObject = dict.objectForKey("index2").objectForKey("date")

यहाँ है:

<plist version="1.0">
<dict>
<key>index2</key>
<dict>
    <key>date</key>
    <string>20140610</string>
    <key>amount</key>
    <string>110</string>
</dict>
<key>index1</key>
<dict>
    <key>amount</key>
    <string>125</string>
    <key>date</key>
    <string>20140212</string>
</dict>
</dict>
</plist>

5

चूँकि यह उत्तर अभी तक यहाँ नहीं है, बस इस ओर इशारा करना चाहता हूँ कि आप एक जानकारी को डिक्शनरी के रूप में इस्तेमाल कर सकते हैं ताकि जानकारी को डिक्शनरी के रूप में प्राप्त किया जा सके Bundle.main.infoDictionary

हालाँकि ऐसा कुछ और तेजी से Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) हो सकता है यदि आप केवल एक विशेष वस्तु में रुचि रखते हैं, जो जानकारी के लिए आवश्यक है।

// Swift 4

// Getting info plist as a dictionary
let dictionary = Bundle.main.infoDictionary

// Getting the app display name from the info plist
Bundle.main.infoDictionary?[kCFBundleNameKey as String]

// Getting the app display name from the info plist (another way)
Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String)

3

मेरे मामले में मैं एक NSDictionaryबुलाया बनाने के लिए appSettingsऔर सभी आवश्यक चाबियाँ जोड़ें। इस मामले के लिए, समाधान है:

if let dict = NSBundle.mainBundle().objectForInfoDictionaryKey("appSettings") {
  if let configAppToken = dict["myKeyInsideAppSettings"] as? String {

  }
}

धन्यवाद। objectForInfoDictionaryKeyवास्तव में मैं क्या देख रहा था।
लूनाकोडगर्ल

2

आप इसका उपयोग कर सकते हैं, मैं github में शब्दकोश के लिए एक सरल एक्सटेंशन https://github.com/DaRkD0G/LoadExtension बना सकता हूं

extension Dictionary {
    /**
        Load a Plist file from the app bundle into a new dictionary

        :param: File name
        :return: Dictionary<String, AnyObject>?
    */
    static func loadPlistFromProject(filename: String) -> Dictionary<String, AnyObject>? {

        if let path = NSBundle.mainBundle().pathForResource("GameParam", ofType: "plist") {
            return NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject>
        }
        println("Could not find file: \(filename)")
        return nil
    }
}

और आप इसे लोड के लिए उपयोग कर सकते हैं

/**
  Example function for load Files Plist

  :param: Name File Plist
*/
func loadPlist(filename: String) -> ExampleClass? {
    if let dictionary = Dictionary<String, AnyObject>.loadPlistFromProject(filename) {
        let stringValue = (dictionary["name"] as NSString)
        let intergerValue = (dictionary["score"] as NSString).integerValue
        let doubleValue = (dictionary["transition"] as NSString).doubleValue

        return ExampleClass(stringValue: stringValue, intergerValue: intergerValue, doubleValue: doubleValue)
    }
    return nil
}

2

यहाँ थोड़ा सा संस्करण है, जो @connor के उत्तर पर आधारित है

guard let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
    let myDict = NSDictionary(contentsOfFile: path) else {
    return nil
}

let value = dict.value(forKey: "CLIENT_ID") as! String?

2

स्विफ्ट 3.0

if let path = Bundle.main.path(forResource: "config", ofType: "plist") {
    let dict = NSDictionary(contentsOfFile: path)

    // use dictionary
}

मेरी राय में ऐसा करने का सबसे आसान तरीका।


2

मैंने एक साधारण Dictionaryइनिशियलाइज़र बनाया है जो रिप्लेस करता है NSDictionary(contentsOfFile: path)। बस हटा दो NS

extension Dictionary where Key == String, Value == Any {

    public init?(contentsOfFile path: String) {
        let url = URL(fileURLWithPath: path)

        self.init(contentsOfURL: url)
    }

    public init?(contentsOfURL url: URL) {
        guard let data = try? Data(contentsOf: url),
            let dictionary = (try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any]) ?? nil
            else { return nil }

        self = dictionary
    }

}

आप इसे इस तरह से उपयोग कर सकते हैं:

let filePath = Bundle.main.path(forResource: "Preferences", ofType: "plist")!
let preferences = Dictionary(contentsOfFile: filePath)!
UserDefaults.standard.register(defaults: preferences)

2

ऊपर दिए गए https://stackoverflow.com/users/3647770/ashok-r उत्तर के आधार पर 4.0 iOS 11.2.6 सूची को पार्स किया गया और इसे पार्स करने के लिए कोड ।

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
  <dict>
    <key>identity</key>
    <string>blah-1</string>
    <key>major</key>
    <string>1</string>
    <key>minor</key>
    <string>1</string>
    <key>uuid</key>
    <string>f45321</string>
    <key>web</key>
    <string>http://web</string>
</dict>
<dict>
    <key>identity</key>
    <string></string>
    <key>major</key>
    <string></string>
    <key>minor</key>
    <string></string>
    <key>uuid</key>
    <string></string>
    <key>web</key>
    <string></string>
  </dict>
</array>
</plist>

do {
   let plistXML = try Data(contentsOf: url)
    var plistData: [[String: AnyObject]] = [[:]]
    var propertyListFormat =  PropertyListSerialization.PropertyListFormat.xml
        do {
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as! [[String:AnyObject]]

        } catch {
            print("Error reading plist: \(error), format: \(propertyListFormat)")
        }
    } catch {
        print("error no upload")
    }

1

चरण 1 : तेज 3+ में प्लिस्ट को पार्स करने का सरल और सबसे तेज़ तरीका

extension Bundle {

    func parsePlist(ofName name: String) -> [String: AnyObject]? {

        // check if plist data available
        guard let plistURL = Bundle.main.url(forResource: name, withExtension: "plist"),
            let data = try? Data(contentsOf: plistURL)
            else {
                return nil
        }

        // parse plist into [String: Anyobject]
        guard let plistDictionary = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: AnyObject] else {
            return nil
        }

        return plistDictionary
    }
}

चरण 2: कैसे उपयोग करें:

Bundle().parsePlist(ofName: "Your-Plist-Name")

0

यहां मैंने जो समाधान पाया है:

let levelBlocks = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("LevelBlocks", ofType: "plist"))
let test: AnyObject = levelBlocks.objectForKey("Level1")
println(test) // Prints the value of test

मैंने अनपेक्षित आक्षेप के बारे में एक चेतावनी को चुप testकरने के AnyObjectलिए टाइप किया ।

साथ ही, इसे क्लास विधि से करना होगा।

किसी ज्ञात प्रकार के विशिष्ट मान को एक्सेस करने और सहेजने के लिए:

let value = levelBlocks.objectForKey("Level1").objectForKey("amount") as Int
println(toString(value)) // Converts value to String and prints it

0

मैं स्विफ्ट शब्दकोशों का उपयोग करता हूं, लेकिन उन्हें अपनी फ़ाइल प्रबंधक कक्षा में NSD शब्दकोशों से इस तरह परिवर्तित करता हूं:

    func writePlist(fileName:String, myDict:Dictionary<String, AnyObject>){
        let docsDir:String = dirPaths[0] as String
        let docPath = docsDir + "/" + fileName
        let thisDict = myDict as NSDictionary
        if(thisDict.writeToFile(docPath, atomically: true)){
            NSLog("success")
        } else {
            NSLog("failure")
        }

    }
    func getPlist(fileName:String)->Dictionary<String, AnyObject>{
        let docsDir:String = dirPaths[0] as String
        let docPath = docsDir + "/" + fileName
        let thisDict = NSDictionary(contentsOfFile: docPath)
        return thisDict! as! Dictionary<String, AnyObject>
    }

यह पढ़ने और लिखने के लिए सबसे कम परेशान करने वाला तरीका लगता है लेकिन आइए मेरे बाकी कोड जितना संभव हो उतना तेज रहें।


0

Plist एक साधारण स्विफ्ट Enum है जिसे मैंने संपत्ति सूचियों के साथ काम करने के लिए बनाया है।

// load an applications info.plist data

let info = Plist(NSBundle.mainBundle().infoDictionary)
let identifier = info["CFBundleIndentifier"].string!

और ज्यादा उदाहरण:

import Plist

// initialize using an NSDictionary
// and retrieve keyed values

let info = Plist(dict)
let name = info["name"].string ?? ""
let age = info["age"].int ?? 0


// initialize using an NSArray
// and retrieve indexed values

let info = Plist(array)
let itemAtIndex0 = info[0].value


// utility initiaizer to load a plist file at specified path
let info = Plist(path: "path_to_plist_file")

// we support index chaining - you can get to a dictionary from an array via
// a dictionary and so on
// don't worry, the following will not fail with errors in case
// the index path is invalid
if let complicatedAccessOfSomeStringValueOfInterest = info["dictKey"][10]["anotherKey"].string {
  // do something
}
else {
  // data cannot be indexed
}

// you can also re-use parts of a plist data structure

let info = Plist(...)
let firstSection = info["Sections"][0]["SectionData"]
let sectionKey = firstSection["key"].string!
let sectionSecret = firstSection["secret"].int!

Plist.swift

प्लास्ट अपने आप में काफी सरल है, यहां इसकी सूची है कि आप सीधे संदर्भ दें।

//
//  Plist.swift
//


import Foundation


public enum Plist {

    case dictionary(NSDictionary)
    case Array(NSArray)
    case Value(Any)
    case none

    public init(_ dict: NSDictionary) {
        self = .dictionary(dict)
    }

    public init(_ array: NSArray) {
        self = .Array(array)
    }

    public init(_ value: Any?) {
        self = Plist.wrap(value)
    }

}


// MARK:- initialize from a path

extension Plist {

    public init(path: String) {
        if let dict = NSDictionary(contentsOfFile: path) {
            self = .dictionary(dict)
        }
        else if let array = NSArray(contentsOfFile: path) {
            self = .Array(array)
        }
        else {
            self = .none
        }
    }

}


// MARK:- private helpers

extension Plist {

    /// wraps a given object to a Plist
    fileprivate static func wrap(_ object: Any?) -> Plist {

        if let dict = object as? NSDictionary {
            return .dictionary(dict)
        }
        if let array = object as? NSArray {
            return .Array(array)
        }
        if let value = object {
            return .Value(value)
        }
        return .none
    }

    /// tries to cast to an optional T
    fileprivate func cast<T>() -> T? {
        switch self {
        case let .Value(value):
            return value as? T
        default:
            return nil
        }
    }
}

// MARK:- subscripting

extension Plist {

    /// index a dictionary
    public subscript(key: String) -> Plist {
        switch self {

        case let .dictionary(dict):
            let v = dict.object(forKey: key)
            return Plist.wrap(v)

        default:
            return .none
        }
    }

    /// index an array
    public subscript(index: Int) -> Plist {
        switch self {
        case let .Array(array):
            if index >= 0 && index < array.count {
                return Plist.wrap(array[index])
            }
            return .none

        default:
            return .none
        }
    }

}


// MARK:- Value extraction

extension Plist {

    public var string: String?       { return cast() }
    public var int: Int?             { return cast() }
    public var double: Double?       { return cast() }
    public var float: Float?         { return cast() }
    public var date: Date?         { return cast() }
    public var data: Data?         { return cast() }
    public var number: NSNumber?     { return cast() }
    public var bool: Bool?           { return cast() }


    // unwraps and returns the underlying value
    public var value: Any? {
        switch self {
        case let .Value(value):
            return value
        case let .dictionary(dict):
            return dict
        case let .Array(array):
            return array
        case .none:
            return nil
        }
    }

    // returns the underlying array
    public var array: NSArray? {
        switch self {
        case let .Array(array):
            return array
        default:
            return nil
        }
    }

    // returns the underlying dictionary
    public var dict: NSDictionary? {
        switch self {
        case let .dictionary(dict):
            return dict
        default:
            return nil
        }
    }

}


// MARK:- CustomStringConvertible

extension Plist : CustomStringConvertible {
    public var description:String {
        switch self {
        case let .Array(array): return "(array \(array))"
        case let .dictionary(dict): return "(dict \(dict))"
        case let .Value(value): return "(value \(value))"
        case .none: return "(none)"
        }
    }
}

0

स्विफ्ट 3.0

यदि आप .plist से "2-आयामी ऐरे" पढ़ना चाहते हैं, तो आप इसे इस तरह आज़मा सकते हैं:

if let path = Bundle.main.path(forResource: "Info", ofType: "plist") {
    if let dimension1 = NSDictionary(contentsOfFile: path) {
        if let dimension2 = dimension1["key"] as? [String] {
            destination_array = dimension2
        }
    }
}

-2

सरलीकृत फ़ाइल तक पहुँचने के लिए सरल संरचना (स्विफ्ट 2.0)

struct Configuration {      
  static let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  static let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  static let someValue = dict["someKey"] as! String
}

उपयोग:

print("someValue = \(Configuration.someValue)")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.