web-dev-qa-db-ja.com

Swift 3 iOSアプリを使用してplistから読み取る方法

-免責事項-
iOSとSwiftの開発は非常に新しいですが、プログラミングは特に新しいものではありません。

Swift3要素を含む基本的なiOSアプリケーションがあります。
アプリケーションで読み取り、表示したいエントリを含むplistファイルを作成しました。 (書き込みアクセスは不要です)

Swift3でバンドルされているplistファイルの特定のキーの値をどのように読み取ることができますか?

これは私には本当に単純な質問のように思えますが、たくさんの検索をすることで、概念的なアプローチ全体に疑問を抱かせています。

役に立つヒントをいただければ幸いです。

29
James T Snell

Swift 2.3以下で行ったのと同じ方法で構文が変更されます。

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

    }
}

注:Swiftでは、NSArrayおよびNSDictionaryの代わりにSwiftのジェネリック型の配列と辞書を使用することをお勧めします。

編集:NSArray(contentsOfFile: path)およびNSDictionary(contentsOfFile:)の代わりに PropertyListSerialization.propertyList(from:) を使用して、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)
       }
}
70
Nirav D

Swift 4はCodableを導入するため

ステップ1:バンドルからPlistファイルをロードします

ステップ2:PropertyListDecoderを使用して、プロパティリスト値をセマンティックDecodableタイプにデコードします。

ステップ3:コード化可能な構造体を作成する

完全なコード-

 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)

    }
}

サンプルPlistファイル-> https://Gist.github.com/janeshsutharios/4b0fb0e3edeff961d3e1f2829eb518db

9
Jack

以下は、Info plistからBundleIDを取得する方法の例です。

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

同じ方法で、任意のキーに簡単にアクセスできます。このアプローチは、多くのターゲットプロジェクトに適しています。

2

Nirav D's answer に基づいたSwift 3の実装です。

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

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
    }

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
Amul4608

また、単にplistファイルから値を直接読み取ることもできます。

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

Swift 3.0の場合、キーを直接ターゲットとするコードに従う。 dict objectは、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