是否可以有一个自动更新的 iPhone 应用程序?

发布于 2024-09-28 21:07:57 字数 192 浏览 6 评论 0原文

是否可以有一个自动更新的 iPhone 应用程序?

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

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

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

Is it possible to have a self-updating iPhone application?

I believe the answer is no, but I am not sure.

I have a database driven app that is in effect a catalogue of products. I want the database to be on the users iPhone so the catalog is fast to use. However, periodically the content in the database changes.

I could create a push notification to tell the user that there is a database update ready, but it would be better if the app updates itself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦屿孤独相伴 2024-10-05 21:07:57

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

如果应用程序的界面没有明确表明应用程序正在下载数据,那么应用程序就会遇到麻烦。应用程序不应在用户不知情的情况下用完 iPhone 的数据计划配额。让用户知道的范围包括从明确的通知(包括取消下载的选项)到使应用程序的概念全部与下载数据有关(例如 Twitter 客户端)。

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

As fluchtpunkt answered, an iOS app can download new data, it just can't download new code. Many iOS apps, such as the multitude of Twitter clients, primarily download and display data.

Where an app will get into trouble is if its interface doesn't make clear the app is downloading data. An app shouldn't use up an iPhone's data plan allotment without the user knowing. Letting the user know can range from explicit notifications including the option to cancel the download to making the concept of the app all about downloading data (e.g. Twitter clients).

The user must also be notified if the app is sharing any information with the server. The app may want to send such data to selectively download specific data. For example the app could use location information to tailor the database, downloading only items available in the region the device happens to be. A login process may be sufficient notification, if the data is account specific.

橙味迷妹 2024-10-05 21:07:57

只要您不需要更改应用程序包内的任何内容,这是可能的。只需将您的内容保存到文档目录即可。

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

as long as you don't need to change anything inside the app-bundle this is possible. Just save your content to the Documents Directory.

And of course you are allowed to update your own database.

初见终念 2024-10-05 21:07:57

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

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

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

并传入动态加载的包。

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

It's not possible to load an executable on the iPhone, although it's worth noting that you can load resource bundles dynamically. If you use IB for creating your views, then you can create an entirely new view, put it up on the cloud and load it from the app. The only caveat is that you can only update the design, but not extend functionality.

To load a XIB dynamically, use the initWithNibName method,

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

and pass in the dynamically loaded bundle.

On the Mac, it is possible to have bundles that contain executable code which can be dynamically loaded, but not on the iPhone. There is a Plist configuration named NSPrincipalClass for the Mac, but unfortunately not for the iPhone yet.

陌上青苔 2024-10-05 21:07:57

你可以通过推送通知来做到这一点,除了你可以设置计时器,它将在每个指定的时间下载新数据,但问题是应用程序必须一直打开。在ios 4中,有本地通知,甚至可以向用户发送通知当应用程序关闭时

u can do it with push notification apart from that u can set timer which will download new data every specified time but the problem is the app has to be open all the time.in ios 4 there is local notification which can send notificationn to user even when app is closed

凉城 2024-10-05 21:07:57

我的应用程序使用 SQLite 数据库并更新它。每次启动(或从挂起模式唤醒)时,它都会连接到我的网络服务器并检查新数据库。为了验证数据库,它首先只下载包含在线数据库的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;  
}

但是,如果数据库不大,下载整个数据库只是一个好的解决方案。此外,我对数据库进行了 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 表明这一点。我只需再回答一个问题并说我仅使用加密进行身份验证。该应用程序已获得批准,没有任何问题。

My app uses an SQLite database and updates it. With every start (or waking up from suspended mode) it connects to my web server and checks for a new database. To authenticate the database, it first only downloads a file containing the MD5 sum of the online database and calculates the MD5 sum of the database on the phone. Only if the sums differ, the new database will be downloaded. This has the nice side effect that it keeps the traffic low.

Sample code for calculatimg the MD5 sum:

#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;  
}

However, downloading the entire database is only a good solution if the database is not to large. Additionally, I gzipped the database and extract it after the download.

#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);
}

It is perfectly fine to only show the network activity indicator in the status bar and not use a progress bar or other indicator. If the phone's database is up to date, I do not even notify the user, as it is unnecessary information and will only distract him. However, if there is an update, I fade in an overlay of the status bar and display the information for a few seconds. From the feedback of my users, I can tell that they pretty much appreciate this solution.

Do not forget that you add cryptography by calculating the MD5 sum. You have to indicate this to Apple when uploading your next Update. I only had to answer one more question and say that I use encryption only for authentication. The app was approved without any problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文