Подтвердить что ты не робот

Хранение данных локально на iphone

Я создаю приложение, где я бы хотел локально хранить информацию о пользователе на устройстве, без использования какой-либо серверной базы данных, но все на стороне устройства. Я ищу, чтобы хранить конкретные местоположения пользователей и показывать их в виде таблицы, и поэтому даже когда пользователь запускает приложение позже - я могу вытащить историю и прокормить таблицу истории с прошлыми местоположениями. В основном возможность чтения/записи из локальной базы данных.

Теперь я знаю, что раньше было много вопросов, но я не мог найти тот, который позволяет экономить данные локально без внешней базы данных. Я не уверен, например, что использование Core Data - это правильная и простая вещь.

Понадобился бы любой совет по этому поводу.

4b9b3361

Ответ 1

Для простых данных вы должны использовать 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"

Ответ 2

У вас есть в основном два варианта хранения данных:

  • CoreData (если вы планируете использовать более новые версии iOS)
  • SQLite (поддерживает любую версию SDK)

CoreData использует SQLite, его API немного проще в использовании (вам не нужно знать SQL или писать много функций для чтения и записи ваших данных).

SQLite API по-прежнему остается отличным выбором, поскольку он использует C API для SQLite, который очень хорошо документирован и прост в использовании. Это имеет то преимущество, что вы можете ориентироваться на более старые платформы iOS с этим.

В обоих вариантах данные будут храниться на стороне клиента и будут поддерживаться каждый раз, когда пользователь синхронизирует свой телефон с iTunes.

Ответ 3

если вы просто сохраняете несколько значений и не нуждаетесь в какой-либо логике поиска, вы можете заглянуть в NSUserDefaults

[NSUserDefaults standardUserDefaults] 

его просто словарь, в котором вы можете хранить массивы, строки, int, объекты и доступ с помощью ключа NSString

внутренне это просто plist, поэтому вы можете открыть его с помощью xcode, чтобы быстро увидеть текущее состояние

Ответ 4

Я рекомендую использовать Realm для более обобщенных решений.

Ответ 5

У вас есть несколько способов хранения данных приложения на вашем iPhone.

  • Файлы plist
  • NSUserDefaults
  • UserDefault
  • Файловая система
  • CoreData​​li >
  • SQLite DB

Ответ 6

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];
            [email protected]"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

Ответ 7

// 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]);
    }
}