是否有可能拥有自我更新的iPhone应用程序?是否有可能拥有自我更新的iPhone应用程序?
我相信答案是否定的,但我不确定。
我有一个数据库驱动的应用程序,实际上是一个产品目录。我希望数据库位于用户iPhone上,因此目录可以快速使用。但是,数据库中的内容会定期更改。
我可以创建一个推送通知来告诉用户有一个数据库更新就绪,但如果应用程序自我更新会更好。
是否有可能拥有自我更新的iPhone应用程序?是否有可能拥有自我更新的iPhone应用程序?
我相信答案是否定的,但我不确定。
我有一个数据库驱动的应用程序,实际上是一个产品目录。我希望数据库位于用户iPhone上,因此目录可以快速使用。但是,数据库中的内容会定期更改。
我可以创建一个推送通知来告诉用户有一个数据库更新就绪,但如果应用程序自我更新会更好。
正如fluchtpunkt回答,iOS应用程序可以下载新的数据,它只是不能下载新的代码。许多iOS应用程序(例如众多的Twitter客户端)主要下载并显示数据。
应用程序会遇到麻烦的地方在于它的界面没有说明应用程序正在下载数据。如果用户不知道,应用程序不应使用iPhone的数据计划分配。让用户知道的范围可以从显式通知(包括取消下载的选项)到使应用程序的概念全部关于下载数据(例如Twitter客户端)。
如果应用程序与服务器共享任何信息,还必须通知用户。该应用可能希望发送这样的数据以选择性地下载特定数据。例如,应用程序可以使用位置信息来定制数据库,只下载该设备恰好在该区域中可用的项目。如果数据是账户特定的,则登录过程可能是充分的通知。
只要你不需要改变应用程序包内的任何东西,这是可能的。只需将您的内容保存到文档目录。
当然,您可以更新自己的数据库。
你可以通过推送通知来做到这一点除了你可以设置定时器,它会在每个指定的时间下载新的数据,但问题是应用程序必须一直打开。在ios 4中有本地通知可以发送即使应用程序关闭,也会通知用户
我的应用程序使用SQLite数据库并进行更新。随着每次开始(或从暂停模式唤醒),它会连接到我的Web服务器并检查新的数据库。为了验证数据库,它首先下载一个包含在线数据库MD5总和的文件,并计算手机上数据库的MD5总和。只有和数不同时,新的数据库才会被下载。这具有很好的副作用,它可以保持低流量。
为calculatimg 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;
}
然而,在下载整个数据库仅仅是一个很好的解决方案,如果数据库不是很大。另外,我在下载后将gzip数据库提取出来。
#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表明这一点。我只需要回答一个问题,并说我只使用加密进行身份验证。该应用程序被批准没有任何问题。
不可能在iPhone上加载可执行文件,但值得注意的是可以动态加载资源包。如果您使用IB来创建视图,那么您可以创建一个全新的视图,将其放置在云上并从应用中加载它。唯一需要注意的是,你只能更新设计,而不能扩展功能。
动态地加载一个XIB,使用initWithNibName
方法,
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
,并通过在动态加载的束。
在Mac上,可能有捆绑包包含可动态加载的可执行代码,但不能在iPhone上运行。 Mac上有一个名为NSPrincipalClass
的Plist配置,但不幸的是,它并不适用于iPhone。