是否可以使用自我更新的iPhone应用程序?

我相信答案是否定的,但我不确定。

我有一个数据库驱动的应用程序,实际上是产品目录。我希望数据库在用户iPhone上,以便目录快速使用。但是,数据库中的内容会定期更改。

我可以创建一个推送通知,以告诉用户准备好数据库更新,但是如果应用程序自行更新会更好。

有帮助吗?

解决方案

正如Fluchtpunkt回答的那样,iOS应用程序可以下载新数据,它无法下载新代码。许多iOS应用程序,例如众多Twitter客户端,主要下载和显示数据。

应用程序会遇到麻烦的地方是,如果其界面不清楚该应用程序正在下载数据。如果不知道,应用程序不应用尽iPhone的数据计划。让用户知道的范围从明确通知(包括取消下载的选项)到使应用程序的概念全部有关下载数据(例如Twitter客户端)。

如果应用程序与服务器共享任何信息,则还必须通知用户。该应用程序可能希望发送此类数据以选择性下载特定的数据。例如,该应用程序可以使用位置信息来定制数据库,仅下载设备恰好的区域中可用的项目。如果数据是特定于帐户的,则登录过程可能足够通知。

其他提示

只要您不需要更改App-Bundle内部的任何内容,这就是可能的。只需将您的内容保存到文档目录。

当然,您可以更新自己的数据库。

不可能在iPhone上加载可执行文件,尽管值得注意的是您可以动态加载资源捆绑。如果您使用IB来创建视图,则可以创建一个全新的视图,将其放在云上并从应用程序加载。唯一的警告是您只能更新设计,但不能扩展功能。

要动态加载XIB,请使用 initWithNibName 方法,

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle

并通过动态加载的捆绑包。

在Mac上,可以包含包含可执行代码的捆绑包,这些代码可以动态加载,但不能在iPhone上加载。有一个名称的PLIST配置 NSPrincipalClass 对于Mac,但不幸的是还没有用于iPhone。

您可以通过推送通知来完成此操作,除了您可以设置计时器,每个指定时间都会下载新数据,但问题是该应用程序必须始终打开。在iOS 4中,有本地通知,可以将Notificationn发送给用户当应用关闭时

我的应用程序使用SQLITE数据库并对其进行更新。每次启动(或从悬挂模式醒来)它连接到我的Web服务器并检查新数据库。要验证数据库,它首先仅下载包含在线数据库的MD5总和的文件,并在手机上计算数据库的MD5总和。只有汇率不同,新数据库才会下载。这具有很好的副作用,可以使流量保持较低。

计算的示例代码MD5和:

#define CHUNK_SIZE 16384
#import <CommonCrypto/CommonDigest.h>

+ (NSString *)md5SumForFileAtPath:(NSString *)path {
    NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];

    CC_MD5_CTX md5;
    CC_MD5_Init(&md5);

    BOOL done = NO;
    while(!done)
    {
        NSData* fileData = [handle readDataOfLength:CHUNK_SIZE];
        CC_MD5_Update(&md5, [fileData bytes], [fileData length]);
        if ([fileData length] == 0) done = YES;
    }
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5_Final(result, &md5);

    NSString *digest = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                    result[0], result[1], result[2], result[3],result[4], 
                    result[5], result[6], result[7], result[8], result[9], 
                    result[10], result[11], result[12], result[13],
                    result[14], result[15]
                    ];
    XLog("Checksum for file %@: %@", path, digest);
    return digest;  
}

但是,如果数据库不大,下载整个数据库只是一个好的解决方案。此外,我对数据库进行了处理,并在下载后提取它。

#import <zlib.h>
+ (void)gunzipFileAtPath:(NSString *)zippedPath toPath:(NSString *)unzippedPath {
    gzFile file = gzopen([zippedPath UTF8String], "rb");
    FILE *dest = fopen([unzippedPath UTF8String], "w");
    unsigned char buffer[CHUNK_SIZE];
    int uncompressedLength;
    while (uncompressedLength = gzread(file, buffer, CHUNK_SIZE) ) {
        if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
            NSLog(@"error writing data");
        }
    }
    fclose(dest);
    gzclose(file);
}

仅在状态栏中显示网络活动指示器而不使用进度栏或其他指标是完全可以的。如果手机的数据库是最新的,我什至没有通知用户,因为这是不必要的信息,只会分散他的注意力。但是,如果有更新,我会淡入状态栏的覆盖层,并显示信息几秒钟。从我的用户的反馈来看,我可以看出他们非常感谢这种解决方案。

不要忘记,通过计算MD5总和来添加密码学。上传下一个更新时,您必须向Apple指示这一点。我只需要再回答一个问题,然后说我只使用加密进行身份验证。该应用程序获得了批准,没有任何问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top