I will be storing a few strings (maybe 10-20). I am not sure if I should use NSUserDefaults to save them, or write them out to a plist. What is considered best practice? NSUserDefaults seems like it is less lines of code, therefore quicker to implement.
我将存储一些字符串(可能是10-20)。我不确定是否应该使用NSUserDefaults来保存它们,或者将它们写到plist中。什么是最佳实践?NSUserDefaults看起来好像代码行更少,因此实现起来更快。
I'd like to add that these string values will be added/removed by the user.
我想添加这些字符串值将被用户添加/删除。
9 个解决方案
#1
81
I am assuming an array, but it will work with dictionaries too.
我假设有一个数组,但它也适用于字典。
Userdefaults, Core Data and Plists can all be read/write but if you use a plist you need to pay attention in what dir you put it. See the plist part down below.
Userdefaults, Core Data和Plists都可以读/写,但是如果你使用一个plist,你需要注意你把它放在什么地方。请参阅下面的plist部分。
Core Data I think it's way too much overkill, it's just strings. It's supposed to be used when you want to persist more complex objects.
Core Data,我觉得太过分了,只是字符串。当您希望持久化更复杂的对象时,应该使用它。
NSUserDefaults:
NSUserDefaults:
It's pretty fast and easy to do, though it's supposed to store only user settings. To write them to the userdefaults:
虽然它只存储用户设置,但是速度很快,也很容易实现。将它们写入用户默认值:
NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
[[NSUserDefaults standardUserDefaults] setObject:stringsArray forKey:@"MyStrings"];
[[NSUserDefaults standardUserDefaults] synchronize];
To read the from the userdefaults:
从userdefaults中读取数据:
NSArray *stringsArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyStrings"];
Plist:
Plist:
If your strings are going to be modified you will need to write and read a plist but you cant't write into your app's resources.
如果你的字符串要被修改,你需要写和读一个plist,但是你不能写进你的应用的资源。
-
To have a read/write plist first find the documents directory
要有一个读/写plist首先查找文档目录。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
-
Create the array (I am assuming the strings are string1, ...)
创建数组(假设字符串是string1,…)
NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
-
Write it to file
写文件
[stringsArray writeToFile:stringsPlistPath atomically:YES];
To read the plist:
阅读plist:
-
Find the documents directory
找到的文件目录
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
-
Read it in:
读:
NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
#2
7
If you are storing 10-20 strings and are looking for not too many lines of code, core data is certainly much too much overhead. I recommend going with the plist. Not a lot of code:
如果您正在存储10-20个字符串,并且正在寻找不太多的代码行,那么core data肯定会占用太多的开销。我推荐你去plist。没有很多代码:
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"MyStrings" withExtension:@"plist"];
NSArray *stringArray = [NSArray arrayWithContentsOfURL:plistURL];
#3
7
iOS ultimately stores all NSUserDefaults
data to a plist file. So it will not affect the performance if that is your concern. I personally prefer using NSUserDefaults
for small data and plist for a relatively large set of data.
iOS最终将所有NSUserDefaults数据存储到plist文件中。如果这是你关心的,它不会影响性能。我个人更喜欢对小数据使用NSUserDefaults,对相对较大的数据使用plist。
Note: Never store any sensitive information in NSUserDefaults
as anyone can see that data.
注意:不要在NSUserDefaults中存储任何敏感信息,因为任何人都可以看到这些数据。
#4
4
NSUserDefaults will store the user preferences into a file into the Library/Preferences folder. In theory it serves only to store some application/user properties.
NSUserDefaults会将用户偏好储存在一个文件中到Library/ preferences文件夹中。理论上,它只用于存储一些应用程序/用户属性。
Plist file are usefull to manage a single file. If you need to manage more you should use the Coredata. There is no restriction about the size of the plist file. Otherwise you have to be careful with plist file because when you need to save or read it the entire contents of the file will be load into memory.
Plist文件用于管理单个文件。如果您需要管理更多,您应该使用Coredata。plist文件的大小没有限制。否则,您必须小心处理plist文件,因为当您需要保存或读取它时,文件的全部内容将被加载到内存中。
#5
2
It depends on what you want to store and why. NSUserDefaults is meant for storing user preferences. You can try to use it for other things, but you probably shouldn't.
这取决于你想要存储什么以及为什么要存储。NSUserDefaults是用来存储用户偏好的。你可以试着用它来做其他事情,但你可能不应该这样做。
Otherwise, if your needs are simple a plist file is pretty straightforward. You can also use core data or come up with your own file format. In general, I use plist for simple tasks and then move to core data for anything more complex.
否则,如果您的需求很简单,那么plist文件非常简单。您也可以使用核心数据或提出您自己的文件格式。一般来说,我在简单的任务中使用plist,然后在更复杂的任务中使用core data。
#6
2
Using a plist is a good choice for storing your strings if the strings are not just user settings that can go in NSUserDefaults. As was mentioned, when using a plist you must store your plist in the Documents directory in order to write to it, because you can't write into your own app's resources. When I first learned this, I wasn't clear on where your own app's Bundle directory was vs. where the Documents directory was, so I thought I'd post example code here that first copies a plist called "Strings.plist" (that you already have in your own app's Bundle directory) to the Documents directory, and then writes to it and reads from it.
如果字符串不只是可以在NSUserDefaults中进行的用户设置,那么使用plist存储字符串是一个很好的选择。如前所述,使用plist时,必须将plist存储在Documents目录中,以便写入它,因为不能将其写入自己的应用程序的资源中。当我第一次学这个的时候,我不清楚你自己的应用的Bundle目录在哪里,文档目录在哪里,所以我想我应该在这里发布示例代码,它首先复制了一个名为“Strings”的plist。plist(你已经在你自己的应用的Bundle目录中有了)到Documents目录,然后写到它并从中读取。
// Make a path to the plist in the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stringsPlistPathIndDoc = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
// Make a path to the plist in your app's Bundle directory
NSString *stringsPlistPathInBundle = [[NSBundle mainBundle] pathForResource:@"Strings" ofType:@".plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check first that you haven't already copied this plist to the Documents directory
if (![fileManager fileExistsAtPath:stringsPlistPathIndDoc])
{
NSError *error;
// Copy the plist from the Bundle directory to the Documents directory
[fileManager copyItemAtPath:stringsPlistPathInBundle toPath:stringsPlistPathIndDoc error:&error];
}
// Write your array out to the plist in the Documents directory
NSMutableArray *stringsArray = [[NSMutableArray alloc] initWithObjects:@"string1", @"string2", @"string3", nil];
[stringsArray writeToFile:stringsPlistPathIndDoc atomically:YES];
// Later if you want to read it:
stringsArray = [[NSMutableArray alloc] initWithContentsOfFile:stringsPlistPathIndDoc];
#7
2
NSUSerDefaults
is indeed quick to implement, but mostly as your application grows, you want to store more and more, I went directly for plist files.
NSUSerDefaults的确很容易实现,但是随着应用程序的增长,你会越来越想要存储更多,我直接去找plist文件。
Mostly, people want to store a list of something, so here is my share on how to do this with NSDictionary. This does not require you to create a plist file first, it will be created at the first time saving something
大多数情况下,人们想要存储一些东西的列表,下面是我分享的关于如何使用NSDictionary来实现这一点的方法。这并不要求您首先创建一个plist文件,它将在第一次保存一些东西时创建
xcode 7 beta, Swift 2.0
xcode 7 beta, Swift 2.0。
saving
储蓄
func SaveItemFavorites(items : Array<ItemFavorite>) -> Bool
{
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let docuDir = paths.firstObject as! String
let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
let filemanager = NSFileManager.defaultManager()
let array = NSMutableArray()
for var i = 0 ; i < items.count ; i++
{
let dict = NSMutableDictionary()
let ItemCode = items[i].ItemCode as NSString
dict.setObject(ItemCode, forKey: "ItemCode")
//add any aditional..
array[i] = dict
}
let favoritesDictionary = NSDictionary(object: array, forKey: "favorites")
//check if file exists
if(!filemanager.fileExistsAtPath(path))
{
let created = filemanager.createFileAtPath(path, contents: nil, attributes: nil)
if(created)
{
let succeeded = favoritesDictionary.writeToFile(path, atomically: true)
return succeeded
}
return false
}
else
{
let succeeded = notificationDictionary.writeToFile(path, atomically: true)
return succeeded
}
}
Little note from the docs:
来自文件的小提示:
NSDictionary.writeToFile(path:atomically:)
NSDictionary.writeToFile(路径:自动:)
This method recursively validates that all the contained objects are property list objects (instances of
NSData
,NSDate
,NSNumber
,NSString
,NSArray
, orNSDictionary
) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.该方法在写入文件之前递归地验证所有包含的对象都是属性列表对象(NSData、NSDate、NSNumber、NSString、NSArray或NSDictionary的实例),如果所有对象都不是属性列表对象,则返回NO,因为生成的文件不是有效的属性列表。
So whatever you set at dict.SetObject()
should be one of the above mentioned types.
因此,无论您在dict.SetObject()上设置什么,都应该是上述类型之一。
loading
加载
private let ItemFavoritesFilePath = "ItemFavorites.plist"
func LoadItemFavorites() -> Array<ItemFavorite>
{
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let docuDir = paths.firstObject as! String
let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
let dict = NSDictionary(contentsOfFile: path)
let dictitems : AnyObject? = dict?.objectForKey("favorites")
var favoriteItemsList = Array<ItemFavorite>()
if let arrayitems = dictitems as? NSArray
{
for var i = 0;i<arrayitems.count;i++
{
if let itemDict = arrayitems[i] as? NSDictionary
{
let ItemCode = itemDict.objectForKey("ItemCode") as? String
//get any additional
let ItemFavorite = ItemFavorite(item: ItemCode)
favoriteItemsList.append(ItemFavorite)
}
}
}
return favoriteItemsList
}
#8
1
The recommended way to persist data like this is to use Core Data. While NSUserDefaults can be used to store more or less anything it's only supposed to be used to store preferences.
像这样持久化数据的推荐方法是使用Core data。虽然NSUserDefaults可以用来存储或多或少的东西,但它只应该用来存储偏好。
#9
1
Using .plist
使用.plist
- Create a plist using Xcode
- 使用Xcode创建一个plist
Write a value to plist
给plist写一个值。
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"settings" withExtension:@"plist"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
[dict setValue:@"value" forKey:@"key"];
[dict writeToURL:plistURL atomically:YES];
Read a value from plist
从plist中读取一个值
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
NSString *myValue = [dict valueForKey:@"key"];
#1
81
I am assuming an array, but it will work with dictionaries too.
我假设有一个数组,但它也适用于字典。
Userdefaults, Core Data and Plists can all be read/write but if you use a plist you need to pay attention in what dir you put it. See the plist part down below.
Userdefaults, Core Data和Plists都可以读/写,但是如果你使用一个plist,你需要注意你把它放在什么地方。请参阅下面的plist部分。
Core Data I think it's way too much overkill, it's just strings. It's supposed to be used when you want to persist more complex objects.
Core Data,我觉得太过分了,只是字符串。当您希望持久化更复杂的对象时,应该使用它。
NSUserDefaults:
NSUserDefaults:
It's pretty fast and easy to do, though it's supposed to store only user settings. To write them to the userdefaults:
虽然它只存储用户设置,但是速度很快,也很容易实现。将它们写入用户默认值:
NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
[[NSUserDefaults standardUserDefaults] setObject:stringsArray forKey:@"MyStrings"];
[[NSUserDefaults standardUserDefaults] synchronize];
To read the from the userdefaults:
从userdefaults中读取数据:
NSArray *stringsArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyStrings"];
Plist:
Plist:
If your strings are going to be modified you will need to write and read a plist but you cant't write into your app's resources.
如果你的字符串要被修改,你需要写和读一个plist,但是你不能写进你的应用的资源。
-
To have a read/write plist first find the documents directory
要有一个读/写plist首先查找文档目录。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
-
Create the array (I am assuming the strings are string1, ...)
创建数组(假设字符串是string1,…)
NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
-
Write it to file
写文件
[stringsArray writeToFile:stringsPlistPath atomically:YES];
To read the plist:
阅读plist:
-
Find the documents directory
找到的文件目录
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
-
Read it in:
读:
NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
#2
7
If you are storing 10-20 strings and are looking for not too many lines of code, core data is certainly much too much overhead. I recommend going with the plist. Not a lot of code:
如果您正在存储10-20个字符串,并且正在寻找不太多的代码行,那么core data肯定会占用太多的开销。我推荐你去plist。没有很多代码:
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"MyStrings" withExtension:@"plist"];
NSArray *stringArray = [NSArray arrayWithContentsOfURL:plistURL];
#3
7
iOS ultimately stores all NSUserDefaults
data to a plist file. So it will not affect the performance if that is your concern. I personally prefer using NSUserDefaults
for small data and plist for a relatively large set of data.
iOS最终将所有NSUserDefaults数据存储到plist文件中。如果这是你关心的,它不会影响性能。我个人更喜欢对小数据使用NSUserDefaults,对相对较大的数据使用plist。
Note: Never store any sensitive information in NSUserDefaults
as anyone can see that data.
注意:不要在NSUserDefaults中存储任何敏感信息,因为任何人都可以看到这些数据。
#4
4
NSUserDefaults will store the user preferences into a file into the Library/Preferences folder. In theory it serves only to store some application/user properties.
NSUserDefaults会将用户偏好储存在一个文件中到Library/ preferences文件夹中。理论上,它只用于存储一些应用程序/用户属性。
Plist file are usefull to manage a single file. If you need to manage more you should use the Coredata. There is no restriction about the size of the plist file. Otherwise you have to be careful with plist file because when you need to save or read it the entire contents of the file will be load into memory.
Plist文件用于管理单个文件。如果您需要管理更多,您应该使用Coredata。plist文件的大小没有限制。否则,您必须小心处理plist文件,因为当您需要保存或读取它时,文件的全部内容将被加载到内存中。
#5
2
It depends on what you want to store and why. NSUserDefaults is meant for storing user preferences. You can try to use it for other things, but you probably shouldn't.
这取决于你想要存储什么以及为什么要存储。NSUserDefaults是用来存储用户偏好的。你可以试着用它来做其他事情,但你可能不应该这样做。
Otherwise, if your needs are simple a plist file is pretty straightforward. You can also use core data or come up with your own file format. In general, I use plist for simple tasks and then move to core data for anything more complex.
否则,如果您的需求很简单,那么plist文件非常简单。您也可以使用核心数据或提出您自己的文件格式。一般来说,我在简单的任务中使用plist,然后在更复杂的任务中使用core data。
#6
2
Using a plist is a good choice for storing your strings if the strings are not just user settings that can go in NSUserDefaults. As was mentioned, when using a plist you must store your plist in the Documents directory in order to write to it, because you can't write into your own app's resources. When I first learned this, I wasn't clear on where your own app's Bundle directory was vs. where the Documents directory was, so I thought I'd post example code here that first copies a plist called "Strings.plist" (that you already have in your own app's Bundle directory) to the Documents directory, and then writes to it and reads from it.
如果字符串不只是可以在NSUserDefaults中进行的用户设置,那么使用plist存储字符串是一个很好的选择。如前所述,使用plist时,必须将plist存储在Documents目录中,以便写入它,因为不能将其写入自己的应用程序的资源中。当我第一次学这个的时候,我不清楚你自己的应用的Bundle目录在哪里,文档目录在哪里,所以我想我应该在这里发布示例代码,它首先复制了一个名为“Strings”的plist。plist(你已经在你自己的应用的Bundle目录中有了)到Documents目录,然后写到它并从中读取。
// Make a path to the plist in the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stringsPlistPathIndDoc = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
// Make a path to the plist in your app's Bundle directory
NSString *stringsPlistPathInBundle = [[NSBundle mainBundle] pathForResource:@"Strings" ofType:@".plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check first that you haven't already copied this plist to the Documents directory
if (![fileManager fileExistsAtPath:stringsPlistPathIndDoc])
{
NSError *error;
// Copy the plist from the Bundle directory to the Documents directory
[fileManager copyItemAtPath:stringsPlistPathInBundle toPath:stringsPlistPathIndDoc error:&error];
}
// Write your array out to the plist in the Documents directory
NSMutableArray *stringsArray = [[NSMutableArray alloc] initWithObjects:@"string1", @"string2", @"string3", nil];
[stringsArray writeToFile:stringsPlistPathIndDoc atomically:YES];
// Later if you want to read it:
stringsArray = [[NSMutableArray alloc] initWithContentsOfFile:stringsPlistPathIndDoc];
#7
2
NSUSerDefaults
is indeed quick to implement, but mostly as your application grows, you want to store more and more, I went directly for plist files.
NSUSerDefaults的确很容易实现,但是随着应用程序的增长,你会越来越想要存储更多,我直接去找plist文件。
Mostly, people want to store a list of something, so here is my share on how to do this with NSDictionary. This does not require you to create a plist file first, it will be created at the first time saving something
大多数情况下,人们想要存储一些东西的列表,下面是我分享的关于如何使用NSDictionary来实现这一点的方法。这并不要求您首先创建一个plist文件,它将在第一次保存一些东西时创建
xcode 7 beta, Swift 2.0
xcode 7 beta, Swift 2.0。
saving
储蓄
func SaveItemFavorites(items : Array<ItemFavorite>) -> Bool
{
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let docuDir = paths.firstObject as! String
let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
let filemanager = NSFileManager.defaultManager()
let array = NSMutableArray()
for var i = 0 ; i < items.count ; i++
{
let dict = NSMutableDictionary()
let ItemCode = items[i].ItemCode as NSString
dict.setObject(ItemCode, forKey: "ItemCode")
//add any aditional..
array[i] = dict
}
let favoritesDictionary = NSDictionary(object: array, forKey: "favorites")
//check if file exists
if(!filemanager.fileExistsAtPath(path))
{
let created = filemanager.createFileAtPath(path, contents: nil, attributes: nil)
if(created)
{
let succeeded = favoritesDictionary.writeToFile(path, atomically: true)
return succeeded
}
return false
}
else
{
let succeeded = notificationDictionary.writeToFile(path, atomically: true)
return succeeded
}
}
Little note from the docs:
来自文件的小提示:
NSDictionary.writeToFile(path:atomically:)
NSDictionary.writeToFile(路径:自动:)
This method recursively validates that all the contained objects are property list objects (instances of
NSData
,NSDate
,NSNumber
,NSString
,NSArray
, orNSDictionary
) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.该方法在写入文件之前递归地验证所有包含的对象都是属性列表对象(NSData、NSDate、NSNumber、NSString、NSArray或NSDictionary的实例),如果所有对象都不是属性列表对象,则返回NO,因为生成的文件不是有效的属性列表。
So whatever you set at dict.SetObject()
should be one of the above mentioned types.
因此,无论您在dict.SetObject()上设置什么,都应该是上述类型之一。
loading
加载
private let ItemFavoritesFilePath = "ItemFavorites.plist"
func LoadItemFavorites() -> Array<ItemFavorite>
{
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let docuDir = paths.firstObject as! String
let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
let dict = NSDictionary(contentsOfFile: path)
let dictitems : AnyObject? = dict?.objectForKey("favorites")
var favoriteItemsList = Array<ItemFavorite>()
if let arrayitems = dictitems as? NSArray
{
for var i = 0;i<arrayitems.count;i++
{
if let itemDict = arrayitems[i] as? NSDictionary
{
let ItemCode = itemDict.objectForKey("ItemCode") as? String
//get any additional
let ItemFavorite = ItemFavorite(item: ItemCode)
favoriteItemsList.append(ItemFavorite)
}
}
}
return favoriteItemsList
}
#8
1
The recommended way to persist data like this is to use Core Data. While NSUserDefaults can be used to store more or less anything it's only supposed to be used to store preferences.
像这样持久化数据的推荐方法是使用Core data。虽然NSUserDefaults可以用来存储或多或少的东西,但它只应该用来存储偏好。
#9
1
Using .plist
使用.plist
- Create a plist using Xcode
- 使用Xcode创建一个plist
Write a value to plist
给plist写一个值。
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"settings" withExtension:@"plist"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
[dict setValue:@"value" forKey:@"key"];
[dict writeToURL:plistURL atomically:YES];
Read a value from plist
从plist中读取一个值
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
NSString *myValue = [dict valueForKey:@"key"];