2016-03-27 24 views
5

設定バンドルを自分のアプリケーションに追加しました.Xcodeでは、プロジェクトツリービューのルートに表示されます。設定バンドルの値がnilを返す

Root.plistファイルは次のようになります。私は、iOSの設定アプリを開くと

<?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"> 
<dict> 
    <key>StringsTable</key> 
    <string>Root</string> 
    <key>PreferenceSpecifiers</key> 
    <array> 
     <dict> 
      <key>Type</key> 
      <string>PSGroupSpecifier</string> 
      <key>Title</key> 
      <string>Service</string> 
     </dict> 
     <dict> 
      <key>Type</key> 
      <string>PSTextFieldSpecifier</string> 
      <key>Title</key> 
      <string>Hostname</string> 
      <key>Key</key> 
      <string>service_hostname</string> 
    <!-- and so on --> 

エントリが下部に表示されて、私は完全に罰金私の設定を表示し、編集することができます。

ただし、コードからこれらの値を取得することはできません。ここに私のコードです:私もud.objectForKeyud.valueForKeyを試してみました

static func loadSettings() { 

    let ud = NSUserDefaults.standardUserDefaults() 
    ud.synchronize() 

    Settings.hostName = ud.stringForKey("service_hostname") 
    // etc 
} 

- の両方が同様にnilを返します。

Settings.hostNameを設定した後、Xcodeデバッガは、設定アプリで明示的な値を設定しても、nilの値を報告します。

私は、誰かが手動でNSMutableDictionaryに直接Root.plistファイルをロードし、NSUserDefaults.standardUserDefaults().registerDefaultsを呼び出すObjective-Cのコードの塊を投稿が、それはハックのように思える(と私はそれを動作させることはできません。このスレッド(iPhone App : How to get default value from root.plist?)を見ましたコンパイラはstringByAppendingPathComponentがもう存在しないと言っているので、Swiftで)

なぜ、NSUserDefaultsが設定アプリケーションから設定を取得していないのですか?

答えて

7

plistの設定にデフォルトが定義されていて、ユーザーが明示的に値を設定していない場合、設定アプリに表示される値はplistファイルのデフォルトになりますが、NSUserDefaults APIはまだnilを返します。それは私のプロジェクトで二回存在している必要があります:plistで、私のプログラムコードのデフォルトとして:

は、残念ながら、これはデフォルト値は(「http://www.example.com」などのデフォルトのWebサービスのアドレスURIとして)意味がある場合ことを意味し

Root.plist:

​​

Program.swift:

let ud = NSUserDefaults.standardUserDefaults() 
ud.synchronize() 

var mySettingValue = ud.stringForKey("mySettingKey") 
if mySettingValue == nil { 
    mySettingValue = "http://www.example.com" 
} 

驚きです。

+0

私は狂っていたと思います。長い間ソリューションを探しました!なぜこうなった?知っている人はいますか? –

+0

@Daiこれは私のために働かない、それは無価値を与える..私は何かが不足している? – mm24

+0

@ mm24 "それは無価値を与えます" - これは私の投稿についてのもので、なぜソリューションがゼロ値をチェックしてコードのデフォルト値を提供するのかです。 – Dai

7

デフォルトを登録して同期させる必要があります。 source from here

// Swift 3 
var appDefaults = Dictionary<String, AnyObject>() 
appDefaults["mySettingKey"] = "http://www.example.com" // Default Value 

UserDefaults.standard.register(appDefaults) 
UserDefaults.standard.synchronize() 

let mySettingValue = UserDefaults.standard.string(forKey: "mySettingKey") 

あなたもregisterDefaultsを使用する必要がある点に注意してください:あなたのアプリが設定バンドルを使用する場合。設定バンドルのplistの中に既にデフォルト値を指定しているので、あなたのアプリが自動的にこれらの値を選択することを期待するかもしれません。しかし、そうではありません。設定バンドルに含まれる情報は、iOS Settings.appによってのみ読み取られ、アプリでは読み取られません。あなたのアプリがSettings.app内に示されているのと同じデフォルトを使用するようにするには、上記のようにユーザのデフォルトキーとデフォルト値を別々のplistファイルに手動でコピーしてデフォルトデータベースに登録する必要があります。

+0

興味深いことに、私が自分の値を登録して同期したときに、すぐに振り向いて値を照会しましたが、何も得られませんでした。代わりに古いスタイルの "setObject:forKey:"を実行しなければなりませんでした。 – BonanzaDriver

+0

ここで 'synchronize'を呼び出すのは無意味です。 1. 'register'を呼んでも実際に何も変更されないので、同期するものはありません。 2. 'synchronize'を呼び出すことは決して決して必要とされません。 – rmaddy

7

デフォルト値はSettings.bundleから取得し、UserDefaultsに追加できます。以下の関数は、AppDelegate.swiftの中でdidFinishLaunchingWithOptionsから呼び出すことができます。

func setDefaultsFromSettingsBundle() { 
    //Read PreferenceSpecifiers from Root.plist in Settings.Bundle 
    if let settingsURL = Bundle.main.url(forResource: "Root", withExtension: "plist", subdirectory: "Settings.bundle"), 
     let settingsPlist = NSDictionary(contentsOf: settingsURL), 
     let preferences = settingsPlist["PreferenceSpecifiers"] as? [NSDictionary] { 

     for prefSpecification in preferences { 

      if let key = prefSpecification["Key"] as? String, let value = prefSpecification["DefaultValue"] { 

       //If key doesn't exists in userDefaults then register it, else keep original value 
       if UserDefaults.standard.value(forKey: key) == nil { 

        UserDefaults.standard.set(value, forKey: key) 
        NSLog("registerDefaultsFromSettingsBundle: Set following to UserDefaults - (key: \(key), value: \(value), type: \(type(of: value)))") 
       } 
      } 
     } 
    } else { 
     NSLog("registerDefaultsFromSettingsBundle: Could not find Settings.bundle") 
    } 
} 
+0

ありがとう、Tomic、このコードは私が今必要なものです:) –

+0

ここでははるかに良い使用があります。 'preferences'を取得したら、' UserDefaults register'でそれを使います。それは、ループして各値を明示的に設定するよりもはるかに優れています。 – rmaddy

+0

@rmaddyここでは、UserDefaultsに特定のキーが既に含まれているかどうかを確認します。その場合は設定しません。 UserDefaults.register(:)がこの場合にどのように動作するかはわかりません –

関連する問題