Simple title output in ios settings bundle

后端 未结 6 1953
名媛妹妹
名媛妹妹 2021-02-01 21:17

I just want to output the version number of my ios application in a settings file.

I understand that I have to add the settings file to the application folder.

W

相关标签:
6条回答
  • 2021-02-01 21:38

    You can sync the Settings bundle to NSUserDefaults, but weirdly it does not do at first. You have to first retrieve the values from Settings to NSUserDefaults and then after that, edit that you make to those values in NSUserDefaults are automatically applied to Settings bundle.

    I referenced this nice article.

    EDIT:

    For your case to just to save your version, something like this would work. (This sample code is overkill in a way, but should be simpler to understand the flow)

    //Get the bundle file
    NSString *bPath = [[NSBundle mainBundle] bundlePath];
    NSString *settingsPath = [bPath stringByAppendingPathComponent:@"Settings.bundle"];
    NSString *plistFile = [settingsPath stringByAppendingPathComponent:@"Root.plist"];
    
    //Get the Preferences Array from the dictionary
    NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFile];
    NSArray *preferencesArray = [settingsDictionary objectForKey:@"PreferenceSpecifiers"];
    
    //Save default value of "version_number" in preference to NSUserDefaults 
    for(NSDictionary * item in preferencesArray) {
        if([[item objectForKey:@"key"] isEqualToString:@"version_number"]) {
            NSString * defaultValue = [item objectForKey:@"DefaultValue"];
            [[NSUserDefaults standardUserDefaults] setObject:defaultValue forKey:@"version_number"];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    }
    
    //Save your real version number to NSUserDefaults
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    [[NSUserDefaults standardUserDefaults] setValue:version forKey:@"version_number"];
    [[NSUserDefaults standardUserDefaults] synchronize];    
    
    0 讨论(0)
  • 2021-02-01 21:40

    This worked for me :

    Edit the Root.plist as source : Right click on the file and choose Open As->Source Code

    Add the part for the title :

       <key>PreferenceSpecifiers</key>
            <array>
                <dict>
                    <key>DefaultValue</key>
                    <string>NoVersion</string>
                    <key>Key</key>
                    <string>Version</string>
                    <key>Title</key>
                    <string>Version</string>
                    <key>Type</key>
                    <string>PSTitleValueSpecifier</string>
                </dict>
    

    And in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    Add this:

    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
        [[NSUserDefaults standardUserDefaults] setObject:version forKey:@"Version"];
    

    It will work after the app has been launched the first time.

    0 讨论(0)
  • 2021-02-01 21:48

    I had the same issue. To display Title property in the Settings.bundle you need also to add "Default Value" (it could be empty).

    1) Right click on the Title object (in my case it is Item 0) and select Add Row.

    2) In the drop down of the created row select "Default Value"

    enter image description here

    3) In didFinishLaunchingWithOptions set value to NSUserDefaults you want to display, for example:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setValue:@"0.0.1" forKey:@"appVersion"];
    [defaults synchronize];
    

    Result:

    enter image description here

    0 讨论(0)
  • 2021-02-01 21:53

    Ok, I had this problem too. The solution (sort of) was to provide a default value field and give that a value. This is actually explicitly stated in the documentation -- Default Value is a required field for the Title property, so if you don't specify it the title won't show in the settings pane. Unfortunately, I can't seem to CHANGE the value once it's set, possibly also as designed -- the documentation also states that it's a read only property. The solution I'm going to try is to just explicitly put the version number in my Root.plist file each time I make a new build. SUPER not ideal, but will work, I think.

    EDIT: Check out this post on updating version number in settings bundle

    EDIT: Ok, I got this working (thanks to that post, above, and a little hacking around with bash scripts, which I had very little experience with.) Here's the script (which I just wrote inline in a 'Run Script' build phase):

    #!/bin/bash
    
    builtInfoPlistPath=${TARGET_BUILD_DIR}/${INFOPLIST_PATH}
    
    #increment the build number
    buildNumber=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$builtInfoPlistPath")
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$builtInfoPlistPath"
    
    #compose the version number string
    versionString=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$builtInfoPlistPath")
    versionString+=" ("
    versionString+=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$builtInfoPlistPath")
    versionString+=")"
    
    #write the version number string to the settings bundle
    #IMPORTANT: this assumes the version number is the first property in the settings bundle!
    /usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:0:DefaultValue $versionString" "Settings.bundle/Root.plist"
    

    ... and that's it! Works like a charm! Hope that helps with your problem, because it solved mine. Only problem now is a slight discrepancy with the build number ...

    EDIT: ... which I fixed with vakio's second comment on this post, which instead sets the path to the info.plist to the one which is already processed (before the Run Script phase!)

    EDIT: Here's my more up-to-date version, which is in an external file and verifies that some source files have changed before incrementing the build number:

     #!/bin/bash
    
     #note: for simplicity, it's assumed that there's already a bundle version (which is an integer) and a version string. set them in the Summary pane!
    
     #get path to the BUILT .plist, NOT the packaged one! this fixes the off-by-one bug
     builtInfoPlistPath=${TARGET_BUILD_DIR}/${INFOPLIST_PATH}
     echo "using plist at $builtInfoPlistPath"
    
     modifiedFilesExist=false
     #this is the modification date to compare to -- there's a possible bug here, if you edit the built plist directly, for some reason. probably you shouldn't do that anyways.
     compModDate=$(stat -f "%m" "$builtInfoPlistPath")
    
     for filename in *
     do
         modDate=$(stat -f "%m" "$filename")
         if [ "$modDate" -gt "$compModDate" ]
         then
             modifiedFilesExist=true;
             echo "found newly modified file: $filename"
             break
         fi
     done
    
     if $modifiedFilesExist
     then
         echo "A file is new, bumping version"
    
         #increment the build number
         buildNumber=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$builtInfoPlistPath")
         echo "retrieved current build number: $buildNumber"
         buildNumber=$(($buildNumber + 1))
         /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$builtInfoPlistPath"
         /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
    
         #compose the version number string
         versionString=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$builtInfoPlistPath")
         versionString+=" ("
         versionString+=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$builtInfoPlistPath")
         versionString+=")"
    
         #write the version number string to the settings bundle
         #IMPORTANT: this assumes the version number is the second property in the settings bundle!
         /usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:1:DefaultValue $versionString" "Settings.bundle/Root.plist"
     else
         echo "Version not incremented -- no newly modified files"
     fi 
    
    0 讨论(0)
  • 2021-02-01 21:57

    NSUserDefaults doen't write any values to a settings file. It will only save data in the user defaults plist in your app.

    To save something in another file you will have to write this your own. Maybe this will help:

    iOS - How to write a data in plist?

    0 讨论(0)
  • 2021-02-01 21:59

    Another solution, without writing swift code is :

    1/ Create a Setting bundle

    This will create a new section for your app in the Settings of your device

    • Right click your project name -> New File -> Settings Bundle

    2/ Modify the Root.plist

    This will set what you want to display in your app settings - Inside your new Setting Bundle, right click on the Root.plist -> Open As -> Source Code

    • Copy Paste the Following code in it :

      <?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>PreferenceSpecifiers</key>
           <array>
              <dict>
                  <key>Title</key>
                  <string>About</string>
                  <key>Type</key>
                  <string>PSGroupSpecifier</string>
              </dict>
              <dict>
                  <key>DefaultValue</key>
                  <string></string>
                  <key>Key</key>
                  <string>version_preference</string>
                  <key>Title</key>
                  <string>Version</string>
                  <key>Type</key>
                  <string>PSTitleValueSpecifier</string>
              </dict>
          </array>
          <key>StringsTable</key>
          <string>Root</string>
      </dict>
      </plist>
      

    3/ Create a Run Script

    This will always get the version of your app from the Info.plist and display it in your app Settings

    • Navigate to your Project Target on the left panel and click on Build Phases
    • Click the "+" button and hit "New Run Script Phase"
    • In the Newest Run Script section , Copy/Paste the following :

      #Getting Current Version
      VERSIONNUM=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString"   "${PROJECT_DIR}/${INFOPLIST_FILE}")
      
      #Setting the version number in settings
      /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $VERSIONNUM" <YOUR-APP-NAME>/Settings.bundle/Root.plist
      
    • Just replace YOUR-APP-NAME by your app name

    0 讨论(0)
提交回复
热议问题