Копирование данных в папку «Данные приложения» на iPhone - PullRequest
5 голосов
/ 31 января 2010

Я (наконец) загружаю свое приложение на устройство iPhone для тестирования. Пока что я тестировал приложение только в симуляторе. Приложение ориентировано на данные и использует базу данных SQLite. Я создал соответствующую базу данных SQLite с примерами данных, которые я использовал в симуляторе. Как я могу скопировать этот файл .sqlite3 на фактический iPhone?

Это было легко с симулятором, так как я мог просто скопировать файл .sqlite3 в папку ~ / Библиотека / Поддержка приложений / Симулятор iPhone / Пользователь / Приложения / {UUID} / Documents , но я не могу выяснить, как получить это в том же месте на фактическом устройстве iPhone. Воссоздание базы данных с нуля на телефоне на самом деле не вариант, так как я уже выполнил все трудные задачи по созданию базы данных на Mac.

Ответы [ 3 ]

11 голосов
/ 31 января 2010

Как сказал Алекс, вы должны добавить файл базы данных в качестве ресурса в ваш проект. Это даст Xcode команду связать файл базы данных в вашем .app. Этот файл, однако, предназначен только для чтения, вы можете скопировать его в папку документов вашего приложения (на устройстве или в симуляторе, то же самое), где он становится доступным для записи.

Вот код, который я использую для такого рода вещей ниже. Приятная вещь в этом коде заключается в том, что он автоматически обновляет доступную для записи копию в папке с документами вашего приложения всякий раз, когда вы изменяете «основную» копию, входящую в комплект .app. Используйте pathLocal, чтобы открыть свою (доступную для записи) базу данных ...

Приведенная ниже функция возвращает YES, если операция прошла успешно (была необходима копия или нет). Вы можете изменить это на то, что вам подходит:)

NSString *pathLocal, *pathBundle;

// Automatically copy DB from .app bundle to device document folder if needed
- (BOOL)automaticallyCopyDatabase {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];
    pathLocal = [documentsDir stringByAppendingPathComponent:@"mydb.sqlite"];
    pathBundle = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"mydb.sqlite"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDictionary *localAttr = [fileManager fileAttributesAtPath:pathLocal traverseLink:YES];
    BOOL needsCopy = NO;
    if (localAttr == nil) {
        needsCopy = YES;
    } else {
        NSDate *localDate;
        NSDate *appDBDate;
        if (localDate = [localAttr objectForKey:NSFileModificationDate]) {
            NSDictionary *appDBAttr = [fileManager fileAttributesAtPath:pathBundle traverseLink:YES];
            appDBDate = [appDBAttr objectForKey:NSFileModificationDate];
            needsCopy = [appDBDate compare:localDate] == NSOrderedDescending;
        } else {
            needsCopy = YES;
        }
    }
    if (needsCopy) {
        NSError *error;
        BOOL success;
        if (localAttr != nil) {
            success = [fileManager removeItemAtPath:pathLocal error:&error];
        }
        success = [fileManager copyItemAtPath:pathBundle toPath:pathLocal error:&error];
        return success;
    }
    return YES;
}
6 голосов
/ 31 января 2010

Почему бы не добавить его в комплект приложений? Щелкните правой кнопкой мыши папку Resources в окне вашего проекта в XCode, затем выберите Add> Existing Files..., чтобы добавить базу данных sqlite.

Затем вы должны загрузить файл из пакета приложения:

NSString *databasePath = [[NSBundle mainBundle] pathForResource:@"mySQLiteDatabaseFile" ofType:@"sqlite3"];
NSData *databaseData = [NSData dataWithContentsOfFile:databasePath];
// ...
0 голосов
/ 31 января 2010

вот как я это сделал, создав класс под названием DBManagement и в файле m реализуйте эти методы. Также поместите эту строку в файл реализации над строкой @implementation

статический sqlite3 * CHManagement = nil;

-(NSString *) getDBPath
{
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
 NSString *documentsDirectory = [paths objectAtIndex:0];
 NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/CHManagement.sqlite"];
  return MyDatabasePath;

 }

-(void) checkDataBase
{
NSLog(@"CheckDatabase Called");
NSFileManager *fileManager=[NSFileManager defaultManager];
NSError *error=[[[NSError alloc]init] autorelease]; 
NSString *dbPath = [self getDBPath];
BOOL success=[fileManager fileExistsAtPath:dbPath];
if(!success)
{
 NSString *defaultDBPath=nil;
 defaultDBPath=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:@"CHManagement.sqlite"];
 success=[fileManager copyItemAtPath:defaultDBPath  toPath:dbPath error:&error];
 if(!success)
 {
   NSAssert1(0,@"failed to create database with message '%@'.",[error localizedDescription]); 
  }
 }
 else
 {
 sqlite3 *MyDatabase;
 NSInteger VersionNumber=0;
 sqlite3_stmt *CompiledStatement=nil;
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
 NSString *documentsDirectory = [paths objectAtIndex:0];
 NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/CHManagement.sqlite"];
 if(sqlite3_open([MyDatabasePath UTF8String],&MyDatabase) == SQLITE_OK)
 {
  sqlite3_prepare_v2(MyDatabase, "select appVersionNo from VersionInfo", -1, &CompiledStatement, NULL);
  while(sqlite3_step(CompiledStatement) == SQLITE_ROW)
  {
   VersionNumber=sqlite3_column_int(CompiledStatement,0);
  }
  sqlite3_reset(CompiledStatement);
  sqlite3_finalize(CompiledStatement);
  sqlite3_close(MyDatabase);
 }
 if (VersionNumber!=1)
 {
  [self deleteDatabase];
  NSString *defaultDBPath=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:@"CHManagement.sqlite"];
  success=[fileManager copyItemAtPath:defaultDBPath  toPath:dbPath error:&error];
  if(!success)
  {
   NSAssert1(0,@"failed to create database with message '%@'.",[error localizedDescription]); 
   }
  }
 }
 }

- (void)deleteDatabase
{
NSLog(@"Delete Database Called");
NSError **error=nil;
NSFileManager *FileManager = [NSFileManager defaultManager];
NSString *databasepath = [self getDBPath];
  BOOL success = [FileManager fileExistsAtPath:databasepath];
if(success) {
[FileManager removeItemAtPath:databasepath error:error];
}
 }

с помощью этих методов вы можете легко загрузить базу данных в папку документов iphone приложения. Извините за форматирование. и appVersionNo - это поле в tableCalled versionInfo, значением по умолчанию является 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...