升级数据库时,为什么我的iPhone App应用程序更新失败?

时间:2009-05-23 14:05:32

标签: iphone sqlite

我发布了一个应用程序更新,它可以升级数据库,即。在捆绑包中执行一个脚本文件,将列添加到现有表等。我已经通过在xcode上部署我的设备上的先前版本构建然后部署最新版本来测试了这一点。升级工作正常。

昨天我的发布版本被app Store接受了。当我启动它时,我的梦魇场景成为现实,它在数据库升级期间失败了!我已经检查了分发版本,并且升级版本文件就在那里,所以它似乎并不是一个缺少的资源文件,尽管我不确定。我不知道应该怎么调试这个。除了代码签名之外,从app store发布的分发版本和从xcode部署的发布/调试版本有什么区别?对我没有意义。

这是我的崩溃日志和失败的代码:

0   libSystem.B.dylib               0x3141d414 pread + 20
1   libsqlite3.0.dylib              0x303a2154 unixRead + 40
2   libsqlite3.0.dylib              0x303bd7c4 sqlite3PagerAcquire + 3748
3   libsqlite3.0.dylib              0x303c7718 sqlite3BtreeNext + 260
4   libsqlite3.0.dylib              0x303c7b84 sqlite3BtreeNext + 1392
5   libsqlite3.0.dylib              0x304272b8 sqlite3VdbeExec + 38668
6   libsqlite3.0.dylib              0x30428944 sqlite3Step + 504
7   libsqlite3.0.dylib              0x303ecbc4 sqlite3_exec + 600
8   MyApp                       0x00046ae4 +[DBUpgradeService executeUpgradeScript:] (DBUpgradeService.m:94)
9   MyApp                       0x000469aa +[DBUpgradeService upgradeV1_0ToV1_1] (DBUpgradeService.m:67)
10  MyApp                       0x0004687a +[DBUpgradeService upgradeDBIfNecessary] (DBUpgradeService.m:27)
11  MyApp                       0x000021ec -[MyAppAppDelegate applicationDidFinishLaunching:] (MyAppAppDelegate.m:49)
12  UIKit                           0x30a4ef24 -[UIApplication performInitializationWithURL:asPanel:] + 160
13  UIKit                           0x30a57dec -[UIApplication _runWithURL:] + 644
14  Foundation                      0x306945a2 __NSFireDelayedPerform + 326
15  CoreFoundation                  0x30269d88 CFRunLoopRunSpecific + 2642
16  CoreFoundation                  0x30269320 CFRunLoopRunInMode + 44
17  GraphicsServices                0x31567e58 GSEventRunModal + 268
18  UIKit                           0x30a4fa6c -[UIApplication _run] + 520
19  UIKit                           0x30a591d0 UIApplicationMain + 1132
20  MyApp                       0x00002090 main (main.m:20)
21  MyApp                       0x0000202c start + 44



+ (BOOL) executeUpgradeScript:(NSString*) scriptName{
    NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
    NSString *scriptPath = [resourcePath stringByAppendingPathComponent:scriptName];

    NSString* upgradeScript = [NSString stringWithContentsOfFile:scriptPath];
    NSArray* lines = [upgradeScript componentsSeparatedByString:@"\n"];
    //begin transaction
    NSString* begin = [NSString stringWithString:@"BEGIN TRANSACTION"];

    sqlite3_exec([DatabaseManager getDatabase], begin.UTF8String , nil , nil , nil);
    BOOL failed = NO;
    for( NSString* line in lines) {
        const char *sql = line.UTF8String;
        char* error = nil;
        sqlite3_exec([DatabaseManager getDatabase], sql , nil , nil , &error); //THIS LINE FAILS
        if(error != nil) {
            NSLog([NSString stringWithCString:error]);
            failed = YES;
            break;
        }
    }

    if(failed){
        return NO;
    }
    else{
        NSString* commit = [NSString stringWithString:@"COMMIT"];
        sqlite3_exec([DatabaseManager getDatabase], commit.UTF8String , nil , nil , nil);
        return YES;

    }
}

2 个答案:

答案 0 :(得分:1)

您不能修改应用程序包中的文件(请参阅epatel的link)。作为构建过程的一部分,应用程序将被签名,修改捆绑包中的文件将破坏签名。

您应该使用应用程序的文档目录。您应该使用以下命令替换resourcePath分配:

NSString *resourcePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

答案 1 :(得分:1)

如果数据库的升级在启动阶段需要很长时间,则可以启动应用程序。

解决此类问题的一种方法是将升级置于NSThread

- (void)upgradeSomething:(id)sender
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

  // Do something here that takes time

  // and maybe signal when done with some flag or thing...

  [pool release];
}

- (void)awakeFromNib
{
    // The usual stuff

    // and detach a NSThread for upgrade 

    [NSThread detachNewThreadSelector:@selector(upgradeSomething:) 
                             toTarget:self 
                           withObject:nil]
}

阅读here以了解保持事件循环活动的原因。