在iphone上本地存储数据

我正在构build一个应用程序,我希望将用户信息本地存储在设备上,而不使用任何服务器数据库 – 但是设备端的所有信息。 我正在寻找存储特定的用户位置,并显示在表视图,所以即使当用户启动应用程序后 – 我可以拉历史logging和饲料历史表与过去的位置。 基本上来自本地数据库的读/写能力。

现在,我知道以前有很多这样的问题,但是我找不到一个在没有外部数据库的情况下在本地保存数据的问题。 例如,我不确定使用核心数据是否正确和最简单。

将不胜感激任何意见。

对于简单的数据,你应该使用NSUserDefaults。 CoreData是非常酷,但主要是存储数据库结构,并介绍了复杂性(但我爱它:))。 如果你只需要存储String,Array等(基本上是prefs),你可以使用NSUserDefaults:

例如:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; //load NSUserDefaults NSArray *fakeFavs = [[ NSArray alloc] initWithObjects:@"2",@"4", @"100", nil]; //declare array to be stored in NSUserDefaults [prefs setObject:fakeFavs forKey:@"favourites"]; //set the prev Array for key value "favourites" 

基本上有两个select来存储数据:

  1. CoreData(如果你打算使用更新版本的iOS)
  2. SQLite(支持任何版本的SDK)

CoreData使用SQLite,它的API使用起来更容易一些(你不需要知道SQL或者写很多函数来读写你的数据)。

SQLite API仍然是一个很好的select,因为它使用SQLite的C API,这是非常有据可查的和直接使用。 它的好处是你可以用这个来定位老版本的iOS平台。

有了这两个选项,数据将被存储在客户端,并且每次用户将他/她的手机与iTunes同步时都会被备份。

如果你只是存储一些值,不需要任何search逻辑,你可以看看NSUserDefaults

 [NSUserDefaults standardUserDefaults] 

它只是一个字典,你可以存储数组,string,int,对象和一个NSString键的访问

在内部它是一个简单的plist,所以你可以用xcode打开它来快速查看当前状态

我build议使用Realm来获得更一般化的解决scheme。

您有几种不同的方式来将应用程序数据存储在您的iPhone上。

  1. Plist文件
  2. NSUserDefaults的
  3. UserDefault
  4. 文件系统
  5. CoreData
  6. SQLite数据库
 Select Query:::::: NSArray *array_hiback =[app.sk lookupAllForSQL:@"SELECT * FROM cycle_datagathering_begoodyourselef ORDER BY RANDOM() LIMIT 1"]; NSLog(@"%@",array_hiback); insert Query::::: NSMutableDictionary *dict=[[NSMutableDictionary alloc]init]; [dict setObject:@"0" forKey:@"isuploaded"]; [app.sk insertDictionary:dict forTable:@"mindeditor"]; [dict release]; update Query:::: NSMutableDictionary *updatedata=[[NSMutableDictionary alloc]init]; [updatedata setObject: [[NSUserDefaults standardUserDefaults] objectForKey:@"savecycleid"] forKey:@"cycleid"]; delete Query::::: [app.sk deleteWhere:[NSString stringWithFormat:@"rowid=%@",str] forTable:@"mindeditor"]; [app.sk updateDictionary:updatedata forTable:@"mindeditor" where:[NSString stringWithFormat:@"rowid=%@", [[checkarray objectAtIndex:checkarray.count-1] objectForKey:@"cycleid"]]]; [updatedata release]; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { sk = [[SKDatabase alloc] init]; NSString *db = @"MindEditor.db"; [sk initWithDynamicFile:db]; userid=@"0"; } SKDatabase.h // // SKDatabase.h // Version 1.1 // // Created by Shannon Appelcline on 9/11/08. // Copyright 2008 __MyCompanyName__. All rights reserved. // #import <UIKit/UIKit.h> #import <sqlite3.h> @protocol SKDatabaseDelegate <NSObject> @optional - (void)databaseTableWasUpdated:(NSString *)table; @end @interface SKDatabase : NSObject { id<SKDatabaseDelegate> delegate; sqlite3 *dbh; BOOL dynamic; } @property (assign) id<SKDatabaseDelegate> delegate; @property sqlite3 *dbh; @property BOOL dynamic; - (id)initWithFile:(NSString *)dbFile; - (id)initWithDynamicFile:(NSString *)dbFile; - (void)close; - (sqlite3_stmt *)prepare:(NSString *)sql; - (id)lookupColForSQL:(NSString *)sql; - (NSDictionary *)lookupRowForSQL:(NSString *)sql; - (NSArray *)lookupAllForSQL:(NSString *)sql; - (int)lookupCountWhere:(NSString *)where forTable:(NSString *)table; - (int)lookupMax:(NSString *)key Where:(NSString *)where forTable:(NSString *)table; - (int)lookupSum:(NSString *)key Where:(NSString *)where forTable:(NSString *)table; - (void)insertArray:(NSArray *)dbData forTable:(NSString *)table; - (void)insertDictionary:(NSDictionary *)dbData forTable:(NSString *)table; - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table; - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table where:(NSString *)where; - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table; - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table where:(NSString *)where; - (void)updateSQL:(NSString *)sql forTable:(NSString *)table; - (void)deleteWhere:(NSString *)where forTable:(NSString *)table; - (BOOL)runDynamicSQL:(NSString *)sql forTable:(NSString *)table; @end SKDatabase.m // // SKDatabase.m // Version 1.1 // // Created by Shannon Appelcline on 9/11/08. // Copyright 2008 __MyCompanyName__. All rights reserved. // #import "SKDatabase.h" @implementation SKDatabase @synthesize delegate; @synthesize dbh; @synthesize dynamic; // Two ways to init: one if you're just SELECTing from a database, one if you're UPDATing // and or INSERTing - (id)initWithFile:(NSString *)dbFile { if (self = [super init]) { NSString *paths = [[NSBundle mainBundle] resourcePath]; NSString *path = [paths stringByAppendingPathComponent:dbFile]; int result = sqlite3_open([path UTF8String], &dbh); NSAssert1(SQLITE_OK == result, NSLocalizedStringFromTable(@"Unable to open the sqlite database (%@).", @"Database", @""), [NSString stringWithUTF8String:sqlite3_errmsg(dbh)]); self.dynamic = NO; } return self; } - (id)initWithDynamicFile:(NSString *)dbFile { if (self = [super init]) { NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docDir = [docPaths objectAtIndex:0]; NSString *docPath = [docDir stringByAppendingPathComponent:dbFile]; NSFileManager *fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:docPath]) { NSString *origPaths = [[NSBundle mainBundle] resourcePath]; NSString *origPath = [origPaths stringByAppendingPathComponent:dbFile]; NSError *error; int success = [fileManager copyItemAtPath:origPath toPath:docPath error:&error]; NSAssert1(success,[NSString stringWithString:@"Failed to copy database into dynamic location"],error); } int result = sqlite3_open([docPath UTF8String], &dbh); NSAssert1(SQLITE_OK == result, NSLocalizedStringFromTable(@"Unable to open the sqlite database (%@).", @"Database", @""), [NSString stringWithUTF8String:sqlite3_errmsg(dbh)]); self.dynamic = YES; } return self; } // Users should never need to call prepare - (sqlite3_stmt *)prepare:(NSString *)sql { const char *utfsql = [sql UTF8String]; sqlite3_stmt *statement; if (sqlite3_prepare([self dbh],utfsql,-1,&statement,NULL) == SQLITE_OK) { return statement; } else { return 0; } } // Three ways to lookup results: for a variable number of responses, for a full row // of responses, or for a singular bit of data - (NSArray *)lookupAllForSQL:(NSString *)sql { sqlite3_stmt *statement; id result; NSMutableArray *thisArray = [NSMutableArray arrayWithCapacity:4]; if (statement = [self prepare:sql]) { while (sqlite3_step(statement) == SQLITE_ROW) { NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4]; for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) { if (sqlite3_column_decltype(statement,i) != NULL && strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0) { result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)]; } else if (sqlite3_column_type(statement, i) == SQLITE_TEXT) { result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)]; } else if (sqlite3_column_type(statement,i) == SQLITE_INTEGER) { result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)]; } else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT) { result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)]; } else { result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)]; } if (result) { [thisDict setObject:result forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]]; } } [thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]]; [thisArray retain]; } } sqlite3_finalize(statement); return thisArray; } - (NSDictionary *)lookupRowForSQL:(NSString *)sql { sqlite3_stmt *statement; id result; NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4]; if (statement = [self prepare:sql]) { if (sqlite3_step(statement) == SQLITE_ROW) { for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) { if (strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0) { result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)]; } else if (sqlite3_column_type(statement, i) == SQLITE_TEXT) { result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)]; } else if (sqlite3_column_type(statement,i) == SQLITE_INTEGER) { result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)]; } else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT) { result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)]; } else { result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)]; } if (result) { [thisDict setObject:result forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]]; } } } } sqlite3_finalize(statement); return thisDict; } - (id)lookupColForSQL:(NSString *)sql { sqlite3_stmt *statement; id result; if (statement = [self prepare:sql]) { if (sqlite3_step(statement) == SQLITE_ROW) { if (strcasecmp(sqlite3_column_decltype(statement,0),"Boolean") == 0) { result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,0)]; } else if (sqlite3_column_type(statement, 0) == SQLITE_TEXT) { result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)]; } else if (sqlite3_column_type(statement,0) == SQLITE_INTEGER) { result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,0)]; } else if (sqlite3_column_type(statement,0) == SQLITE_FLOAT) { result = [NSNumber numberWithDouble:(double)sqlite3_column_double(statement,0)]; } else { result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)]; } } } sqlite3_finalize(statement); return result; } // Simple use of COUNTS, MAX, etc. - (int)lookupCountWhere:(NSString *)where forTable:(NSString *)table { int tableCount = 0; NSString *sql = [NSString stringWithFormat:@"SELECT COUNT(*) FROM %@ WHERE %@", table,where]; sqlite3_stmt *statement; if (statement = [self prepare:sql]) { if (sqlite3_step(statement) == SQLITE_ROW) { tableCount = sqlite3_column_int(statement,0); } } sqlite3_finalize(statement); return tableCount; } - (int)lookupMax:(NSString *)key Where:(NSString *)where forTable:(NSString *)table { int tableMax = 0; NSString *sql = [NSString stringWithFormat:@"SELECT MAX(%@) FROM %@ WHERE %@", key,table,where]; sqlite3_stmt *statement; if (statement = [self prepare:sql]) { if (sqlite3_step(statement) == SQLITE_ROW) { tableMax = sqlite3_column_int(statement,0); } } sqlite3_finalize(statement); return tableMax; } - (int)lookupSum:(NSString *)key Where:(NSString *)where forTable:(NSString *)table { int tableSum = 0; NSString *sql = [NSString stringWithFormat:@"SELECT SUM(%@) FROM %@ WHERE %@", key,table,where]; sqlite3_stmt *statement; if (statement = [self prepare:sql]) { if (sqlite3_step(statement) == SQLITE_ROW) { tableSum = sqlite3_column_int(statement,0); } } sqlite3_finalize(statement); return tableSum; } // INSERTing and UPDATing - (void)insertArray:(NSArray *)dbData forTable:(NSString *)table { // NSMutableString *sql = [NSMutableString stringWithCapacity:16]; // [sql appendFormat:@"INSERT INTO %@ (",table]; // // // for (int i = 0 ; i < [dbData count] ; i++) { // NSLog(@"%@",[[dbData objectAtIndex:i] objectForKey:@"mid"]); // [sql appendFormat:@"%@",[[dbData objectAtIndex:i] objectForKey:@"key"]]; // if (i + 1 < [dbData count]) { // [sql appendFormat:@", "]; // } // } // [sql appendFormat:@") VALUES("]; // for (int i = 0 ; i < [dbData count] ; i++) { // if ([[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]) { // [sql appendFormat:@"%@",[[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]]; // } else { // [sql appendFormat:@"'%@'",[[dbData objectAtIndex:i] objectForKey:@"value"]]; // } // if (i + 1 < [dbData count]) { // [sql appendFormat:@", "]; // } // } // [sql appendFormat:@")"]; // [self runDynamicSQL:sql forTable:table]; for(int i=0;i<[dbData count];i++) { NSDictionary *dict=[dbData objectAtIndex:i]; NSMutableString *sql = [NSMutableString stringWithCapacity:16]; [sql appendFormat:@"INSERT INTO %@ (",table]; NSArray *dataKeys = [dict allKeys]; for (int i = 0 ; i < [dataKeys count] ; i++) { [sql appendFormat:@"%@",[dataKeys objectAtIndex:i]]; if (i + 1 < [dataKeys count]) { [sql appendFormat:@", "]; } } [sql appendFormat:@") VALUES("]; for (int i = 0 ; i < [dataKeys count] ; i++) { if ([[dict objectForKey:[dataKeys objectAtIndex:i]] intValue]) { [sql appendFormat:@"%@",[dict objectForKey:[dataKeys objectAtIndex:i]]]; } else { [sql appendFormat:@"'%@'",[dict objectForKey:[dataKeys objectAtIndex:i]]]; } if (i + 1 < [dict count]) { [sql appendFormat:@", "]; } } [sql appendFormat:@")"]; [self runDynamicSQL:sql forTable:table]; } } - (void)insertDictionary:(NSDictionary *)dbData forTable:(NSString *)table { NSMutableString *sql = [NSMutableString stringWithCapacity:16]; [sql appendFormat:@"INSERT INTO %@ (",table]; NSArray *dataKeys = [dbData allKeys]; for (int i = 0 ; i < [dataKeys count] ; i++) { [sql appendFormat:@"%@",[dataKeys objectAtIndex:i]]; if (i + 1 < [dbData count]) { [sql appendFormat:@", "]; } } [sql appendFormat:@") VALUES("]; for (int i = 0 ; i < [dataKeys count] ; i++) { //if ([[dbData objectForKey:[dataKeys objectAtIndex:i]] intValue]) { // [sql appendFormat:@"%@",[dbData objectForKey:[dataKeys objectAtIndex:i]]]; // } else { [sql appendFormat:@"'%@'",[dbData objectForKey:[dataKeys objectAtIndex:i]]]; //} if (i + 1 < [dbData count]) { [sql appendFormat:@", "]; } } [sql appendFormat:@")"]; [self runDynamicSQL:sql forTable:table]; } - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table { [self updateArray:dbData forTable:table where:NULL]; } - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table where:(NSString *)where { NSMutableString *sql = [NSMutableString stringWithCapacity:16]; [sql appendFormat:@"UPDATE %@ SET ",table]; for (int i = 0 ; i < [dbData count] ; i++) { if ([[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]) { [sql appendFormat:@"%@=%@", [[dbData objectAtIndex:i] objectForKey:@"key"], [[dbData objectAtIndex:i] objectForKey:@"value"]]; } else { [sql appendFormat:@"%@='%@'", [[dbData objectAtIndex:i] objectForKey:@"key"], [[dbData objectAtIndex:i] objectForKey:@"value"]]; } if (i + 1 < [dbData count]) { [sql appendFormat:@", "]; } } if (where != NULL) { [sql appendFormat:@" WHERE %@",where]; } else { [sql appendFormat:@" WHERE 1",where]; } [self runDynamicSQL:sql forTable:table]; } - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table { [self updateDictionary:dbData forTable:table where:NULL]; } - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table where:(NSString *)where { NSMutableString *sql = [NSMutableString stringWithCapacity:16]; [sql appendFormat:@"UPDATE %@ SET ",table]; NSArray *dataKeys = [dbData allKeys]; for (int i = 0 ; i < [dataKeys count] ; i++) { if ([[dbData objectForKey:[dataKeys objectAtIndex:i]] intValue]) { [sql appendFormat:@"%@=%@", [dataKeys objectAtIndex:i], [dbData objectForKey:[dataKeys objectAtIndex:i]]]; } else { [sql appendFormat:@"%@='%@'", [dataKeys objectAtIndex:i], [dbData objectForKey:[dataKeys objectAtIndex:i]]]; } if (i + 1 < [dbData count]) { [sql appendFormat:@", "]; } } if (where != NULL) { [sql appendFormat:@" WHERE %@",where]; } [self runDynamicSQL:sql forTable:table]; } - (void)updateSQL:(NSString *)sql forTable:(NSString *)table { [self runDynamicSQL:sql forTable:table]; } - (void)deleteWhere:(NSString *)where forTable:(NSString *)table { NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE %@", table,where]; [self runDynamicSQL:sql forTable:table]; } // INSERT/UPDATE/DELETE Subroutines - (BOOL)runDynamicSQL:(NSString *)sql forTable:(NSString *)table { int result; //NSAssert1(self.dynamic == 1,[NSString stringWithString:@"Tried to use a dynamic function on a static database"],NULL); sqlite3_stmt *statement; if (statement = [self prepare:sql]) { result = sqlite3_step(statement); } sqlite3_finalize(statement); if (result) { if (self.delegate != NULL && [self.delegate respondsToSelector:@selector(databaseTableWasUpdated:)]) { [delegate databaseTableWasUpdated:table]; } return YES; } else { return NO; } } // requirements for closing things down - (void)dealloc { [self close]; [delegate release]; [super dealloc]; } - (void)close { if (dbh) { sqlite3_close(dbh); } } @end 
 // Create Database file - (void)createEditableCopyOfDatabaseIfNeeded { // First, test for existence. BOOL success; NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSLog(@"%@",documentsDirectory); NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"TestDB.sqlite"]; success = [fileManager fileExistsAtPath:writableDBPath]; if (success) return; // The writable database does not exist, so copy the default to the appropriate location. NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"TestDB.sqlite"]; success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; if (!success) { NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); } }