是否有可能拥有自我更新的iPhone应用程序?

时间:2010-10-20 11:28:45

标签: iphone updates

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

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

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

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

5 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

如果应用程序遇到麻烦,其界面是否显示应用程序正在下载数据。在用户不知情的情况下,应用程序不应使用iPhone的数据计划分配。让用户知道的范围可以从包括取消下载的选项的显式通知到使app的概念全部关于下载数据(例如,Twitter客户端)。

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

答案 2 :(得分:1)

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

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

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

并传入动态加载的包。

在Mac上,可以包含可以动态加载但不能在iPhone上加载的可执行代码的包。 Mac上有一个名为NSPrincipalClass的Plist配置,但遗憾的是还不适用于iPhone。

答案 3 :(得分:0)

你可以用推送通知来做,除了你可以设置定时器,它会在每个指定时间下载新数据,但问题是应用程序必须一直打开。在ios 4有本地通知,可以发送通知即使应用程序关闭也能用户

答案 4 :(得分:0)

我的应用程序使用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表明这一点。我只需回答一个问题并说我只使用加密进行身份验证。该应用程序被批准没有任何问题。