Easy way to see saved NSUserDefaults?
-
16-09-2019 - |
Question
Is there a way to see what's been saved to NSUserDefaults
directly? I'd like to see if my data saved correctly.
Solution
You can find the pList file for your app in the simulator if you go to:
/users/your user name/Library/Application Support/iPhone Simulator/<Sim Version>/Applications
This directory has a bunch of GUID named directories. If you are working on a few apps there will be a few of them. So you need to find your app binary:
find . -name foo.app
./1BAB4C83-8E7E-4671-AC36-6043F8A9BFA7/foo.app
Then go to the Library/Preferences directory in the GUID directory. So:
cd 1BAB4C83-8E7E-4671-AC35-6043F8A9BFA7/Library/Preferences
You should find a file that looks like:
<Bundle Identifier>.foo.pList
Open this up in the pList editor and browse persisted values to your heart's content.
OTHER TIPS
You can print all current NSUserDefaults to the log:
Just keys:
NSLog(@"%@", [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]);
Keys and values:
NSLog(@"%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
In Swift we can use the following:-
Swift 3.x & 4.x
For getting all keys & values:
for (key, value) in UserDefaults.standard.dictionaryRepresentation() {
print("\(key) = \(value) \n")
}
For retrieving the complete dictionary representation of user defaults:
print(Array(UserDefaults.standard.dictionaryRepresentation()))
For retrieving the keys:
// Using dump since the keys are an array of strings.
dump(Array(UserDefaults.standard.dictionaryRepresentation().keys))
For retrieving the values:
We can use dump here as well, but that will return the complete inheritance hierarchy of each element in the values array. If more information about the objects is required, then use dump, else go ahead with the normal print statement.
// dump(Array(UserDefaults.standard.dictionaryRepresentation().values))
print(Array(UserDefaults.standard.dictionaryRepresentation().values))
Swift 2.x
For retrieving the complete dictionary representation of user defaults:
print(NSUserDefaults.standardUserDefaults().dictionaryRepresentation())
For retrieving the keys:
print(NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys.array)
For retrieving the values:
print(NSUserDefaults.standardUserDefaults().dictionaryRepresentation().values.array)
You can check the values for each key in the array, returned by
[[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]
I sometimes use the following snippet to print out the location of my NSUserDefaults file when running in the simulator
NSArray *path = NSSearchPathForDirectoriesInDomains( NSLibraryDirectory, NSUserDomainMask, YES); NSString *folder = [path objectAtIndex:0]; NSLog(@"Your NSUserDefaults are stored in this folder: %@/Preferences", folder);
It yields the path to the preferences folder
Your NSUserDefaults are stored in this folder: /Users/castle/Library/Application Support/iPhone Simulator/User/Applications/BC5056A0-F46B-4AF1-A6DC-3A7DAB984960/Library/Preferences
Your NSUserDefaults file is located in the preferences folder and named according to your prefix and appliation name e.g.
dk.castleandersen.dreamteam.grid.plist
I expect the same to be true for the actual device.
Use below code.
NSLog(@"NSUserDefault: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
In Swift 4.0
//func dictionaryRepresentation() -> [String : AnyObject]
because dictionaryRepresentation of NSUserDefaults.standardUserDefaults() returns [String : AnyObject]
We cast it into an NSDictionary
. Then by surrounding it in parenthesis '()' will allow us to to call .allKeys or .allValues just as you would on any NSDictionary
print((UserDefaults.standard.dictionaryRepresentation() as NSDictionary).allKeys)
Easy, since the plist file name is <app-bundle-identifier>.plist
, you can use find
command to find its path. But it will take very long if you search your whole computer, so you have to pick a good scope, like ~/Library/Developer/CoreSimulator
for Xcode 6.
example:
find ~/Library/Developer/CoreSimulator -type f -name com.awesome.app.plist
the output will be something like this...
/Users/hlung/Library/Developer/CoreSimulator/Devices/B61913F6-7D7C-4E45-AE2F-F45220A71823/data/Containers/Data/Application/E4CC51CF-11E5-4168-8A74-6BAE3B89998F/Library/Preferences/com.awesome.app.plist
And from there you can use open
command. Or if you use iTerm2, just command-click on the path to open it.
For Xcode 7
NSUserDefaults standardDefaults are stored here:
/Users/{USER}/Library/Developer/CoreSimulator/Devices/{UUID}/data/Containers/Data/Application/{UUID}
NSUserDefaults for a suite/app group are stored here:
/Users/{USER}/Library/Developer/CoreSimulator/Devices/{UUID}/data/Containers/Shared/AppGroup/{UUID}/Library/Preferences/{GROUP_NAME}.plist
I would recommend using https://github.com/scinfu/NCSimulatorPlugin because these days everything is behind UUIDs and are a pain to find. It allows easy access to your simulator app directories.
For OS X applications, instead of finding the application's defaults plist file, it is simpler to use the defaults
command line utility.
NAME
defaults -- access the Mac OS X user defaults system
SYNOPSIS
defaults [-currentHost | -host hostname] read [domain [key]] defaults [-currentHost | -host hostname] read-type domain key defaults [-currentHost | -host hostname] write domain { 'plist' | key 'value' } defaults [-currentHost | -host hostname] rename domain old_key new_key defaults [-currentHost | -host hostname] delete [domain [key]] defaults [-currentHost | -host hostname] { domains | find word | help }
DESCRIPTION
defaults
allows users to read, write, and delete Mac OS X user defaults from a command-line shell. Mac OS X applications and other programs use the defaults system to record user preferences and other information that must be maintained when the applications aren't running (such as default font for new documents, or the position of an Info panel). Much of this information is accessible through an appli- cation's Preferences panel, but some of it isn't, such as the position of the Info panel. You can access this information withdefaults
Example:
$ defaults read com.apple.Safari
{
AutoplayPolicyWhitelistConfigurationUpdateDate = "2018-08-24 17:33:48 +0000";
AutoplayQuirksWhitelistConfigurationUpdateDate = "2018-08-24 17:33:48 +0000";
DefaultBrowserPromptingState2 = 4;
...
I built this method based on Morion's suggestion for better presentation. Use it by calling [self logAllUserDefaults]
- (void) logAllUserDefaults
{
NSArray *keys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys];
NSArray *values = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allValues];
for (int i = 0; i < keys.count; i++) {
NSLog(@"%@: %@", [keys objectAtIndex:i], [values objectAtIndex:i]);
}
}
Look for the Mac app called SimPholders2. It lives in the menu bar, and lists all of the simulators you've used, and then shows each of your apps. Select one and you get a new Finder window, already open to the app's directory. This makes it super easy to find your app and all of it's directories. It's a huge time saver (and I readily donated to the author).
You could NSLog each value you set, like:
NSLog(@"%@",[[NSUserDefaults standardDefaults] stringForKey:@"WhateverTheKeyYouSet"]);
In Swift 2.2
let path = NSSearchPathForDirectoriesInDomains(.LibraryDirectory, .UserDomainMask, true)
let folder = path[0]
NSLog("Your NSUserDefaults are stored in this folder: \(folder)/Preferences")
will print out NSUserDefaults's plist file folder location in Xcode debug console. Copy the path string. Open your Finder, select Go to Folder in Go menu item, Paste the path string. Double click the plist file. You will see the contents in your Xcode editor.
Only work in Simulator
Thanks @Niels Castle
I keep a shortcut on my desktop to the simulator's folder where it keeps the apps, ie:
/Users/gary/Library/Application Support/iPhone Simulator/User/Applications
Sorted by most recent date, then just go into the most recent app folder Library/Preferences and view the file in the plist editor.
Swift 3
print(UserDefaults.standard.dictionaryRepresentation())
Simulator App
This shell script search for the name of the app, obtain the bundle id, and open folders containing the Plist files.
#!/bin/bash
appname="$1"
[ -z $appname ] && read -p "Application name : " appname
apppath=$(find ~/Library/Developer/CoreSimulator/Devices/ -name "$appname.app" -print -quit)
if [[ ! -z $apppath ]]; then
appbundle=$(osascript -e "id of app \"$apppath\"")
find ~/Library/Developer/CoreSimulator/Devices/ -name "$appbundle.plist" -exec bash -c 'open "$(dirname "$1")"' -- {} \;
else
echo "No application found by that name: $appname.app"
fi
Extended script version
Usage: iphone-app-folder "My App"
#!/bin/bash
appname="$1"
[ -z "$appname" ] && read -p "Application name : " appname
apppath=$(find ~/Library/Developer/CoreSimulator/Devices -name "$appname.app" -print -quit)
if [[ ! -z $apppath ]]; then
appbundle=$(osascript -e "id of app \"$apppath\"")
echo "Found app $appname (${appbundle})"
echo -e "\033[1;30m$apppath\033[0m"
plists=$(find ~/Library/Developer/CoreSimulator/Devices -name "$appbundle.plist" -print -quit)
count=$(echo plists | wc -l | sed "s/ //g")
if [[ $count -eq 1 ]] && [[ -f "$plists" ]]; then
echo -e "\033[1;32mUserDefaults found for $appname\033[0m"
echo -e "\033[1;30m$plists\033[0m"
plistutil -i "$plists"
/usr/bin/open $(dirname "$plists")
elif [[ ${#plists} -gt 0 ]]; then
echo -e "\033[1;32mUserDefaults found for $appname\033[0m"
i=1
while read line; do
echo "[${i}] ${line} "
i=$((i+1))
done < <(echo "$plists")
echo
read -p "Select defaults to read: [1-${count}] " choice
plist=$(echo ${plists} | sed -n "${choice}p")
plistutil -i "$plist"
/usr/bin/open $(dirname "$plist")
else
echo -e "\033[31mNo UserDefaults plist found for $appname\033[0m"
fi
else
echo -e "\033[31mNo application found by that name: $appname.app\033[0m"
fi
Found app My App (com.organisation.MyApp) /Users/organisation/Library/Developer/CoreSimulator/Devices/3E4C8DC3-6FF4-428F-A624-B78DBE0B8C83/data/Containers/Bundle/Application/960A5232-219D-4C46-8CA3-01E259D8DDAD/My App.app
UserDefaults found for My App
Mac App
defaults read com.bundleid.app
For MacOS apps
Go to: /Users/{User}/Library/Containers/com.{your company}.{your app}/Data/Library/Preferences and open your app's pList with Xcode.
After reading this question's accepted answer, I put together this simple script that opens the plist files used by the iOS simulator to store the NSUserDefaults
preferences, and while it assumes a certain setup (fits mine perfectly), it may work as a starting point for others.
$ cat open-prefs-plist.sh
#!/bin/sh
# The project name based on the workspace path, e.g. "MyProject" from "./MyProject.xcworkspace"
WORKSPACE_NAME=$(echo `find . -name *.xcworkspace -type d -exec basename {} \;` | cut -d'.' -f1)
SIMULATOR_PATH="$HOME/Library/Application Support/iPhone Simulator"
# The App's bundle ID taken from its info plist, e.g "com.myproject" from "./MyProject/MyProject-Info.plist"
BUNDLE_ID=`/usr/libexec/PlistBuddy -c Print:CFBundleIdentifier $WORKSPACE_NAME/$WORKSPACE_NAME"-Info.plist"`
# Open all plist files in the simulator path that match the app's bundle ID
# normally one per iOS version
find "$SIMULATOR_PATH" -name $BUNDLE_ID".plist" -type f -print0 \
| while IFS= read -r -d '' PLIST; do
echo $PLIST
open "$PLIST"
done
Example placement:
$ ls -1
MyProject
MyProject Tests
MyProject.xcodeproj
MyProject.xcworkspace
Podfile
open-prefs-plist.sh
You can user this to get the full path on user preferences, cache and many other data
print(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true))